diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/VERSION b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/VERSION deleted file mode 100644 index 9a9f13434c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/VERSION +++ /dev/null @@ -1 +0,0 @@ -15.0.0-rc1 \ No newline at end of file diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit.go deleted file mode 100644 index 1b8f010c2d..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 - -package main - -import ( - "context" - "encoding/gob" - "flag" - - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit" -) - -type commitSubcommand struct{} - -func (commitSubcommand) Flags() *flag.FlagSet { return flag.NewFlagSet("commit", flag.ExitOnError) } - -func (commitSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { - return commit.Run(ctx, decoder, encoder) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper/testhelper.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper/testhelper.go deleted file mode 100644 index 0b3a5e9e57..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper/testhelper.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 - -package testhelper - -import ( - "testing" - "time" - - git "github.com/libgit2/git2go/v33" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" -) - -// DefaultAuthor is the author used by BuildCommit -var DefaultAuthor = git.Signature{ - Name: "Foo", - Email: "foo@example.com", - When: time.Date(2020, 1, 1, 1, 1, 1, 0, time.FixedZone("", 2*60*60)), -} - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func BuildCommit(t testing.TB, repoPath string, parents []*git.Oid, fileContents map[string]string) *git.Oid { - repo, err := git2goutil.OpenRepository(repoPath) - require.NoError(t, err) - defer repo.Free() - - odb, err := repo.Odb() - require.NoError(t, err) - - treeBuilder, err := repo.TreeBuilder() - require.NoError(t, err) - - for file, contents := range fileContents { - oid, err := odb.Write([]byte(contents), git.ObjectBlob) - require.NoError(t, err) - require.NoError(t, treeBuilder.Insert(file, oid, git.FilemodeBlob)) - } - - tree, err := treeBuilder.Write() - require.NoError(t, err) - - var commit *git.Oid - commit, err = repo.CreateCommitFromIds("", &DefaultAuthor, &DefaultAuthor, "Message", tree, parents...) - require.NoError(t, err) - - return commit -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper_test.go deleted file mode 100644 index 826c9250f0..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper_test.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 - -package main - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func buildExecutor(tb testing.TB, cfg config.Cfg) *git2go.Executor { - return git2go.NewExecutor(cfg, gittest.NewCommandFactory(tb, cfg), config.NewLocator(cfg)) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/README.md deleted file mode 100644 index 629cebbd09..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# gitaly-hooks - -`gitaly-hooks` is a binary that is the single point of entry for git hooks through gitaly. - -## How is it invoked? - -`gitaly-hooks` has the following subcommands: - -| subcommand | purpose | arguments | stdin | -|--------------|-------------------------------------------------|--------------------------------------|---------------------------------------------| -| `check` | checks if the hooks can reach the gitlab server | none | none | -| `pre-receive` | used as the git pre-receive hook | none | `` SP `` SP `` LF | -| `update` | used as the git update hook | `` `` `` | none -| `post-receive` | used as the git post-receive hook | none | `` SP `` SP `` LF | -| `git` | used as the git pack-objects hook | `pack-objects` `[--stdout]` `[--shallow-file]` | `` | - -## Where is it invoked from? - -There are three main code paths that call `gitaly-hooks`. - -### git receive-pack (SSH & HTTP) - -We have two RPCs that perform the `git receive-pack` function, [SSHReceivePack](https://gitlab.com/gitlab-org/gitaly/-/blob/master/internal/service/ssh/receive_pack.go) and [PostReceivePack](https://gitlab.com/gitlab-org/gitaly/-/blob/master/internal/service/smarthttp/receive_pack.go). - -Both of these RPCs, when executing `git receive-pack`, set `core.hooksPath` to the path of the `gitaly-hooks` binary. [That happens here in `ReceivePackConfig`](https://gitlab.com/gitlab-org/gitaly/-/blob/master/internal/git/receivepack.go). - -### Operations service RPCs - -In the [operations service](https://gitlab.com/gitlab-org/gitaly/-/tree/master/internal/service/operations) there are RPCs that call out to `gitaly-ruby`, which then do certain operations that execute git hooks. -This is accomplished through the `with_hooks` method [here](https://gitlab.com/gitlab-org/gitaly/-/blob/master/ruby/lib/gitlab/git/operation_service.rb). Eventually the [`hook.rb`](https://gitlab.com/gitlab-org/gitaly/-/blob/master/ruby/lib/gitlab/git/hook.rb) is -called, which then calls the `gitaly-hooks` binary. This method doesn't rely on git to run the hooks. Instead, the arguments and input to the -hooks are built in ruby and then get shelled out to `gitaly-hooks`. - -### git upload-pack (SSH & HTTP) - -Only when the pack-objects cache is enabled in Gitaly's configuration file. - -SSHUploadPack and PostUploadPack, when executing `git upload-pack`, set `uploadpack.packObjectsHook` to the path of the `gitaly-hooks` binary. Afterward, when `git upload-pack` requests packfile data, it calls `gitaly-hooks` binary instead of `git pack-objects`. [That happens here in `WithPackObjectsHookEnv`](https://gitlab.com/gitlab-org/gitaly/-/blob/47164700a1ea086c5e8ca0d02feefe4e68bf4f81/internal/git/hooks_options.go#L54) - -## What does gitaly-hooks do? - -`gitaly-hooks` will take the arguments and make an RPC call to `PreReceiveHook`, `UpdateHook`, `PostReceiveHook`, or `PackObjectsHook` accordingly. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge.go deleted file mode 100644 index 108706104b..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge.go +++ /dev/null @@ -1,141 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net/url" - "path/filepath" - - "github.com/git-lfs/git-lfs/lfs" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/labkit/tracing" -) - -type configProvider interface { - Get(key string) string -} - -func initLogging(p configProvider) (io.Closer, error) { - path := p.Get(gitalylog.GitalyLogDirEnvKey) - if path == "" { - return nil, nil - } - - filepath := filepath.Join(path, "gitaly_lfs_smudge.log") - - return log.Initialize( - log.WithFormatter("json"), - log.WithLogLevel("info"), - log.WithOutputName(filepath), - ) -} - -func smudge(to io.Writer, from io.Reader, cfgProvider configProvider) error { - // Since the environment is sanitized at the moment, we're only - // using this to extract the correlation ID. The finished() call - // to clean up the tracing will be a NOP here. - ctx, finished := tracing.ExtractFromEnv(context.Background()) - defer finished() - - output, err := handleSmudge(ctx, to, from, cfgProvider) - if err != nil { - log.WithError(err).Error(err) - return err - } - defer func() { - if err := output.Close(); err != nil { - log.ContextLogger(ctx).WithError(err).Error("closing LFS object: %w", err) - } - }() - - _, copyErr := io.Copy(to, output) - if copyErr != nil { - log.WithError(err).Error(copyErr) - return copyErr - } - - return nil -} - -func handleSmudge(ctx context.Context, to io.Writer, from io.Reader, config configProvider) (io.ReadCloser, error) { - logger := log.ContextLogger(ctx) - - ptr, contents, err := lfs.DecodeFrom(from) - if err != nil { - // This isn't a valid LFS pointer. Just copy the existing pointer data. - return io.NopCloser(contents), nil - } - - logger.WithField("oid", ptr.Oid).Debug("decoded LFS OID") - - glCfg, tlsCfg, glRepository, err := loadConfig(config) - if err != nil { - return io.NopCloser(contents), err - } - - logger.WithField("gitlab_config", glCfg). - WithField("gitaly_tls_config", tlsCfg). - Debug("loaded GitLab API config") - - client, err := gitlab.NewHTTPClient(logger, glCfg, tlsCfg, prometheus.Config{}) - if err != nil { - return io.NopCloser(contents), err - } - - qs := url.Values{} - qs.Set("oid", ptr.Oid) - qs.Set("gl_repository", glRepository) - u := url.URL{Path: "/lfs", RawQuery: qs.Encode()} - - response, err := client.Get(ctx, u.String()) - if err != nil { - return io.NopCloser(contents), fmt.Errorf("error loading LFS object: %v", err) - } - - if response.StatusCode == 200 { - return response.Body, nil - } - - if err := response.Body.Close(); err != nil { - logger.WithError(err).Error("closing LFS pointer body: %w", err) - } - - return io.NopCloser(contents), nil -} - -func loadConfig(cfgProvider configProvider) (config.Gitlab, config.TLS, string, error) { - var cfg config.Gitlab - var tlsCfg config.TLS - - glRepository := cfgProvider.Get("GL_REPOSITORY") - if glRepository == "" { - return cfg, tlsCfg, "", fmt.Errorf("error loading project: GL_REPOSITORY is not defined") - } - - u := cfgProvider.Get("GL_INTERNAL_CONFIG") - if u == "" { - return cfg, tlsCfg, glRepository, fmt.Errorf("unable to retrieve GL_INTERNAL_CONFIG") - } - - if err := json.Unmarshal([]byte(u), &cfg); err != nil { - return cfg, tlsCfg, glRepository, fmt.Errorf("unable to unmarshal GL_INTERNAL_CONFIG: %v", err) - } - - u = cfgProvider.Get("GITALY_TLS") - if u == "" { - return cfg, tlsCfg, glRepository, errors.New("unable to retrieve GITALY_TLS") - } - - if err := json.Unmarshal([]byte(u), &tlsCfg); err != nil { - return cfg, tlsCfg, glRepository, fmt.Errorf("unable to unmarshal GITALY_TLS: %w", err) - } - - return cfg, tlsCfg, glRepository, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge_test.go deleted file mode 100644 index 88f4c661fe..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/lfs_smudge_test.go +++ /dev/null @@ -1,256 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "net/http" - "path/filepath" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -const ( - lfsOid = "3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa" - lfsPointer = `version https://git-lfs.github.com/spec/v1 -oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa -size 177735 -` - lfsPointerWithCRLF = `version https://git-lfs.github.com/spec/v1 -oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa` + "\r\nsize 177735" - invalidLfsPointer = `version https://git-lfs.github.com/spec/v1 -oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa&gl_repository=project-51 -size 177735 -` - invalidLfsPointerWithNonHex = `version https://git-lfs.github.com/spec/v1 -oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12z- -size 177735` - glRepository = "project-1" - secretToken = "topsecret" - testData = "hello world" - certPath = "../../internal/gitlab/testdata/certs/server.crt" - keyPath = "../../internal/gitlab/testdata/certs/server.key" -) - -var defaultOptions = gitlab.TestServerOptions{ - SecretToken: secretToken, - LfsBody: testData, - LfsOid: lfsOid, - GlRepository: glRepository, - ClientCACertPath: certPath, - ServerCertPath: certPath, - ServerKeyPath: keyPath, -} - -type mapConfig struct { - env map[string]string -} - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func (m *mapConfig) Get(key string) string { - return m.env[key] -} - -func runTestServer(t *testing.T, options gitlab.TestServerOptions) (config.Gitlab, func()) { - tempDir := testhelper.TempDir(t) - - gitlab.WriteShellSecretFile(t, tempDir, secretToken) - secretFilePath := filepath.Join(tempDir, ".gitlab_shell_secret") - - serverURL, serverCleanup := gitlab.NewTestServer(t, options) - - c := config.Gitlab{URL: serverURL, SecretFile: secretFilePath, HTTPSettings: config.HTTPSettings{CAFile: certPath}} - - return c, func() { - serverCleanup() - } -} - -func TestSuccessfulLfsSmudge(t *testing.T) { - testCases := []struct { - desc string - data string - }{ - { - desc: "regular LFS pointer", - data: lfsPointer, - }, - { - desc: "LFS pointer with CRLF", - data: lfsPointerWithCRLF, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - var b bytes.Buffer - reader := strings.NewReader(tc.data) - - c, cleanup := runTestServer(t, defaultOptions) - defer cleanup() - - cfg, err := json.Marshal(c) - require.NoError(t, err) - - tlsCfg, err := json.Marshal(config.TLS{ - CertPath: certPath, - KeyPath: keyPath, - }) - require.NoError(t, err) - - tmpDir := testhelper.TempDir(t) - - env := map[string]string{ - "GL_REPOSITORY": "project-1", - "GL_INTERNAL_CONFIG": string(cfg), - "GITALY_LOG_DIR": tmpDir, - "GITALY_TLS": string(tlsCfg), - } - cfgProvider := &mapConfig{env: env} - _, err = initLogging(cfgProvider) - require.NoError(t, err) - - err = smudge(&b, reader, cfgProvider) - require.NoError(t, err) - require.Equal(t, testData, b.String()) - - logFilename := filepath.Join(tmpDir, "gitaly_lfs_smudge.log") - require.FileExists(t, logFilename) - - data := testhelper.MustReadFile(t, logFilename) - require.NoError(t, err) - d := string(data) - - require.Contains(t, d, `"msg":"Finished HTTP request"`) - require.Contains(t, d, `"status":200`) - require.Contains(t, d, `"content_length_bytes":`) - }) - } -} - -func TestUnsuccessfulLfsSmudge(t *testing.T) { - testCases := []struct { - desc string - data string - missingEnv string - tlsCfg config.TLS - expectedError bool - options gitlab.TestServerOptions - expectedLogMessage string - expectedGitalyTLS string - }{ - { - desc: "bad LFS pointer", - data: "test data", - options: defaultOptions, - expectedError: false, - }, - { - desc: "invalid LFS pointer", - data: invalidLfsPointer, - options: defaultOptions, - expectedError: false, - }, - { - desc: "invalid LFS pointer with non-hex characters", - data: invalidLfsPointerWithNonHex, - options: defaultOptions, - expectedError: false, - }, - { - desc: "missing GL_REPOSITORY", - data: lfsPointer, - missingEnv: "GL_REPOSITORY", - options: defaultOptions, - expectedError: true, - expectedLogMessage: "GL_REPOSITORY is not defined", - }, - { - desc: "missing GL_INTERNAL_CONFIG", - data: lfsPointer, - missingEnv: "GL_INTERNAL_CONFIG", - options: defaultOptions, - expectedError: true, - expectedLogMessage: "unable to retrieve GL_INTERNAL_CONFIG", - }, - { - desc: "failed HTTP response", - data: lfsPointer, - options: gitlab.TestServerOptions{ - SecretToken: secretToken, - LfsBody: testData, - LfsOid: lfsOid, - GlRepository: glRepository, - LfsStatusCode: http.StatusInternalServerError, - }, - expectedError: true, - expectedLogMessage: "error loading LFS object", - }, - { - desc: "invalid TLS paths", - data: lfsPointer, - options: defaultOptions, - tlsCfg: config.TLS{CertPath: "fake-path", KeyPath: "not-real"}, - expectedError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - c, cleanup := runTestServer(t, tc.options) - defer cleanup() - - cfg, err := json.Marshal(c) - require.NoError(t, err) - - tlsCfg, err := json.Marshal(tc.tlsCfg) - require.NoError(t, err) - - tmpDir := testhelper.TempDir(t) - - env := map[string]string{ - "GL_REPOSITORY": "project-1", - "GL_INTERNAL_CONFIG": string(cfg), - "GITALY_LOG_DIR": tmpDir, - "GITALY_TLS": string(tlsCfg), - } - - if tc.missingEnv != "" { - delete(env, tc.missingEnv) - } - - cfgProvider := &mapConfig{env: env} - - var b bytes.Buffer - reader := strings.NewReader(tc.data) - - _, err = initLogging(cfgProvider) - require.NoError(t, err) - - err = smudge(&b, reader, cfgProvider) - - if tc.expectedError { - require.Error(t, err) - } else { - require.NoError(t, err) - require.Equal(t, tc.data, b.String()) - } - - logFilename := filepath.Join(tmpDir, "gitaly_lfs_smudge.log") - require.FileExists(t, logFilename) - - data := testhelper.MustReadFile(t, logFilename) - - if tc.expectedLogMessage != "" { - require.Contains(t, string(data), tc.expectedLogMessage) - } - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/main.go deleted file mode 100644 index 314105b500..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-lfs-smudge/main.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "fmt" - "os" -) - -type envConfig struct{} - -func (e *envConfig) Get(key string) string { - return os.Getenv(key) -} - -func requireStdin(msg string) { - var out string - - stat, err := os.Stdin.Stat() - if err != nil { - out = fmt.Sprintf("Cannot read from STDIN. %s (%s)", msg, err) - } else if (stat.Mode() & os.ModeCharDevice) != 0 { - out = fmt.Sprintf("Cannot read from STDIN. %s", msg) - } - - if len(out) > 0 { - fmt.Println(out) - os.Exit(1) - } -} - -func main() { - requireStdin("This command should be run by the Git 'smudge' filter") - - closer, err := initLogging(&envConfig{}) - if err != nil { - fmt.Fprintf(os.Stderr, "error initializing log file for gitaly-lfs-smudge: %v", err) - } - defer closer.Close() - - err = smudge(os.Stdout, os.Stdin, &envConfig{}) - if err != nil { - os.Exit(1) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile deleted file mode 100644 index 0d89eafbc5..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gem 'gitlab-dangerfiles', '~> 3.1.0', require: false diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile.lock b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile.lock deleted file mode 100644 index 6dc3748784..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/Gemfile.lock +++ /dev/null @@ -1,101 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - claide (1.1.0) - claide-plugins (0.9.2) - cork - nap - open4 (~> 1.3) - colored2 (3.1.2) - cork (0.3.0) - colored2 (~> 3.1) - danger (8.6.0) - claide (~> 1.0) - claide-plugins (>= 0.9.2) - colored2 (~> 3.1) - cork (~> 0.1) - faraday (>= 0.9.0, < 2.0) - faraday-http-cache (~> 2.0) - git (~> 1.7) - kramdown (~> 2.3) - kramdown-parser-gfm (~> 1.0) - no_proxy_fix - octokit (~> 4.7) - terminal-table (>= 1, < 4) - danger-gitlab (8.0.0) - danger - gitlab (~> 4.2, >= 4.2.0) - faraday (1.10.0) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-http-cache (2.2.0) - faraday (>= 0.8) - faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - git (1.11.0) - rchardet (~> 1.8) - gitlab (4.18.0) - httparty (~> 0.18) - terminal-table (>= 1.5.1) - gitlab-dangerfiles (3.1.0) - danger (>= 8.4.5) - danger-gitlab (>= 8.0.0) - rake - httparty (0.20.0) - mime-types (~> 3.0) - multi_xml (>= 0.5.2) - kramdown (2.3.2) - rexml - kramdown-parser-gfm (1.1.0) - kramdown (~> 2.0) - mime-types (3.4.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - multi_xml (0.6.0) - multipart-post (2.1.1) - nap (1.1.0) - no_proxy_fix (0.1.2) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) - open4 (1.3.4) - public_suffix (4.0.7) - rake (13.0.6) - rchardet (1.8.0) - rexml (3.2.5) - ruby2_keywords (0.0.5) - sawyer (0.8.2) - addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.1.0) - -PLATFORMS - ruby - -DEPENDENCIES - gitlab-dangerfiles (~> 3.1.0) - -BUNDLED WITH - 2.2.33 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.mod b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.mod deleted file mode 100644 index 6c4fd51060..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.mod +++ /dev/null @@ -1,53 +0,0 @@ -module gitlab.com/gitlab-org/gitaly/v14 - -exclude ( - // grpc-go version v1.34.0 and v1.35.0-dev have a bug that affects unix domain docket - // dialing. It should be avoided until upgraded to a newer fixed - // version. More details: - // https://github.com/grpc/grpc-go/issues/3990 - github.com/grpc/grpc-go v1.34.0 - github.com/grpc/grpc-go v1.35.0-dev -) - -require ( - github.com/beevik/ntp v0.3.0 - github.com/cloudflare/tableflip v1.2.2 - github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99 - github.com/getsentry/sentry-go v0.10.0 - github.com/git-lfs/git-lfs v1.5.1-0.20210304194248-2e1d981afbe3 - github.com/go-enry/go-license-detector/v4 v4.3.0 - github.com/go-git/go-git/v5 v5.3.0 // indirect - github.com/google/go-cmp v0.5.5 - github.com/google/uuid v1.2.0 - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/hashicorp/golang-lru v0.5.4 - github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 - github.com/jackc/pgconn v1.10.1 - github.com/jackc/pgtype v1.9.1 - github.com/jackc/pgx/v4 v4.14.1 - github.com/kelseyhightower/envconfig v1.3.0 - github.com/libgit2/git2go/v33 v33.0.9 - github.com/olekukonko/tablewriter v0.0.2 - github.com/opencontainers/runtime-spec v1.0.2 - github.com/opentracing/opentracing-go v1.2.0 - github.com/pelletier/go-toml v1.8.1 - github.com/prometheus/client_golang v1.10.0 - github.com/prometheus/client_model v0.2.0 - github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237 - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 - github.com/uber/jaeger-client-go v2.27.0+incompatible - gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 - gitlab.com/gitlab-org/labkit v1.5.0 - go.uber.org/goleak v1.1.10 - gocloud.dev v0.23.0 - golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 - golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 - google.golang.org/grpc v1.38.0 - google.golang.org/protobuf v1.26.0 -) - -go 1.16 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/boring.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/boring.go deleted file mode 100644 index cc09fab9d8..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/boring.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build boringcrypto -// +build boringcrypto - -package boring - -import ( - "crypto/boring" - - "gitlab.com/gitlab-org/labkit/log" -) - -// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go -// compiler in https://github.com/golang-fips/go, this requires that: -// -// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). -// 2. A system OpenSSL can be dynamically loaded via ldopen(). -func CheckBoring() { - if boring.Enabled() { - log.Info("FIPS mode is enabled. Using an external SSL library.") - return - } - log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/notboring.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/notboring.go deleted file mode 100644 index 1a7eb52f73..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/boring/notboring.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !boringcrypto -// +build !boringcrypto - -package boring - -// CheckBoring does nothing when the boringcrypto tag is not in the -// build. -func CheckBoring() { -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups.go deleted file mode 100644 index 273746685f..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups.go +++ /dev/null @@ -1,32 +0,0 @@ -package cgroups - -import ( - "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" -) - -// Manager supplies an interface for interacting with cgroups -type Manager interface { - // Setup creates cgroups and assigns configured limitations. - // It is expected to be called once at Gitaly startup from any - // instance of the Manager. - Setup() error - // AddCommand adds a Command to a cgroup - AddCommand(*command.Command) error - // Cleanup cleans up cgroups created in Setup. - // It is expected to be called once at Gitaly shutdown from any - // instance of the Manager. - Cleanup() error - Describe(ch chan<- *prometheus.Desc) - Collect(ch chan<- prometheus.Metric) -} - -// NewManager returns the appropriate Cgroups manager -func NewManager(cfg cgroups.Config) Manager { - if cfg.Count > 0 { - return newV1Manager(cfg) - } - - return &NoopManager{} -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups_linux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups_linux_test.go deleted file mode 100644 index 9d8267bffc..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/cgroups_linux_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package cgroups - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func TestNewManager(t *testing.T) { - cfg := cgroups.Config{Count: 10} - - require.IsType(t, &CGroupV1Manager{}, &CGroupV1Manager{cfg: cfg}) - require.IsType(t, &NoopManager{}, NewManager(cgroups.Config{})) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux.go deleted file mode 100644 index d98a758076..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux.go +++ /dev/null @@ -1,189 +0,0 @@ -package cgroups - -import ( - "fmt" - "hash/crc32" - "os" - "strings" - - "github.com/containerd/cgroups" - specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - cgroupscfg "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" -) - -// CGroupV1Manager is the manager for cgroups v1 -type CGroupV1Manager struct { - cfg cgroupscfg.Config - hierarchy func() ([]cgroups.Subsystem, error) - memoryFailedTotal, cpuUsage *prometheus.GaugeVec - procs *prometheus.GaugeVec -} - -func newV1Manager(cfg cgroupscfg.Config) *CGroupV1Manager { - return &CGroupV1Manager{ - cfg: cfg, - hierarchy: func() ([]cgroups.Subsystem, error) { - return defaultSubsystems(cfg.Mountpoint) - }, - memoryFailedTotal: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "gitaly_cgroup_memory_failed_total", - Help: "Number of memory usage hits limits", - }, - []string{"path"}, - ), - cpuUsage: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "gitaly_cgroup_cpu_usage", - Help: "CPU Usage of Cgroup", - }, - []string{"path", "type"}, - ), - procs: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "gitaly_cgroup_procs_total", - Help: "Total number of procs", - }, - []string{"path", "subsystem"}, - ), - } -} - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (cg *CGroupV1Manager) Setup() error { - resources := &specs.LinuxResources{} - - if cg.cfg.CPU.Enabled { - resources.CPU = &specs.LinuxCPU{ - Shares: &cg.cfg.CPU.Shares, - } - } - - if cg.cfg.Memory.Enabled { - resources.Memory = &specs.LinuxMemory{ - Limit: &cg.cfg.Memory.Limit, - } - } - - for i := 0; i < int(cg.cfg.Count); i++ { - _, err := cgroups.New(cg.hierarchy, cgroups.StaticPath(cg.cgroupPath(i)), resources) - if err != nil { - return fmt.Errorf("failed creating cgroup: %w", err) - } - } - - return nil -} - -// AddCommand adds the given command to one of the CGroup's buckets. The bucket used for the command -// is determined by hashing the commands arguments. No error is returned if the command has already -// exited. -func (cg *CGroupV1Manager) AddCommand(cmd *command.Command) error { - checksum := crc32.ChecksumIEEE([]byte(strings.Join(cmd.Args(), ""))) - groupID := uint(checksum) % cg.cfg.Count - cgroupPath := cg.cgroupPath(int(groupID)) - - control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(cgroupPath)) - if err != nil { - return fmt.Errorf("failed loading %s cgroup: %w", cgroupPath, err) - } - - if err := control.Add(cgroups.Process{Pid: cmd.Pid()}); err != nil { - // Command could finish so quickly before we can add it to a cgroup, so - // we don't consider it an error. - if strings.Contains(err.Error(), "no such process") { - return nil - } - return fmt.Errorf("failed adding process to cgroup: %w", err) - } - - cmd.SetCgroupPath(cgroupPath) - - return nil -} - -// Collect collects metrics from the cgroups controller -func (cg *CGroupV1Manager) Collect(ch chan<- prometheus.Metric) { - path := cg.currentProcessCgroup() - logger := log.Default().WithField("cgroup_path", path) - control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(path)) - if err != nil { - logger.WithError(err).Warn("unable to load cgroup controller") - return - } - - if metrics, err := control.Stat(); err != nil { - logger.WithError(err).Warn("unable to get cgroup stats") - } else { - memoryMetric := cg.memoryFailedTotal.WithLabelValues(path) - memoryMetric.Set(float64(metrics.Memory.Usage.Failcnt)) - ch <- memoryMetric - - cpuUserMetric := cg.cpuUsage.WithLabelValues(path, "user") - cpuUserMetric.Set(float64(metrics.CPU.Usage.User)) - ch <- cpuUserMetric - - cpuKernelMetric := cg.cpuUsage.WithLabelValues(path, "kernel") - cpuKernelMetric.Set(float64(metrics.CPU.Usage.Kernel)) - ch <- cpuKernelMetric - } - - if subsystems, err := cg.hierarchy(); err != nil { - logger.WithError(err).Warn("unable to get cgroup hierarchy") - } else { - for _, subsystem := range subsystems { - processes, err := control.Processes(subsystem.Name(), true) - if err != nil { - logger.WithField("subsystem", subsystem.Name()). - WithError(err). - Warn("unable to get process list") - continue - } - - procsMetric := cg.procs.WithLabelValues(path, string(subsystem.Name())) - procsMetric.Set(float64(len(processes))) - ch <- procsMetric - } - } -} - -// Describe describes the cgroup metrics that Collect provides -func (cg *CGroupV1Manager) Describe(ch chan<- *prometheus.Desc) { - prometheus.DescribeByCollect(cg, ch) -} - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (cg *CGroupV1Manager) Cleanup() error { - processCgroupPath := cg.currentProcessCgroup() - - control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(processCgroupPath)) - if err != nil { - return fmt.Errorf("failed loading cgroup %s: %w", processCgroupPath, err) - } - - if err := control.Delete(); err != nil { - return fmt.Errorf("failed cleaning up cgroup %s: %w", processCgroupPath, err) - } - - return nil -} - -func (cg *CGroupV1Manager) cgroupPath(groupID int) string { - return fmt.Sprintf("/%s/shard-%d", cg.currentProcessCgroup(), groupID) -} - -func (cg *CGroupV1Manager) currentProcessCgroup() string { - return fmt.Sprintf("/%s/gitaly-%d", cg.cfg.HierarchyRoot, os.Getpid()) -} - -func defaultSubsystems(root string) ([]cgroups.Subsystem, error) { - subsystems := []cgroups.Subsystem{ - cgroups.NewMemory(root, cgroups.OptionalSwap()), - cgroups.NewCpu(root), - } - - return subsystems, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux_test.go deleted file mode 100644 index 4db332830e..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1_linux_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package cgroups - -import ( - "bytes" - "fmt" - "hash/crc32" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "github.com/prometheus/client_golang/prometheus/testutil" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func defaultCgroupsConfig() cgroups.Config { - return cgroups.Config{ - Count: 3, - HierarchyRoot: "gitaly", - CPU: cgroups.CPU{ - Enabled: true, - Shares: 256, - }, - Memory: cgroups.Memory{ - Enabled: true, - Limit: 1024000, - }, - } -} - -func TestSetup(t *testing.T) { - mock := newMock(t) - - v1Manager := &CGroupV1Manager{ - cfg: defaultCgroupsConfig(), - hierarchy: mock.hierarchy, - } - require.NoError(t, v1Manager.Setup()) - - for i := 0; i < 3; i++ { - memoryPath := filepath.Join( - mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", os.Getpid()), fmt.Sprintf("shard-%d", i), "memory.limit_in_bytes", - ) - memoryContent := readCgroupFile(t, memoryPath) - - require.Equal(t, string(memoryContent), "1024000") - - cpuPath := filepath.Join( - mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", os.Getpid()), fmt.Sprintf("shard-%d", i), "cpu.shares", - ) - cpuContent := readCgroupFile(t, cpuPath) - - require.Equal(t, string(cpuContent), "256") - } -} - -func TestAddCommand(t *testing.T) { - mock := newMock(t) - - config := defaultCgroupsConfig() - v1Manager1 := &CGroupV1Manager{ - cfg: config, - hierarchy: mock.hierarchy, - } - require.NoError(t, v1Manager1.Setup()) - ctx := testhelper.Context(t) - - cmd1 := exec.Command("ls", "-hal", ".") - cmd2, err := command.New(ctx, cmd1, nil, nil, nil) - require.NoError(t, err) - require.NoError(t, cmd2.Wait()) - - v1Manager2 := &CGroupV1Manager{ - cfg: config, - hierarchy: mock.hierarchy, - } - require.NoError(t, v1Manager2.AddCommand(cmd2)) - - checksum := crc32.ChecksumIEEE([]byte(strings.Join(cmd2.Args(), ""))) - groupID := uint(checksum) % config.Count - - for _, s := range mock.subsystems { - path := filepath.Join(mock.root, string(s.Name()), "gitaly", fmt.Sprintf("gitaly-%d", os.Getpid()), fmt.Sprintf("shard-%d", groupID), "cgroup.procs") - content := readCgroupFile(t, path) - - pid, err := strconv.Atoi(string(content)) - require.NoError(t, err) - - require.Equal(t, cmd2.Pid(), pid) - } -} - -func TestCleanup(t *testing.T) { - mock := newMock(t) - - v1Manager := &CGroupV1Manager{ - cfg: defaultCgroupsConfig(), - hierarchy: mock.hierarchy, - } - require.NoError(t, v1Manager.Setup()) - require.NoError(t, v1Manager.Cleanup()) - - for i := 0; i < 3; i++ { - memoryPath := filepath.Join(mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", os.Getpid()), fmt.Sprintf("shard-%d", i)) - cpuPath := filepath.Join(mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", os.Getpid()), fmt.Sprintf("shard-%d", i)) - - require.NoDirExists(t, memoryPath) - require.NoDirExists(t, cpuPath) - } -} - -func TestMetrics(t *testing.T) { - mock := newMock(t) - - config := defaultCgroupsConfig() - v1Manager1 := newV1Manager(config) - v1Manager1.hierarchy = mock.hierarchy - - mock.setupMockCgroupFiles(t, v1Manager1, 2) - - require.NoError(t, v1Manager1.Setup()) - ctx := testhelper.Context(t) - - logger, hook := test.NewNullLogger() - logger.SetLevel(logrus.DebugLevel) - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd1 := exec.Command("ls", "-hal", ".") - cmd2, err := command.New(ctx, cmd1, nil, nil, nil) - require.NoError(t, err) - - require.NoError(t, v1Manager1.AddCommand(cmd2)) - require.NoError(t, cmd2.Wait()) - - processCgroupPath := v1Manager1.currentProcessCgroup() - - expected := bytes.NewBufferString(fmt.Sprintf(`# HELP gitaly_cgroup_cpu_usage CPU Usage of Cgroup -# TYPE gitaly_cgroup_cpu_usage gauge -gitaly_cgroup_cpu_usage{path="%s",type="kernel"} 0 -gitaly_cgroup_cpu_usage{path="%s",type="user"} 0 -# HELP gitaly_cgroup_memory_failed_total Number of memory usage hits limits -# TYPE gitaly_cgroup_memory_failed_total gauge -gitaly_cgroup_memory_failed_total{path="%s"} 2 -# HELP gitaly_cgroup_procs_total Total number of procs -# TYPE gitaly_cgroup_procs_total gauge -gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 -gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 -`, processCgroupPath, processCgroupPath, processCgroupPath, processCgroupPath, processCgroupPath)) - assert.NoError(t, testutil.CollectAndCompare( - v1Manager1, - expected, - "gitaly_cgroup_memory_failed_total", - "gitaly_cgroup_cpu_usage", - "gitaly_cgroup_procs_total")) - - logEntry := hook.LastEntry() - assert.Contains( - t, - logEntry.Data["command.cgroup_path"], - processCgroupPath, - "log field includes a cgroup path that is a subdirectory of the current process' cgroup path", - ) -} - -func readCgroupFile(t *testing.T, path string) []byte { - t.Helper() - - // The cgroups package defaults to permission 0 as it expects the file to be existing (the kernel creates the file) - // and its testing override the permission private variable to something sensible, hence we have to chmod ourselves - // so we can read the file. - require.NoError(t, os.Chmod(path, 0o666)) - - return testhelper.MustReadFile(t, path) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command_test.go deleted file mode 100644 index 3ff5cbac86..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command_test.go +++ /dev/null @@ -1,386 +0,0 @@ -package command - -import ( - "bytes" - "context" - "fmt" - "io" - "os/exec" - "regexp" - "runtime" - "strings" - "testing" - "time" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func TestNewCommandExtraEnv(t *testing.T) { - ctx := testhelper.Context(t) - - extraVar := "FOOBAR=123456" - buff := &bytes.Buffer{} - cmd, err := New(ctx, exec.Command("/usr/bin/env"), nil, buff, nil, extraVar) - - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - - require.Contains(t, strings.Split(buff.String(), "\n"), extraVar) -} - -func TestNewCommandExportedEnv(t *testing.T) { - ctx := testhelper.Context(t) - - testCases := []struct { - key string - value string - }{ - { - key: "HOME", - value: "/home/git", - }, - { - key: "PATH", - value: "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin", - }, - { - key: "LD_LIBRARY_PATH", - value: "/path/to/your/lib", - }, - { - key: "TZ", - value: "foobar", - }, - { - key: "GIT_TRACE", - value: "true", - }, - { - key: "GIT_TRACE_PACK_ACCESS", - value: "true", - }, - { - key: "GIT_TRACE_PACKET", - value: "true", - }, - { - key: "GIT_TRACE_PERFORMANCE", - value: "true", - }, - { - key: "GIT_TRACE_SETUP", - value: "true", - }, - { - key: "all_proxy", - value: "http://localhost:4000", - }, - { - key: "http_proxy", - value: "http://localhost:5000", - }, - { - key: "HTTP_PROXY", - value: "http://localhost:6000", - }, - { - key: "https_proxy", - value: "https://localhost:5000", - }, - { - key: "HTTPS_PROXY", - value: "https://localhost:6000", - }, - { - key: "no_proxy", - value: "https://excluded:5000", - }, - { - key: "NO_PROXY", - value: "https://excluded:5000", - }, - } - - for _, tc := range testCases { - t.Run(tc.key, func(t *testing.T) { - if tc.key == "LD_LIBRARY_PATH" && runtime.GOOS == "darwin" { - t.Skip("System Integrity Protection prevents using dynamic linker (dyld) environment variables on macOS. https://apple.co/2XDH4iC") - } - - testhelper.ModifyEnvironment(t, tc.key, tc.value) - - buff := &bytes.Buffer{} - cmd, err := New(ctx, exec.Command("/usr/bin/env"), nil, buff, nil) - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - - expectedEnv := fmt.Sprintf("%s=%s", tc.key, tc.value) - require.Contains(t, strings.Split(buff.String(), "\n"), expectedEnv) - }) - } -} - -func TestNewCommandUnexportedEnv(t *testing.T) { - ctx := testhelper.Context(t) - - unexportedEnvKey, unexportedEnvVal := "GITALY_UNEXPORTED_ENV", "foobar" - testhelper.ModifyEnvironment(t, unexportedEnvKey, unexportedEnvVal) - - buff := &bytes.Buffer{} - cmd, err := New(ctx, exec.Command("/usr/bin/env"), nil, buff, nil) - - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - - require.NotContains(t, strings.Split(buff.String(), "\n"), fmt.Sprintf("%s=%s", unexportedEnvKey, unexportedEnvVal)) -} - -func TestRejectEmptyContextDone(t *testing.T) { - defer func() { - p := recover() - if p == nil { - t.Error("expected panic, got none") - return - } - - if _, ok := p.(contextWithoutDonePanic); !ok { - panic(p) - } - }() - - _, err := New(testhelper.ContextWithoutCancel(), exec.Command("true"), nil, nil, nil) - require.NoError(t, err) -} - -func TestNewCommandTimeout(t *testing.T) { - ctx := testhelper.Context(t) - - defer func(ch chan struct{}, t time.Duration) { - spawnTokens = ch - spawnConfig.Timeout = t - }(spawnTokens, spawnConfig.Timeout) - - // This unbuffered channel will behave like a full/blocked buffered channel. - spawnTokens = make(chan struct{}) - // Speed up the test by lowering the timeout - spawnTimeout := 200 * time.Millisecond - spawnConfig.Timeout = spawnTimeout - - testDeadline := time.After(1 * time.Second) - tick := time.After(spawnTimeout / 2) - - errCh := make(chan error) - go func() { - _, err := New(ctx, exec.Command("true"), nil, nil, nil) - errCh <- err - }() - - var err error - timePassed := false - -wait: - for { - select { - case err = <-errCh: - break wait - case <-tick: - timePassed = true - case <-testDeadline: - t.Fatal("test timed out") - } - } - - require.True(t, timePassed, "time must have passed") - require.Error(t, err) - require.Contains(t, err.Error(), "process spawn timed out after") -} - -func TestCommand_Wait_interrupts_after_context_cancellation(t *testing.T) { - ctx, cancel := context.WithCancel(testhelper.Context(t)) - - cmd, err := New(ctx, exec.CommandContext(ctx, "sleep", "1h"), nil, nil, nil) - require.NoError(t, err) - - // Cancel the command early. - go cancel() - - err = cmd.Wait() - require.Error(t, err) - s, ok := ExitStatus(err) - require.True(t, ok) - require.Equal(t, -1, s) -} - -func TestNewCommandWithSetupStdin(t *testing.T) { - ctx := testhelper.Context(t) - - value := "Test value" - output := bytes.NewBuffer(nil) - - cmd, err := New(ctx, exec.Command("cat"), SetupStdin, nil, nil) - require.NoError(t, err) - - _, err = fmt.Fprintf(cmd, "%s", value) - require.NoError(t, err) - - // The output of the `cat` subprocess should exactly match its input - _, err = io.CopyN(output, cmd, int64(len(value))) - require.NoError(t, err) - require.Equal(t, value, output.String()) - - require.NoError(t, cmd.Wait()) -} - -func TestNewCommandNullInArg(t *testing.T) { - ctx := testhelper.Context(t) - - _, err := New(ctx, exec.Command("sh", "-c", "hello\x00world"), nil, nil, nil) - require.Error(t, err) - require.EqualError(t, err, `detected null byte in command argument "hello\x00world"`) -} - -func TestNewNonExistent(t *testing.T) { - ctx := testhelper.Context(t) - - cmd, err := New(ctx, exec.Command("command-non-existent"), nil, nil, nil) - require.Nil(t, cmd) - require.Error(t, err) -} - -func TestCommandStdErr(t *testing.T) { - ctx := testhelper.Context(t) - - var stdout, stderr bytes.Buffer - expectedMessage := `hello world\nhello world\nhello world\nhello world\nhello world\n` - - logger := logrus.New() - logger.SetOutput(&stderr) - - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("./testdata/stderr_script.sh"), nil, &stdout, nil) - require.NoError(t, err) - require.Error(t, cmd.Wait()) - - assert.Empty(t, stdout.Bytes()) - require.Equal(t, expectedMessage, extractLastMessage(stderr.String())) -} - -func TestCommandStdErrLargeOutput(t *testing.T) { - ctx := testhelper.Context(t) - - var stdout, stderr bytes.Buffer - - logger := logrus.New() - logger.SetOutput(&stderr) - - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("./testdata/stderr_many_lines.sh"), nil, &stdout, nil) - require.NoError(t, err) - require.Error(t, cmd.Wait()) - - assert.Empty(t, stdout.Bytes()) - msg := strings.ReplaceAll(extractLastMessage(stderr.String()), "\\n", "\n") - require.LessOrEqual(t, len(msg), maxStderrBytes) -} - -func TestCommandStdErrBinaryNullBytes(t *testing.T) { - ctx := testhelper.Context(t) - - var stdout, stderr bytes.Buffer - - logger := logrus.New() - logger.SetOutput(&stderr) - - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("./testdata/stderr_binary_null.sh"), nil, &stdout, nil) - require.NoError(t, err) - require.Error(t, cmd.Wait()) - - assert.Empty(t, stdout.Bytes()) - msg := strings.SplitN(extractLastMessage(stderr.String()), "\\n", 2)[0] - require.Equal(t, strings.Repeat("\\x00", maxStderrLineLength), msg) -} - -func TestCommandStdErrLongLine(t *testing.T) { - ctx := testhelper.Context(t) - - var stdout, stderr bytes.Buffer - - logger := logrus.New() - logger.SetOutput(&stderr) - - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("./testdata/stderr_repeat_a.sh"), nil, &stdout, nil) - require.NoError(t, err) - require.Error(t, cmd.Wait()) - - assert.Empty(t, stdout.Bytes()) - require.Contains(t, stderr.String(), fmt.Sprintf("%s\\n%s", strings.Repeat("a", maxStderrLineLength), strings.Repeat("b", maxStderrLineLength))) -} - -func TestCommandStdErrMaxBytes(t *testing.T) { - ctx := testhelper.Context(t) - - var stdout, stderr bytes.Buffer - - logger := logrus.New() - logger.SetOutput(&stderr) - - ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("./testdata/stderr_max_bytes_edge_case.sh"), nil, &stdout, nil) - require.NoError(t, err) - require.Error(t, cmd.Wait()) - - assert.Empty(t, stdout.Bytes()) - message := extractLastMessage(stderr.String()) - require.Equal(t, maxStderrBytes, len(strings.ReplaceAll(message, "\\n", "\n"))) -} - -var logMsgRegex = regexp.MustCompile(`msg="(.+?)"`) - -func extractLastMessage(logMessage string) string { - subMatchesAll := logMsgRegex.FindAllStringSubmatch(logMessage, -1) - if len(subMatchesAll) < 1 { - return "" - } - - subMatches := subMatchesAll[len(subMatchesAll)-1] - if len(subMatches) != 2 { - return "" - } - - return subMatches[1] -} - -func TestCommand_logMessage(t *testing.T) { - logger, hook := test.NewNullLogger() - logger.SetLevel(logrus.DebugLevel) - - ctx := ctxlogrus.ToContext(testhelper.Context(t), logrus.NewEntry(logger)) - - cmd, err := New(ctx, exec.Command("echo", "hello world"), nil, nil, nil) - require.NoError(t, err) - cgroupPath := "/sys/fs/cgroup/1" - cmd.SetCgroupPath(cgroupPath) - - require.NoError(t, cmd.Wait()) - logEntry := hook.LastEntry() - assert.Equal(t, cmd.Pid(), logEntry.Data["pid"]) - assert.Equal(t, []string{"echo", "hello world"}, logEntry.Data["args"]) - assert.Equal(t, 0, logEntry.Data["command.exitCode"]) - assert.Equal(t, cgroupPath, logEntry.Data["command.cgroup_path"]) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_binary_null.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_binary_null.sh deleted file mode 100755 index e8e1d0baa9..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_binary_null.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -dd if=/dev/zero bs=1000 count=1000 >&2 -exit 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_many_lines.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_many_lines.sh deleted file mode 100755 index e8b51b6466..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_many_lines.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -let x=0 -while [ $x -lt 100010 ] -do - let x=x+1 - printf '%06d zzzzzzzzzz\n' $x >&2 -done -exit 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_max_bytes_edge_case.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_max_bytes_edge_case.sh deleted file mode 100755 index 6e1454966e..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_max_bytes_edge_case.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# This script is used to test that a command writes at most maxBytes to stderr. It simulates the -# edge case where the logwriter has already written MaxStderrBytes-1 (9999) bytes - -# This edge case happens when 9999 bytes are written. To simulate this, stderr_max_bytes_edge_case has 4 lines of the following format: -# line1: 3333 bytes long -# line2: 3331 bytes -# line3: 3331 bytes -# line4: 1 byte -# The first 3 lines sum up to 9999 bytes written, since we write a 2-byte escaped `\n` for each \n we see. -# The 4th line can be any data. - -printf 'a%.0s' {1..3333} >&2 -printf '\n' >&2 -printf 'a%.0s' {1..3331} >&2 -printf '\n' >&2 -printf 'a%.0s' {1..3331} >&2 -printf '\na\n' >&2 -exit 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_repeat_a.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_repeat_a.sh deleted file mode 100755 index 8463929ae2..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_repeat_a.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -printf 'a%.0s' {1..8192} >&2 -printf '\n' >&2 -printf 'b%.0s' {1..8192} >&2 -exit 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_script.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_script.sh deleted file mode 100755 index 57abd97d0f..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/testdata/stderr_script.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -for i in {1..5} -do - echo 'hello world' 1>&2 -done -exit 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit_test.go deleted file mode 100644 index f53e4736b8..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package catfile - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/metadata" -) - -func TestGetCommit(t *testing.T) { - ctx := testhelper.Context(t) - - _, objectReader, _ := setupObjectReader(t, ctx) - - ctx = metadata.NewIncomingContext(ctx, metadata.MD{}) - - const commitSha = "2d1db523e11e777e49377cfb22d368deec3f0793" - const commitMsg = "Correct test_env.rb path for adding branch\n" - const blobSha = "c60514b6d3d6bf4bec1030f70026e34dfbd69ad5" - - testCases := []struct { - desc string - revision string - errStr string - }{ - { - desc: "commit", - revision: commitSha, - }, - { - desc: "not existing commit", - revision: "not existing revision", - errStr: "object not found", - }, - { - desc: "blob sha", - revision: blobSha, - errStr: "object not found", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - c, err := GetCommit(ctx, objectReader, git.Revision(tc.revision)) - - if tc.errStr == "" { - require.NoError(t, err) - require.Equal(t, commitMsg, string(c.Body)) - } else { - require.EqualError(t, err, tc.errStr) - } - }) - } -} - -func TestGetCommitWithTrailers(t *testing.T) { - ctx := testhelper.Context(t) - - cfg, objectReader, testRepo := setupObjectReader(t, ctx) - - ctx = metadata.NewIncomingContext(ctx, metadata.MD{}) - - commit, err := GetCommitWithTrailers(ctx, gittest.NewCommandFactory(t, cfg), testRepo, - objectReader, "5937ac0a7beb003549fc5fd26fc247adbce4a52e") - - require.NoError(t, err) - - require.Equal(t, commit.Trailers, []*gitalypb.CommitTrailer{ - { - Key: []byte("Signed-off-by"), - Value: []byte("Dmitriy Zaporozhets "), - }, - }) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description_test.go deleted file mode 100644 index 52da034c32..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package git - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCommandDescriptions_revListPositionalArgs(t *testing.T) { - revlist, ok := commandDescriptions["rev-list"] - require.True(t, ok) - require.NotNil(t, revlist.validatePositionalArgs) - - for _, tc := range []struct { - desc string - args []string - expectedErr error - }{ - { - desc: "normal reference", - args: []string{ - "master", - }, - }, - { - desc: "reference with leading dash", - args: []string{ - "-master", - }, - expectedErr: fmt.Errorf("rev-list: %w", - fmt.Errorf("positional arg \"-master\" cannot start with dash '-': %w", ErrInvalidArg), - ), - }, - { - desc: "revisions and pseudo-revisions", - args: []string{ - "master --not --all", - }, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - err := revlist.validatePositionalArgs(tc.args) - require.Equal(t, tc.expectedErr, err) - }) - } -} - -func TestThreadsConfigValue(t *testing.T) { - t.Parallel() - for _, tt := range []struct { - cpus int - threads string - }{ - {1, "1"}, - {2, "1"}, - {3, "1"}, - {4, "2"}, - {8, "3"}, - {9, "3"}, - {13, "3"}, - {16, "4"}, - {27, "4"}, - {32, "5"}, - } { - actualThreads := threadsConfigValue(tt.cpus) - require.Equal(t, tt.threads, actualThreads) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_test.go deleted file mode 100644 index 0c774d48d7..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package gitpipe - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" -) - -const ( - lfsPointer1 = "0c304a93cb8430108629bbbcaa27db3343299bc0" - lfsPointer2 = "f78df813119a79bfbe0442ab92540a61d3ab7ff3" - lfsPointer3 = "bab31d249f78fba464d1b75799aad496cc07fa3b" - lfsPointer4 = "125fcc9f6e33175cb278b9b2809154d2535fe19f" -) - -func TestCatfileInfo(t *testing.T) { - cfg := testcfg.Build(t) - - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - for _, tc := range []struct { - desc string - revlistInputs []RevisionResult - opts []CatfileInfoOption - expectedResults []CatfileInfoResult - expectedErr error - }{ - { - desc: "single blob", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - }, - }, - { - desc: "multiple blobs", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - {OID: lfsPointer2}, - {OID: lfsPointer3}, - {OID: lfsPointer4}, - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, - }, - }, - { - desc: "object name", - revlistInputs: []RevisionResult{ - {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, - {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")}, - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, - }, - }, - { - desc: "invalid object ID", - revlistInputs: []RevisionResult{ - {OID: "invalidobjectid"}, - }, - expectedErr: errors.New("retrieving object info for \"invalidobjectid\": object not found"), - }, - { - desc: "mixed valid and invalid revision", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - {OID: "invalidobjectid"}, - {OID: lfsPointer2}, - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - }, - expectedErr: errors.New("retrieving object info for \"invalidobjectid\": object not found"), - }, - { - desc: "skip everything", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - {OID: lfsPointer2}, - }, - opts: []CatfileInfoOption{ - WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return true }), - }, - }, - { - desc: "skip one", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - {OID: lfsPointer2}, - }, - opts: []CatfileInfoOption{ - WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool { - return objectInfo.Oid == lfsPointer1 - }), - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - }, - }, - { - desc: "skip nothing", - revlistInputs: []RevisionResult{ - {OID: lfsPointer1}, - {OID: lfsPointer2}, - }, - opts: []CatfileInfoOption{ - WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return false }), - }, - expectedResults: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - }, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) - - catfileCache := catfile.NewCache(cfg) - defer catfileCache.Stop() - - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) - require.NoError(t, err) - - it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(tc.revlistInputs), tc.opts...) - require.NoError(t, err) - - var results []CatfileInfoResult - for it.Next() { - results = append(results, it.Result()) - } - - // We're converting the error here to a plain un-nested error such - // that we don't have to replicate the complete error's structure. - err = it.Err() - if err != nil { - err = errors.New(err.Error()) - } - - require.Equal(t, tc.expectedErr, err) - require.Equal(t, tc.expectedResults, results) - }) - } -} - -func TestCatfileInfoAllObjects(t *testing.T) { - cfg := testcfg.Build(t) - ctx := testhelper.Context(t) - - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - blob1 := gittest.WriteBlob(t, cfg, repoPath, []byte("foobar")) - blob2 := gittest.WriteBlob(t, cfg, repoPath, []byte("barfoo")) - tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ - {Path: "foobar", Mode: "100644", OID: blob1}, - }) - commit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) - - it := CatfileInfoAllObjects(ctx, repo) - - var results []CatfileInfoResult - for it.Next() { - results = append(results, it.Result()) - } - require.NoError(t, it.Err()) - - require.ElementsMatch(t, []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: blob1, Type: "blob", Size: 6}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: blob2, Type: "blob", Size: 6}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: 34}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: 177}}, - }, results) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_test.go deleted file mode 100644 index fa74d2f069..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package gitpipe - -import ( - "errors" - "io" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" -) - -func TestCatfileObject(t *testing.T) { - cfg := testcfg.Build(t) - - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - for _, tc := range []struct { - desc string - catfileInfoInputs []CatfileInfoResult - expectedResults []CatfileObjectResult - expectedErr error - }{ - { - desc: "single blob", - catfileInfoInputs: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - }, - expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}}, - }, - }, - { - desc: "multiple blobs", - catfileInfoInputs: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, - }, - expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}}, - }, - }, - { - desc: "revlist result with object names", - catfileInfoInputs: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, - }, - expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")}, - }, - }, - { - desc: "invalid object ID", - catfileInfoInputs: []CatfileInfoResult{ - {ObjectInfo: &catfile.ObjectInfo{Oid: "invalidobjectid", Type: "blob"}}, - }, - expectedErr: errors.New("requesting object: object not found"), - }, - } { - t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) - - catfileCache := catfile.NewCache(cfg) - defer catfileCache.Stop() - - objectReader, err := catfileCache.ObjectReader(ctx, repo) - require.NoError(t, err) - - it, err := CatfileObject(ctx, objectReader, NewCatfileInfoIterator(tc.catfileInfoInputs)) - require.NoError(t, err) - - var results []CatfileObjectResult - for it.Next() { - result := it.Result() - - objectData, err := io.ReadAll(result) - require.NoError(t, err) - require.Len(t, objectData, int(result.ObjectSize())) - - // We only really want to compare the publicly visible fields - // containing info about the object itself, and not the object's - // private state. We thus need to reconstruct the objects here. - results = append(results, CatfileObjectResult{ - Object: &catfile.Object{ - ObjectInfo: catfile.ObjectInfo{ - Oid: result.ObjectID(), - Type: result.ObjectType(), - Size: result.ObjectSize(), - }, - }, - ObjectName: result.ObjectName, - }) - } - - // We're converting the error here to a plain un-nested error such - // that we don't have to replicate the complete error's structure. - err = it.Err() - if err != nil { - err = errors.New(err.Error()) - } - - require.Equal(t, tc.expectedErr, err) - require.Equal(t, tc.expectedResults, results) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/testhelper_test.go deleted file mode 100644 index 8b2532840e..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/testhelper_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package gitpipe - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command_factory.go deleted file mode 100644 index 8a368e2289..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command_factory.go +++ /dev/null @@ -1,18 +0,0 @@ -package gittest - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" -) - -// NewCommandFactory creates a new Git command factory. -func NewCommandFactory(tb testing.TB, cfg config.Cfg, opts ...git.ExecCommandFactoryOption) git.CommandFactory { - tb.Helper() - factory, cleanup, err := git.NewExecCommandFactory(cfg, opts...) - require.NoError(tb, err) - tb.Cleanup(cleanup) - return factory -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit.go deleted file mode 100644 index 50ab3aa2cb..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit.go +++ /dev/null @@ -1,179 +0,0 @@ -package gittest - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -const ( - committerName = "Scrooge McDuck" - committerEmail = "scrooge@mcduck.com" -) - -type writeCommitConfig struct { - branch string - parents []git.ObjectID - committerName string - message string - treeEntries []TreeEntry - alternateObjectDir string -} - -// WriteCommitOption is an option which can be passed to WriteCommit. -type WriteCommitOption func(*writeCommitConfig) - -// WithBranch is an option for WriteCommit which will cause it to update the update the given branch -// name to the new commit. -func WithBranch(branch string) WriteCommitOption { - return func(cfg *writeCommitConfig) { - cfg.branch = branch - } -} - -// WithMessage is an option for WriteCommit which will set the commit message. -func WithMessage(message string) WriteCommitOption { - return func(cfg *writeCommitConfig) { - cfg.message = message - } -} - -// WithParents is an option for WriteCommit which will set the parent OIDs of the resulting commit. -func WithParents(parents ...git.ObjectID) WriteCommitOption { - return func(cfg *writeCommitConfig) { - if parents != nil { - cfg.parents = parents - } else { - // We're explicitly initializing parents here such that we can discern the - // case where the commit should be created with no parents. - cfg.parents = []git.ObjectID{} - } - } -} - -// WithTreeEntries is an option for WriteCommit which will cause it to create a new tree and use it -// as root tree of the resulting commit. -func WithTreeEntries(entries ...TreeEntry) WriteCommitOption { - return func(cfg *writeCommitConfig) { - cfg.treeEntries = entries - } -} - -// WithCommitterName is an option for WriteCommit which will set the committer name. -func WithCommitterName(name string) WriteCommitOption { - return func(cfg *writeCommitConfig) { - cfg.committerName = name - } -} - -// WithAlternateObjectDirectory will cause the commit to be written into the given alternate object -// directory. This can either be an absolute path or a relative path. In the latter case the path -// is considered to be relative to the repository path. -func WithAlternateObjectDirectory(alternateObjectDir string) WriteCommitOption { - return func(cfg *writeCommitConfig) { - cfg.alternateObjectDir = alternateObjectDir - } -} - -// WriteCommit writes a new commit into the target repository. -func WriteCommit(t testing.TB, cfg config.Cfg, repoPath string, opts ...WriteCommitOption) git.ObjectID { - t.Helper() - - var writeCommitConfig writeCommitConfig - for _, opt := range opts { - opt(&writeCommitConfig) - } - - message := "message" - if writeCommitConfig.message != "" { - message = writeCommitConfig.message - } - stdin := bytes.NewBufferString(message) - - // The ID of an arbitrary commit known to exist in the test repository. - parents := []git.ObjectID{"1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"} - if writeCommitConfig.parents != nil { - parents = writeCommitConfig.parents - } - - var tree string - if len(writeCommitConfig.treeEntries) > 0 { - tree = WriteTree(t, cfg, repoPath, writeCommitConfig.treeEntries).String() - } else if len(parents) == 0 { - // If there are no parents, then we set the root tree to the empty tree. - tree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" - } else { - tree = parents[0].String() + "^{tree}" - } - - if writeCommitConfig.committerName == "" { - writeCommitConfig.committerName = committerName - } - - // Use 'commit-tree' instead of 'commit' because we are in a bare - // repository. What we do here is the same as "commit -m message - // --allow-empty". - commitArgs := []string{ - "-c", fmt.Sprintf("user.name=%s", writeCommitConfig.committerName), - "-c", fmt.Sprintf("user.email=%s", committerEmail), - "-C", repoPath, - "commit-tree", "-F", "-", tree, - } - - var env []string - if writeCommitConfig.alternateObjectDir != "" { - require.True(t, filepath.IsAbs(writeCommitConfig.alternateObjectDir), - "alternate object directory must be an absolute path") - require.NoError(t, os.MkdirAll(writeCommitConfig.alternateObjectDir, 0o755)) - - env = append(env, - fmt.Sprintf("GIT_OBJECT_DIRECTORY=%s", writeCommitConfig.alternateObjectDir), - fmt.Sprintf("GIT_ALTERNATE_OBJECT_DIRECTORIES=%s", filepath.Join(repoPath, "objects")), - ) - } - - for _, parent := range parents { - commitArgs = append(commitArgs, "-p", parent.String()) - } - - stdout := ExecOpts(t, cfg, ExecConfig{ - Stdin: stdin, - Env: env, - }, commitArgs...) - oid, err := git.NewObjectIDFromHex(text.ChompBytes(stdout)) - require.NoError(t, err) - - if writeCommitConfig.branch != "" { - ExecOpts(t, cfg, ExecConfig{ - Env: env, - }, "-C", repoPath, "update-ref", "refs/heads/"+writeCommitConfig.branch, oid.String()) - } - - return oid -} - -func authorEqualIgnoringDate(t testing.TB, expected *gitalypb.CommitAuthor, actual *gitalypb.CommitAuthor) { - t.Helper() - require.Equal(t, expected.GetName(), actual.GetName(), "author name does not match") - require.Equal(t, expected.GetEmail(), actual.GetEmail(), "author mail does not match") -} - -// CommitEqual tests if two `GitCommit`s are equal -func CommitEqual(t testing.TB, expected, actual *gitalypb.GitCommit) { - t.Helper() - - authorEqualIgnoringDate(t, expected.GetAuthor(), actual.GetAuthor()) - authorEqualIgnoringDate(t, expected.GetCommitter(), actual.GetCommitter()) - require.Equal(t, expected.GetBody(), actual.GetBody(), "body does not match") - require.Equal(t, expected.GetSubject(), actual.GetSubject(), "subject does not match") - require.Equal(t, expected.GetId(), actual.GetId(), "object ID does not match") - require.Equal(t, expected.GetParentIds(), actual.GetParentIds(), "parent IDs do not match") -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit_test.go deleted file mode 100644 index 515455252c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/commit_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package gittest_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func TestWriteCommit(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - ctx := testhelper.Context(t) - - catfileCache := catfile.NewCache(cfg) - defer catfileCache.Stop() - - objectReader, err := catfileCache.ObjectReader(ctx, repo) - require.NoError(t, err) - - defaultCommitter := &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - } - defaultParentID := "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" - - revisions := map[git.Revision]git.ObjectID{ - "refs/heads/master": "", - "refs/heads/master~": "", - } - for revision := range revisions { - oid, err := repo.ResolveRevision(ctx, revision) - require.NoError(t, err) - revisions[revision] = oid - } - - for _, tc := range []struct { - desc string - opts []gittest.WriteCommitOption - expectedCommit *gitalypb.GitCommit - expectedTreeEntries []gittest.TreeEntry - expectedRevUpdate git.Revision - }{ - { - desc: "no options", - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("message"), - Body: []byte("message"), - Id: "cab056fb7bfc5a4d024c2c5b9b445b80f212fdcd", - ParentIds: []string{ - defaultParentID, - }, - }, - }, - { - desc: "with commit message", - opts: []gittest.WriteCommitOption{ - gittest.WithMessage("my custom message\n\nfoobar\n"), - }, - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("my custom message"), - Body: []byte("my custom message\n\nfoobar\n"), - Id: "7b7e8876f7df27ab99e46678acbf9ae3d29264ba", - ParentIds: []string{ - defaultParentID, - }, - }, - }, - { - desc: "with no parents", - opts: []gittest.WriteCommitOption{ - gittest.WithParents(), - }, - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("message"), - Body: []byte("message"), - Id: "549090fbeacc6607bc70648d3ba554c355e670c5", - ParentIds: nil, - }, - }, - { - desc: "with multiple parents", - opts: []gittest.WriteCommitOption{ - gittest.WithParents(revisions["refs/heads/master"], revisions["refs/heads/master~"]), - }, - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("message"), - Body: []byte("message"), - Id: "650084693e5ca9c0b05a21fc5ac21ad1805c758b", - ParentIds: []string{ - revisions["refs/heads/master"].String(), - revisions["refs/heads/master~"].String(), - }, - }, - }, - { - desc: "with branch", - opts: []gittest.WriteCommitOption{ - gittest.WithBranch("foo"), - }, - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("message"), - Body: []byte("message"), - Id: "cab056fb7bfc5a4d024c2c5b9b445b80f212fdcd", - ParentIds: []string{ - defaultParentID, - }, - }, - expectedRevUpdate: "refs/heads/foo", - }, - { - desc: "with tree entry", - opts: []gittest.WriteCommitOption{ - gittest.WithTreeEntries(gittest.TreeEntry{ - Content: "foobar", - Mode: "100644", - Path: "file", - }), - }, - expectedCommit: &gitalypb.GitCommit{ - Author: defaultCommitter, - Committer: defaultCommitter, - Subject: []byte("message"), - Body: []byte("message"), - Id: "12da4907ed3331f4991ba6817317a3a90801288e", - ParentIds: []string{ - defaultParentID, - }, - }, - expectedTreeEntries: []gittest.TreeEntry{ - { - Content: "foobar", - Mode: "100644", - Path: "file", - }, - }, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - oid := gittest.WriteCommit(t, cfg, repoPath, tc.opts...) - - commit, err := catfile.GetCommit(ctx, objectReader, oid.Revision()) - require.NoError(t, err) - - gittest.CommitEqual(t, tc.expectedCommit, commit) - - if tc.expectedTreeEntries != nil { - gittest.RequireTree(t, cfg, repoPath, oid.String(), tc.expectedTreeEntries) - } - - if tc.expectedRevUpdate != "" { - updatedOID, err := repo.ResolveRevision(ctx, tc.expectedRevUpdate) - require.NoError(t, err) - require.Equal(t, oid, updatedOID) - } - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/delta_islands.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/delta_islands.go deleted file mode 100644 index 23f2e88847..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/delta_islands.go +++ /dev/null @@ -1,77 +0,0 @@ -package gittest - -import ( - "crypto/rand" - "io" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" -) - -// TestDeltaIslands is based on the tests in -// https://github.com/git/git/blob/master/t/t5320-delta-islands.sh . -func TestDeltaIslands(t *testing.T, cfg config.Cfg, repoPath string, repack func() error) { - t.Helper() - - // Create blobs that we expect Git to use delta compression on. - blob1, err := io.ReadAll(io.LimitReader(rand.Reader, 100000)) - require.NoError(t, err) - - blob2 := append(blob1, "\nblob 2"...) - - // Assume Git prefers the largest blob as the delta base. - badBlob := append(blob2, "\nbad blob"...) - - blob1ID := commitBlob(t, cfg, repoPath, "refs/heads/branch1", blob1) - blob2ID := commitBlob(t, cfg, repoPath, "refs/tags/tag2", blob2) - - // The bad blob will only be reachable via a non-standard ref. Because of - // that it should be excluded from delta chains in the main island. - badBlobID := commitBlob(t, cfg, repoPath, "refs/bad/ref3", badBlob) - - // So far we have create blobs and commits but they will be in loose - // object files; we want them to be delta compressed. Run repack to make - // that happen. - Exec(t, cfg, "-C", repoPath, "repack", "-ad") - - assert.Equal(t, badBlobID, deltaBase(t, cfg, repoPath, blob1ID), "expect blob 1 delta base to be bad blob after test setup") - assert.Equal(t, badBlobID, deltaBase(t, cfg, repoPath, blob2ID), "expect blob 2 delta base to be bad blob after test setup") - - require.NoError(t, repack(), "repack after delta island setup") - - assert.Equal(t, blob2ID, deltaBase(t, cfg, repoPath, blob1ID), "blob 1 delta base should be blob 2 after repack") - - // blob2 is the bigger of the two so it should be the delta base - assert.Equal(t, git.ZeroOID.String(), deltaBase(t, cfg, repoPath, blob2ID), "blob 2 should not be delta compressed after repack") -} - -func commitBlob(t *testing.T, cfg config.Cfg, repoPath, ref string, content []byte) string { - blobID := WriteBlob(t, cfg, repoPath, content) - - // No parent, that means this will be an initial commit. Not very - // realistic but it doesn't matter for delta compression. - commitID := WriteCommit(t, cfg, repoPath, - WithTreeEntries(TreeEntry{ - Mode: "100644", OID: blobID, Path: "file", - }), - WithParents(), - ) - - Exec(t, cfg, "-C", repoPath, "update-ref", ref, commitID.String()) - - return blobID.String() -} - -func deltaBase(t *testing.T, cfg config.Cfg, repoPath string, blobID string) string { - catfileOut := ExecOpts(t, cfg, ExecConfig{Stdin: strings.NewReader(blobID)}, - "-C", repoPath, "cat-file", "--batch-check=%(deltabase)", - ) - - return chompToString(catfileOut) -} - -func chompToString(s []byte) string { return strings.TrimSuffix(string(s), "\n") } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory_test.go deleted file mode 100644 index f3005f86b4..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package gittest - -import ( - "bytes" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestInterceptingCommandFactory(t *testing.T) { - cfg, repoProto, repoPath := setup(t) - ctx := testhelper.Context(t) - - factory := NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { - return fmt.Sprintf( - `#!/usr/bin/env bash - %q rev-parse --sq-quote 'Hello, world!' - `, execEnv.BinaryPath) - }) - expectedString := " 'Hello, world'\\!''\n" - - t.Run("New", func(t *testing.T) { - var stdout bytes.Buffer - cmd, err := factory.New(ctx, repoProto, git.SubCmd{ - Name: "rev-parse", - Args: []string{"something"}, - }, git.WithStdout(&stdout)) - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - require.Equal(t, expectedString, stdout.String()) - }) - - t.Run("NewWithDir", func(t *testing.T) { - var stdout bytes.Buffer - cmd, err := factory.NewWithDir(ctx, repoPath, git.SubCmd{ - Name: "rev-parse", - Args: []string{"something"}, - }, git.WithStdout(&stdout)) - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - require.Equal(t, expectedString, stdout.String()) - }) - - t.Run("NewWithoutRepo", func(t *testing.T) { - var stdout bytes.Buffer - cmd, err := factory.NewWithoutRepo(ctx, git.SubCmd{ - Name: "rev-parse", - Args: []string{"something"}, - Flags: []git.Option{ - git.ValueFlag{Name: "-C", Value: repoPath}, - }, - }, git.WithStdout(&stdout)) - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - require.Equal(t, expectedString, stdout.String()) - }) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/objects.go deleted file mode 100644 index 218a7af5bf..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/objects.go +++ /dev/null @@ -1,83 +0,0 @@ -package gittest - -import ( - "bytes" - "os/exec" - "path/filepath" - "strconv" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" -) - -// RequireObjectExists asserts that the given repository does contain an object with the specified -// object ID. -func RequireObjectExists(t testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID) { - requireObjectExists(t, cfg, repoPath, objectID, true) -} - -// RequireObjectNotExists asserts that the given repository does not contain an object with the -// specified object ID. -func RequireObjectNotExists(t testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID) { - requireObjectExists(t, cfg, repoPath, objectID, false) -} - -func requireObjectExists(t testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID, exists bool) { - cmd := NewCommand(t, cfg, "-C", repoPath, "cat-file", "-e", objectID.String()) - cmd.Env = []string{ - "GIT_ALLOW_PROTOCOL=", // To prevent partial clone reaching remote repo over SSH - } - - if exists { - require.NoError(t, cmd.Run(), "checking for object should succeed") - return - } - require.Error(t, cmd.Run(), "checking for object should fail") -} - -// GetGitPackfileDirSize gets the number of 1k blocks of a git object directory -func GetGitPackfileDirSize(t testing.TB, repoPath string) int64 { - return getGitDirSize(t, repoPath, "objects", "pack") -} - -func getGitDirSize(t testing.TB, repoPath string, subdirs ...string) int64 { - cmd := exec.Command("du", "-s", "-k", filepath.Join(append([]string{repoPath}, subdirs...)...)) - output, err := cmd.Output() - require.NoError(t, err) - if len(output) < 2 { - t.Error("invalid output of du -s -k") - } - - outputSplit := strings.SplitN(string(output), "\t", 2) - blocks, err := strconv.ParseInt(outputSplit[0], 10, 64) - require.NoError(t, err) - - return blocks -} - -// WriteBlobs writes n distinct blobs into the git repository's object -// database. Each object has the current time in nanoseconds as contents. -func WriteBlobs(t testing.TB, cfg config.Cfg, testRepoPath string, n int) []string { - var blobIDs []string - for i := 0; i < n; i++ { - contents := []byte(strconv.Itoa(time.Now().Nanosecond())) - blobIDs = append(blobIDs, WriteBlob(t, cfg, testRepoPath, contents).String()) - } - - return blobIDs -} - -// WriteBlob writes the given contents as a blob into the repository and returns its OID. -func WriteBlob(t testing.TB, cfg config.Cfg, testRepoPath string, contents []byte) git.ObjectID { - hex := text.ChompBytes(ExecOpts(t, cfg, ExecConfig{Stdin: bytes.NewReader(contents)}, - "-C", testRepoPath, "hash-object", "-w", "--stdin", - )) - oid, err := git.NewObjectIDFromHex(hex) - require.NoError(t, err) - return oid -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/pktline.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/pktline.go deleted file mode 100644 index d8c0ee1ba9..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/pktline.go +++ /dev/null @@ -1,25 +0,0 @@ -package gittest - -import ( - "io" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" -) - -// WritePktlineString writes the pktline-formatted data into the writer. -func WritePktlineString(t *testing.T, writer io.Writer, data string) { - _, err := pktline.WriteString(writer, data) - require.NoError(t, err) -} - -// WritePktlineFlush writes the pktline-formatted flush into the writer. -func WritePktlineFlush(t *testing.T, writer io.Writer) { - require.NoError(t, pktline.WriteFlush(writer)) -} - -// WritePktlineDelim writes the pktline-formatted delimiter into the writer. -func WritePktlineDelim(t *testing.T, writer io.Writer) { - require.NoError(t, pktline.WriteDelim(writer)) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/protocol.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/protocol.go deleted file mode 100644 index 301cf34e58..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/protocol.go +++ /dev/null @@ -1,35 +0,0 @@ -package gittest - -import ( - "context" - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -// NewProtocolDetectingCommandFactory creates a new intercepting Git command factory that allows the -// protocol to be tested. It returns this factory and a function to read the GIT_PROTOCOL -// environment variable created by the wrapper script. -func NewProtocolDetectingCommandFactory(ctx context.Context, t testing.TB, cfg config.Cfg) (git.CommandFactory, func() string) { - envPath := filepath.Join(testhelper.TempDir(t), "git-env") - - gitCmdFactory := NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { - return fmt.Sprintf( - `#!/usr/bin/env bash - env | grep ^GIT_PROTOCOL= >>%q - exec %q "$@" - `, envPath, execEnv.BinaryPath) - }) - - return gitCmdFactory, func() string { - data, err := os.ReadFile(envPath) - require.NoError(t, err) - return string(data) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/ref.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/ref.go deleted file mode 100644 index 19e9c2cbec..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/ref.go +++ /dev/null @@ -1,13 +0,0 @@ -package gittest - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" -) - -// WriteRef writes a reference into the repository pointing to the given object ID. -func WriteRef(t testing.TB, cfg config.Cfg, repoPath string, ref git.ReferenceName, oid git.ObjectID) { - Exec(t, cfg, "-C", repoPath, "update-ref", ref.String(), oid.String()) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repo.go deleted file mode 100644 index 1d606fa7fd..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repo.go +++ /dev/null @@ -1,378 +0,0 @@ -package gittest - -import ( - "bytes" - "context" - "crypto/sha256" - "os" - "path/filepath" - "runtime" - "testing" - - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -const ( - // GlRepository is the default repository name for newly created test - // repos. - GlRepository = "project-1" - // GlProjectPath is the default project path for newly created test - // repos. - GlProjectPath = "gitlab-org/gitlab-test" - - // SeedGitLabTest is the path of the gitlab-test.git repository in _build/testrepos - SeedGitLabTest = "gitlab-test.git" - - // SeedGitLabTestMirror is the path of the gitlab-test-mirror.git repository in _build/testrepos - SeedGitLabTestMirror = "gitlab-test-mirror.git" -) - -// InitRepoDir creates a temporary directory for a repo, without initializing it -func InitRepoDir(t testing.TB, storagePath, relativePath string) *gitalypb.Repository { - repoPath := filepath.Join(storagePath, relativePath, "..") - require.NoError(t, os.MkdirAll(repoPath, 0o755), "making repo parent dir") - return &gitalypb.Repository{ - StorageName: "default", - RelativePath: relativePath, - GlRepository: GlRepository, - GlProjectPath: GlProjectPath, - } -} - -// NewObjectPoolName returns a random pool repository name in format -// '@pools/[0-9a-z]{2}/[0-9a-z]{2}/[0-9a-z]{64}.git'. -func NewObjectPoolName(t testing.TB) string { - return filepath.Join("@pools", newDiskHash(t)+".git") -} - -// NewRepositoryName returns a random repository hash -// in format '@hashed/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{64}(.git)?'. -func NewRepositoryName(t testing.TB, bare bool) string { - suffix := "" - if bare { - suffix = ".git" - } - - return filepath.Join("@hashed", newDiskHash(t)+suffix) -} - -// newDiskHash generates a random directory path following the Rails app's -// approach in the hashed storage module, formatted as '[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{64}'. -// https://gitlab.com/gitlab-org/gitlab/-/blob/f5c7d8eb1dd4eee5106123e04dec26d277ff6a83/app/models/storage/hashed.rb#L38-43 -func newDiskHash(t testing.TB) string { - // rails app calculates a sha256 and uses its hex representation - // as the directory path - b, err := text.RandomHex(sha256.Size) - require.NoError(t, err) - return filepath.Join(b[0:2], b[2:4], b) -} - -// CreateRepositoryConfig allows for configuring how the repository is created. -type CreateRepositoryConfig struct { - // ClientConn is the connection used to create the repository. If unset, the config is used to - // dial the service. - ClientConn *grpc.ClientConn - // Storage determines the storage the repository is created in. If unset, the first storage - // from the config is used. - Storage config.Storage - // RelativePath sets the relative path of the repository in the storage. If unset, - // the relative path is set to a randomly generated hashed storage path - RelativePath string - // Seed determines which repository is used to seed the created repository. If unset, the repository - // is just created. The value should be one of the test repositories in _build/testrepos. - Seed string -} - -func dialService(ctx context.Context, t testing.TB, cfg config.Cfg) *grpc.ClientConn { - dialOptions := []grpc.DialOption{} - if cfg.Auth.Token != "" { - dialOptions = append(dialOptions, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token))) - } - - conn, err := client.DialContext(ctx, cfg.SocketPath, dialOptions) - require.NoError(t, err) - return conn -} - -// CreateRepository creates a new repository and returns it and its absolute path. -func CreateRepository(ctx context.Context, t testing.TB, cfg config.Cfg, configs ...CreateRepositoryConfig) (*gitalypb.Repository, string) { - t.Helper() - - require.Less(t, len(configs), 2, "you must either pass no or exactly one option") - - opts := CreateRepositoryConfig{} - if len(configs) == 1 { - opts = configs[0] - } - - conn := opts.ClientConn - if conn == nil { - conn = dialService(ctx, t, cfg) - t.Cleanup(func() { conn.Close() }) - } - - client := gitalypb.NewRepositoryServiceClient(conn) - - storage := cfg.Storages[0] - if (opts.Storage != config.Storage{}) { - storage = opts.Storage - } - - relativePath := newDiskHash(t) - if opts.RelativePath != "" { - relativePath = opts.RelativePath - } - - repository := &gitalypb.Repository{ - StorageName: storage.Name, - RelativePath: relativePath, - GlRepository: GlRepository, - GlProjectPath: GlProjectPath, - } - - if opts.Seed != "" { - _, err := client.CreateRepositoryFromURL(ctx, &gitalypb.CreateRepositoryFromURLRequest{ - Repository: repository, - Url: testRepositoryPath(t, opts.Seed), - Mirror: true, - }) - require.NoError(t, err) - } else { - _, err := client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{ - Repository: repository, - }) - require.NoError(t, err) - } - - t.Cleanup(func() { - // The ctx parameter would be canceled by now as the tests defer the cancellation. - _, err := client.RemoveRepository(context.TODO(), &gitalypb.RemoveRepositoryRequest{ - Repository: repository, - }) - - if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { - // The tests may delete the repository, so this is not a failure. - return - } - - require.NoError(t, err) - }) - - // Return a cloned repository so the above clean up function still targets the correct repository - // if the tests modify the returned repository. - clonedRepo := proto.Clone(repository).(*gitalypb.Repository) - - return clonedRepo, filepath.Join(storage.Path, getReplicaPath(ctx, t, conn, repository)) -} - -// GetReplicaPath retrieves the repository's replica path if the test has been -// run with Praefect in front of it. This is necessary if the test creates a repository -// through Praefect and peeks into the filesystem afterwards. Conn should be pointing to -// Praefect. -func GetReplicaPath(ctx context.Context, t testing.TB, cfg config.Cfg, repo repository.GitRepo) string { - conn := dialService(ctx, t, cfg) - defer conn.Close() - - return getReplicaPath(ctx, t, conn, repo) -} - -func getReplicaPath(ctx context.Context, t testing.TB, conn *grpc.ClientConn, repo repository.GitRepo) string { - metadata, err := gitalypb.NewPraefectInfoServiceClient(conn).GetRepositoryMetadata( - ctx, &gitalypb.GetRepositoryMetadataRequest{ - Query: &gitalypb.GetRepositoryMetadataRequest_Path_{ - Path: &gitalypb.GetRepositoryMetadataRequest_Path{ - VirtualStorage: repo.GetStorageName(), - RelativePath: repo.GetRelativePath(), - }, - }, - }) - if status, ok := status.FromError(err); ok && status.Code() == codes.Unimplemented && status.Message() == "unknown service gitaly.PraefectInfoService" { - // The repository is stored at relative path if the test is running without Praefect in front. - return repo.GetRelativePath() - } - require.NoError(t, err) - - return metadata.ReplicaPath -} - -// RewrittenRepository returns the repository as it would be received by a Gitaly after being rewritten by Praefect. -// This should be used when the repository is being accessed through the filesystem to ensure the access path is -// correct. If the test is not running with Praefect in front, it returns the an unaltered copy of repository. -func RewrittenRepository(ctx context.Context, t testing.TB, cfg config.Cfg, repository *gitalypb.Repository) *gitalypb.Repository { - // Don't modify the original repository. - rewritten := proto.Clone(repository).(*gitalypb.Repository) - rewritten.RelativePath = GetReplicaPath(ctx, t, cfg, repository) - return rewritten -} - -// InitRepoOpts contains options for InitRepo. -type InitRepoOpts struct { - // WithWorktree determines whether the resulting Git repository should have a worktree or - // not. - WithWorktree bool - // WithRelativePath determines the relative path of this repository. - WithRelativePath string -} - -// InitRepo creates a new empty repository in the given storage. You can either pass no or exactly -// one InitRepoOpts. -func InitRepo(t testing.TB, cfg config.Cfg, storage config.Storage, opts ...InitRepoOpts) (*gitalypb.Repository, string) { - require.Less(t, len(opts), 2, "you must either pass no or exactly one option") - - opt := InitRepoOpts{} - if len(opts) == 1 { - opt = opts[0] - } - - relativePath := opt.WithRelativePath - if relativePath == "" { - relativePath = NewRepositoryName(t, !opt.WithWorktree) - } - repoPath := filepath.Join(storage.Path, relativePath) - - args := []string{"init"} - if !opt.WithWorktree { - args = append(args, "--bare") - } - - Exec(t, cfg, append(args, repoPath)...) - - repo := InitRepoDir(t, storage.Path, relativePath) - repo.StorageName = storage.Name - if opt.WithWorktree { - repo.RelativePath = filepath.Join(repo.RelativePath, ".git") - } - - t.Cleanup(func() { require.NoError(t, os.RemoveAll(repoPath)) }) - - return repo, repoPath -} - -// CloneRepoOpts is an option for CloneRepo. -type CloneRepoOpts struct { - // RelativePath determines the relative path of newly created Git repository. If unset, the - // relative path is computed via NewRepositoryName. - RelativePath string - // WithWorktree determines whether the resulting Git repository should have a worktree or - // not. - WithWorktree bool - // SourceRepo determines the name of the source repository which shall be cloned. The source - // repository is assumed to be relative to "_build/testrepos". If unset, defaults to - // "gitlab-test.git". - SourceRepo string -} - -// CloneRepo clones a new copy of test repository under a subdirectory in the storage root. You can -// either pass no or exactly one CloneRepoOpts. -func CloneRepo(t testing.TB, cfg config.Cfg, storage config.Storage, opts ...CloneRepoOpts) (*gitalypb.Repository, string) { - require.Less(t, len(opts), 2, "you must either pass no or exactly one option") - - opt := CloneRepoOpts{} - if len(opts) == 1 { - opt = opts[0] - } - - relativePath := opt.RelativePath - if relativePath == "" { - relativePath = NewRepositoryName(t, !opt.WithWorktree) - } - - sourceRepo := opt.SourceRepo - if sourceRepo == "" { - sourceRepo = "gitlab-test.git" - } - - repo := InitRepoDir(t, storage.Path, relativePath) - repo.StorageName = storage.Name - - args := []string{"clone", "--no-hardlinks", "--dissociate"} - if !opt.WithWorktree { - args = append(args, "--bare") - } else { - // For non-bare repos the relative path is the .git folder inside the path - repo.RelativePath = filepath.Join(relativePath, ".git") - } - - absolutePath := filepath.Join(storage.Path, relativePath) - Exec(t, cfg, append(args, testRepositoryPath(t, sourceRepo), absolutePath)...) - Exec(t, cfg, "-C", absolutePath, "remote", "remove", "origin") - - t.Cleanup(func() { require.NoError(t, os.RemoveAll(absolutePath)) }) - - return repo, absolutePath -} - -// BundleTestRepo creates a bundle of a local test repo. E.g. -// `gitlab-test.git`. `patterns` define the bundle contents as per -// `git-rev-list-args`. If there are no patterns then `--all` is assumed. -func BundleTestRepo(t testing.TB, cfg config.Cfg, sourceRepo, bundlePath string, patterns ...string) { - if len(patterns) == 0 { - patterns = []string{"--all"} - } - repoPath := testRepositoryPath(t, sourceRepo) - Exec(t, cfg, append([]string{"-C", repoPath, "bundle", "create", bundlePath}, patterns...)...) -} - -// ChecksumTestRepo calculates the checksum of a local test repo. E.g. -// `gitlab-test.git`. -func ChecksumTestRepo(t testing.TB, cfg config.Cfg, sourceRepo string) *git.Checksum { - var checksum git.Checksum - repoPath := testRepositoryPath(t, sourceRepo) - lines := bytes.Split(Exec(t, cfg, "-C", repoPath, "show-ref", "--head"), []byte("\n")) - for _, line := range lines { - checksum.AddBytes(line) - } - return &checksum -} - -// testRepositoryPath returns the absolute path of local 'gitlab-org/gitlab-test.git' clone. -// It is cloned under the path by the test preparing step of make. -func testRepositoryPath(t testing.TB, repo string) string { - _, currentFile, _, ok := runtime.Caller(0) - if !ok { - require.Fail(t, "could not get caller info") - } - - path := filepath.Join(filepath.Dir(currentFile), "..", "..", "..", "_build", "testrepos", repo) - if !isValidRepoPath(path) { - makePath := filepath.Join(filepath.Dir(currentFile), "..", "..", "..") - makeTarget := "prepare-test-repos" - log.Printf("local clone of test repository %q not found in %q, running `make %v`", repo, path, makeTarget) - testhelper.MustRunCommand(t, nil, "make", "-C", makePath, makeTarget) - } - - return path -} - -// isValidRepoPath checks whether a valid git repository exists at the given path. -func isValidRepoPath(absolutePath string) bool { - if _, err := os.Stat(filepath.Join(absolutePath, "objects")); err != nil { - return false - } - - return true -} - -// AddWorktreeArgs returns git command arguments for adding a worktree at the -// specified repo -func AddWorktreeArgs(repoPath, worktreeName string) []string { - return []string{"-C", repoPath, "worktree", "add", "--detach", worktreeName} -} - -// AddWorktree creates a worktree in the repository path for tests -func AddWorktree(t testing.TB, cfg config.Cfg, repoPath string, worktreeName string) { - Exec(t, cfg, AddWorktreeArgs(repoPath, worktreeName)...) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testhelper_test.go deleted file mode 100644 index 4565301d2c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testhelper_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package gittest - -import ( - "os" - "path/filepath" - "runtime" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -// setup sets up a test configuration and repository. Ideally we'd use our central test helpers to -// do this, but because of an import cycle we can't. -func setup(t testing.TB) (config.Cfg, *gitalypb.Repository, string) { - t.Helper() - - rootDir := testhelper.TempDir(t) - - var cfg config.Cfg - - cfg.SocketPath = "it is a stub to bypass Validate method" - - cfg.Storages = []config.Storage{ - { - Name: "default", - Path: filepath.Join(rootDir, "storage.d"), - }, - } - require.NoError(t, os.Mkdir(cfg.Storages[0].Path, 0o755)) - - _, currentFile, _, ok := runtime.Caller(0) - require.True(t, ok, "could not get caller info") - cfg.Ruby.Dir = filepath.Join(filepath.Dir(currentFile), "../../../ruby") - - cfg.GitlabShell.Dir = filepath.Join(rootDir, "shell.d") - require.NoError(t, os.Mkdir(cfg.GitlabShell.Dir, 0o755)) - - cfg.BinDir = filepath.Join(rootDir, "bin.d") - require.NoError(t, os.Mkdir(cfg.BinDir, 0o755)) - - cfg.RuntimeDir = filepath.Join(rootDir, "run.d") - require.NoError(t, os.Mkdir(cfg.RuntimeDir, 0o700)) - - require.NoError(t, cfg.Validate()) - - repo, repoPath := CloneRepo(t, cfg, cfg.Storages[0]) - - return cfg, repo, repoPath -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/helper_test.go deleted file mode 100644 index 5734c024c6..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/helper_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package git - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func TestValidateRevision(t *testing.T) { - testCases := []struct { - rev string - ok bool - }{ - {rev: "foo/bar", ok: true}, - {rev: "-foo/bar", ok: false}, - {rev: "foo bar", ok: false}, - {rev: "foo\x00bar", ok: false}, - {rev: "foo/bar:baz", ok: false}, - } - - for _, tc := range testCases { - t.Run(tc.rev, func(t *testing.T) { - err := ValidateRevision([]byte(tc.rev)) - if tc.ok { - require.NoError(t, err) - } else { - require.Error(t, err) - } - }) - } -} - -func newCommandFactory(tb testing.TB, cfg config.Cfg, opts ...ExecCommandFactoryOption) *ExecCommandFactory { - gitCmdFactory, cleanup, err := NewExecCommandFactory(cfg, opts...) - require.NoError(tb, err) - tb.Cleanup(cleanup) - return gitCmdFactory -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options_test.go deleted file mode 100644 index 17e7b02f1e..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package git_test - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" -) - -func TestWithRefHook(t *testing.T) { - cfg, repo, _ := testcfg.BuildWithRepo(t) - ctx := testhelper.Context(t) - - opt := git.WithRefTxHook(repo) - subCmd := git.SubCmd{Name: "update-ref", Args: []string{"refs/heads/master", git.ZeroOID.String()}} - - for _, tt := range []struct { - name string - fn func() (*command.Command, error) - }{ - { - name: "NewCommand", - fn: func() (*command.Command, error) { - return gittest.NewCommandFactory(t, cfg, git.WithSkipHooks()).New(ctx, repo, subCmd, opt) - }, - }, - } { - t.Run(tt.name, func(t *testing.T) { - cmd, err := tt.fn() - require.NoError(t, err) - require.NoError(t, cmd.Wait()) - - var actualEnvVars []string - for _, env := range cmd.Env() { - kv := strings.SplitN(env, "=", 2) - require.Len(t, kv, 2) - key, val := kv[0], kv[1] - - if strings.HasPrefix(key, "GL_") || strings.HasPrefix(key, "GITALY_") { - require.NotEmptyf(t, strings.TrimSpace(val), - "env var %s value should not be empty string", key) - actualEnvVars = append(actualEnvVars, key) - } - } - - require.EqualValues(t, []string{ - "GITALY_HOOKS_PAYLOAD", - "GITALY_LOG_DIR", - }, actualEnvVars) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/commit_graph.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/commit_graph.go deleted file mode 100644 index dcdd2cb2e0..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/commit_graph.go +++ /dev/null @@ -1,64 +0,0 @@ -package housekeeping - -import ( - "bytes" - "context" - "errors" - "fmt" - "os" - "path/filepath" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" -) - -// WriteCommitGraph updates the commit-graph in the given repository. The commit-graph is updated -// incrementally, except in the case where it doesn't exist yet or in case it is detected that the -// commit-graph is missing bloom filters. -func WriteCommitGraph(ctx context.Context, repo *localrepo.Repo) error { - repoPath, err := repo.Path() - if err != nil { - return err - } - - missingBloomFilters := true - if _, err := os.Stat(filepath.Join(repoPath, stats.CommitGraphRelPath)); err != nil { - if !errors.Is(err, os.ErrNotExist) { - return helper.ErrInternal(fmt.Errorf("remove commit graph file: %w", err)) - } - - // objects/info/commit-graph file doesn't exists - // check if commit-graph chain exists and includes Bloom filters - if missingBloomFilters, err = stats.IsMissingBloomFilters(repoPath); err != nil { - return helper.ErrInternal(fmt.Errorf("should remove commit graph chain: %w", err)) - } - } - - flags := []git.Option{ - git.Flag{Name: "--reachable"}, - git.Flag{Name: "--changed-paths"}, // enables Bloom filters - git.ValueFlag{Name: "--size-multiple", Value: "4"}, - } - - if missingBloomFilters { - // if commit graph doesn't use Bloom filters we instruct operation to replace - // existent commit graph with the new one - // https://git-scm.com/docs/git-commit-graph#Documentation/git-commit-graph.txt-emwriteem - flags = append(flags, git.Flag{Name: "--split=replace"}) - } else { - flags = append(flags, git.Flag{Name: "--split"}) - } - - var stderr bytes.Buffer - if err := repo.ExecAndWait(ctx, git.SubSubCmd{ - Name: "commit-graph", - Action: "write", - Flags: flags, - }, git.WithStderr(&stderr)); err != nil { - return helper.ErrInternalf("writing commit-graph: %s: %v", err, stderr.String()) - } - - return nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool.go deleted file mode 100644 index 1e4a935c89..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool.go +++ /dev/null @@ -1,25 +0,0 @@ -package housekeeping - -import ( - "regexp" - "strings" -) - -// railsPoolDirRegexp is used to validate object pool directory structure and name as generated by Rails. -var railsPoolDirRegexp = regexp.MustCompile(`^@pools/([0-9a-f]{2})/([0-9a-f]{2})/([0-9a-f]{64})\.git$`) - -// IsRailsPoolPath returns whether the relative path indicates this is a pool path generated by Rails. -func IsRailsPoolPath(relativePath string) bool { - matches := railsPoolDirRegexp.FindStringSubmatch(relativePath) - if matches == nil || !strings.HasPrefix(matches[3], matches[1]+matches[2]) { - return false - } - - return true -} - -// IsPoolPath returns whether the relative path indicates the repository is an object -// pool. -func IsPoolPath(relativePath string) bool { - return IsRailsPoolPath(relativePath) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool_test.go deleted file mode 100644 index 6fdded51f2..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/object_pool_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package housekeeping - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" -) - -func TestIsPoolPath(t *testing.T) { - for _, tc := range []struct { - desc string - relativePath string - isPoolPath bool - }{ - { - desc: "rails pool directory", - relativePath: gittest.NewObjectPoolName(t), - isPoolPath: true, - }, - { - desc: "empty string", - }, - { - desc: "rails path first to subdirs dont match full hash", - relativePath: "@pools/aa/bb/ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.git", - }, - { - desc: "normal repos dont match", - relativePath: "@hashed/" + gittest.NewRepositoryName(t, true), - }, - } { - t.Run(tc.desc, func(t *testing.T) { - require.Equal(t, tc.isPoolPath, IsPoolPath(tc.relativePath)) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/testhelper_test.go deleted file mode 100644 index f0afe0397b..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/testhelper_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package housekeeping - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id.go deleted file mode 100644 index d4cb725ddc..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id.go +++ /dev/null @@ -1,73 +0,0 @@ -package git - -import ( - "encoding/hex" - "errors" - "fmt" - "regexp" -) - -const ( - // EmptyTreeOID is the Git tree object hash that corresponds to an empty tree (directory) - EmptyTreeOID = ObjectID("4b825dc642cb6eb9a060e54bf8d69288fbee4904") - - // ZeroOID is the special value that Git uses to signal a ref or object does not exist - ZeroOID = ObjectID("0000000000000000000000000000000000000000") -) - -var ( - // ErrInvalidObjectID is returned in case an object ID's string - // representation is not a valid one. - ErrInvalidObjectID = errors.New("invalid object ID") - - objectIDRegex = regexp.MustCompile(`\A[0-9a-f]{40}\z`) -) - -// ObjectID represents an object ID. -type ObjectID string - -// NewObjectIDFromHex constructs a new ObjectID from the given hex -// representation of the object ID. Returns ErrInvalidObjectID if the given -// OID is not valid. -func NewObjectIDFromHex(hex string) (ObjectID, error) { - if err := ValidateObjectID(hex); err != nil { - return "", err - } - return ObjectID(hex), nil -} - -// String returns the hex representation of the ObjectID. -func (oid ObjectID) String() string { - return string(oid) -} - -// Bytes returns the byte representation of the ObjectID. -func (oid ObjectID) Bytes() ([]byte, error) { - decoded, err := hex.DecodeString(string(oid)) - if err != nil { - return nil, err - } - return decoded, nil -} - -// Revision returns a revision of the ObjectID. This directly returns the hex -// representation as every object ID is a valid revision. -func (oid ObjectID) Revision() Revision { - return Revision(oid.String()) -} - -// ValidateObjectID checks if id is a syntactically correct object ID. Abbreviated -// object IDs are not deemed to be valid. Returns an ErrInvalidObjectID if the -// id is not valid. -func ValidateObjectID(id string) error { - if objectIDRegex.MatchString(id) { - return nil - } - - return fmt.Errorf("%w: %q", ErrInvalidObjectID, id) -} - -// IsZeroOID is a shortcut for `something == git.ZeroOID.String()` -func (oid ObjectID) IsZeroOID() bool { - return string(oid) == string(ZeroOID) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id_test.go deleted file mode 100644 index 734726cd70..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/id_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package git - -import ( - "bytes" - "encoding/hex" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestValidateObjectID(t *testing.T) { - for _, tc := range []struct { - desc string - oid string - valid bool - }{ - { - desc: "valid object ID", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa3", - valid: true, - }, - { - desc: "object ID with non-hex characters fails", - oid: "x56e7793f9654d51dfb27312a1464062bceb9fa3", - valid: false, - }, - { - desc: "object ID with upper-case letters fails", - oid: "356E7793F9654D51DFB27312A1464062BCEB9FA3", - valid: false, - }, - { - desc: "too short object ID fails", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa", - valid: false, - }, - { - desc: "too long object ID fails", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa33", - valid: false, - }, - { - desc: "empty string fails", - oid: "", - valid: false, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - err := ValidateObjectID(tc.oid) - if tc.valid { - require.NoError(t, err) - } else { - require.Error(t, err) - require.EqualError(t, err, fmt.Sprintf("invalid object ID: %q", tc.oid)) - } - }) - } -} - -func TestNewObjectIDFromHex(t *testing.T) { - for _, tc := range []struct { - desc string - oid string - valid bool - }{ - { - desc: "valid object ID", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa3", - valid: true, - }, - { - desc: "object ID with non-hex characters fails", - oid: "x56e7793f9654d51dfb27312a1464062bceb9fa3", - valid: false, - }, - { - desc: "object ID with upper-case letters fails", - oid: "356E7793F9654D51DFB27312A1464062BCEB9FA3", - valid: false, - }, - { - desc: "too short object ID fails", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa", - valid: false, - }, - { - desc: "too long object ID fails", - oid: "356e7793f9654d51dfb27312a1464062bceb9fa33", - valid: false, - }, - { - desc: "empty string fails", - oid: "", - valid: false, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - oid, err := NewObjectIDFromHex(tc.oid) - if tc.valid { - require.NoError(t, err) - require.Equal(t, tc.oid, oid.String()) - } else { - require.Error(t, err) - } - }) - } -} - -func TestObjectID_Bytes(t *testing.T) { - for _, tc := range []struct { - desc string - oid ObjectID - expectedBytes []byte - expectedErr error - }{ - { - desc: "zero OID", - oid: ZeroOID, - expectedBytes: bytes.Repeat([]byte{0}, 20), - }, - { - desc: "valid object ID", - oid: ObjectID(strings.Repeat("8", 40)), - expectedBytes: bytes.Repeat([]byte{0x88}, 20), - }, - { - desc: "invalid object ID", - oid: ObjectID(strings.Repeat("8", 39) + "x"), - expectedErr: hex.InvalidByteError('x'), - }, - } { - t.Run(tc.desc, func(t *testing.T) { - actualBytes, err := tc.oid.Bytes() - require.Equal(t, tc.expectedErr, err) - require.Equal(t, tc.expectedBytes, actualBytes) - }) - } -} - -func TestIsZeroOID(t *testing.T) { - for _, tc := range []struct { - desc string - oid ObjectID - isZero bool - }{ - { - desc: "zero object ID", - oid: ZeroOID, - isZero: true, - }, - { - desc: "zero object ID", - oid: EmptyTreeOID, - isZero: false, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - require.Equal(t, tc.isZero, tc.oid.IsZeroOID()) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo.go deleted file mode 100644 index 7d7f3e4094..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo.go +++ /dev/null @@ -1,121 +0,0 @@ -package localrepo - -import ( - "bytes" - "context" - "fmt" - "strconv" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -// Repo represents a local Git repository. -type Repo struct { - repository.GitRepo - locator storage.Locator - gitCmdFactory git.CommandFactory - catfileCache catfile.Cache -} - -// New creates a new Repo from its protobuf representation. -func New(locator storage.Locator, gitCmdFactory git.CommandFactory, catfileCache catfile.Cache, repo repository.GitRepo) *Repo { - return &Repo{ - GitRepo: repo, - locator: locator, - gitCmdFactory: gitCmdFactory, - catfileCache: catfileCache, - } -} - -// NewTestRepo constructs a Repo. It is intended as a helper function for tests which assembles -// dependencies ad-hoc from the given config. -func NewTestRepo(t testing.TB, cfg config.Cfg, repo repository.GitRepo, factoryOpts ...git.ExecCommandFactoryOption) *Repo { - t.Helper() - - if cfg.SocketPath != testcfg.UnconfiguredSocketPath { - repo = gittest.RewrittenRepository(testhelper.Context(t), t, cfg, &gitalypb.Repository{ - StorageName: repo.GetStorageName(), - RelativePath: repo.GetRelativePath(), - GitObjectDirectory: repo.GetGitObjectDirectory(), - GitAlternateObjectDirectories: repo.GetGitAlternateObjectDirectories(), - }) - } - - gitCmdFactory, cleanup, err := git.NewExecCommandFactory(cfg, factoryOpts...) - t.Cleanup(cleanup) - require.NoError(t, err) - - catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) - - locator := config.NewLocator(cfg) - - return New(locator, gitCmdFactory, catfileCache, repo) -} - -// Exec creates a git command with the given args and Repo, executed in the -// Repo. It validates the arguments in the command before executing. -func (repo *Repo) Exec(ctx context.Context, cmd git.Cmd, opts ...git.CmdOpt) (*command.Command, error) { - return repo.gitCmdFactory.New(ctx, repo, cmd, opts...) -} - -// ExecAndWait is similar to Exec, but waits for the command to exit before -// returning. -func (repo *Repo) ExecAndWait(ctx context.Context, cmd git.Cmd, opts ...git.CmdOpt) error { - command, err := repo.Exec(ctx, cmd, opts...) - if err != nil { - return err - } - - return command.Wait() -} - -// GitVersion returns the Git version in use. -func (repo *Repo) GitVersion(ctx context.Context) (git.Version, error) { - return repo.gitCmdFactory.GitVersion(ctx) -} - -func errorWithStderr(err error, stderr []byte) error { - if len(stderr) == 0 { - return err - } - return fmt.Errorf("%w, stderr: %q", err, stderr) -} - -// Size calculates the size of all reachable objects in bytes -func (repo *Repo) Size(ctx context.Context) (int64, error) { - var stdout bytes.Buffer - if err := repo.ExecAndWait(ctx, - git.SubCmd{ - Name: "rev-list", - Flags: []git.Option{ - git.Flag{Name: "--all"}, - git.Flag{Name: "--objects"}, - git.Flag{Name: "--use-bitmap-index"}, - git.Flag{Name: "--disk-usage"}, - }, - }, - git.WithStdout(&stdout), - ); err != nil { - return -1, err - } - - size, err := strconv.ParseInt(strings.TrimSuffix(stdout.String(), "\n"), 10, 64) - if err != nil { - return -1, err - } - - return size, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo_test.go deleted file mode 100644 index c305519c85..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/repo_test.go +++ /dev/null @@ -1,173 +0,0 @@ -package localrepo - -import ( - "bytes" - "context" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func TestRepo(t *testing.T) { - cfg := testcfg.Build(t) - - gittest.TestRepository(t, cfg, func(ctx context.Context, t testing.TB, seeded bool) (git.Repository, string) { - t.Helper() - - var ( - pbRepo *gitalypb.Repository - repoPath string - ) - - if seeded { - pbRepo, repoPath = gittest.CloneRepo(t, cfg, cfg.Storages[0]) - } else { - pbRepo, repoPath = gittest.InitRepo(t, cfg, cfg.Storages[0]) - } - - gitCmdFactory := gittest.NewCommandFactory(t, cfg) - catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) - return New(config.NewLocator(cfg), gitCmdFactory, catfileCache, pbRepo), repoPath - }) -} - -func TestSize(t *testing.T) { - cfg := testcfg.Build(t) - gitCmdFactory := gittest.NewCommandFactory(t, cfg) - catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) - - testCases := []struct { - desc string - setup func(repoPath string, t *testing.T) - expectedSize int64 - }{ - { - desc: "empty repository", - expectedSize: 0, - }, - { - desc: "one committed file", - setup: func(repoPath string, t *testing.T) { - require.NoError(t, os.WriteFile( - filepath.Join(repoPath, "file"), - bytes.Repeat([]byte("a"), 1000), - 0o644, - )) - - cmd := gittest.NewCommand(t, cfg, "-C", repoPath, "add", "file") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-m", "initial") - require.NoError(t, cmd.Run()) - }, - expectedSize: 202, - }, - { - desc: "one large loose blob", - setup: func(repoPath string, t *testing.T) { - require.NoError(t, os.WriteFile( - filepath.Join(repoPath, "file"), - bytes.Repeat([]byte("a"), 1000), - 0o644, - )) - - cmd := gittest.NewCommand(t, cfg, "-C", repoPath, "checkout", "-b", "branch-a") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "add", "file") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-m", "initial") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "update-ref", "-d", "refs/heads/branch-a") - require.NoError(t, cmd.Run()) - }, - expectedSize: 0, - }, - { - desc: "modification to blob without repack", - setup: func(repoPath string, t *testing.T) { - require.NoError(t, os.WriteFile( - filepath.Join(repoPath, "file"), - bytes.Repeat([]byte("a"), 1000), - 0o644, - )) - - cmd := gittest.NewCommand(t, cfg, "-C", repoPath, "add", "file") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-m", "initial") - require.NoError(t, cmd.Run()) - - f, err := os.OpenFile( - filepath.Join(repoPath, "file"), - os.O_APPEND|os.O_WRONLY, - 0o644) - require.NoError(t, err) - defer f.Close() - _, err = f.WriteString("a") - assert.NoError(t, err) - - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-am", "modification") - require.NoError(t, cmd.Run()) - }, - expectedSize: 437, - }, - { - desc: "modification to blob after repack", - setup: func(repoPath string, t *testing.T) { - require.NoError(t, os.WriteFile( - filepath.Join(repoPath, "file"), - bytes.Repeat([]byte("a"), 1000), - 0o644, - )) - - cmd := gittest.NewCommand(t, cfg, "-C", repoPath, "add", "file") - require.NoError(t, cmd.Run()) - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-m", "initial") - require.NoError(t, cmd.Run()) - - f, err := os.OpenFile( - filepath.Join(repoPath, "file"), - os.O_APPEND|os.O_WRONLY, - 0o644) - require.NoError(t, err) - defer f.Close() - _, err = f.WriteString("a") - assert.NoError(t, err) - - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit", "-am", "modification") - require.NoError(t, cmd.Run()) - - cmd = gittest.NewCommand(t, cfg, "-C", repoPath, "repack", "-a", "-d") - require.NoError(t, cmd.Run()) - }, - expectedSize: 391, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - pbRepo, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0], gittest.InitRepoOpts{ - WithWorktree: true, - }) - repo := New(config.NewLocator(cfg), gitCmdFactory, catfileCache, pbRepo) - if tc.setup != nil { - tc.setup(repoPath, t) - } - - ctx := testhelper.Context(t) - size, err := repo.Size(ctx) - require.NoError(t, err) - assert.Equal(t, tc.expectedSize, size) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser_test.go deleted file mode 100644 index f1a4dfab8c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package lstree - -import ( - "io" - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParser(t *testing.T) { - testCases := []struct { - desc string - filename string - entries Entries - }{ - { - desc: "regular entries", - filename: "testdata/z-lstree.txt", - entries: Entries{ - { - Mode: []byte("100644"), - Type: Blob, - ObjectID: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - Path: ".gitignore", - }, - { - Mode: []byte("100644"), - Type: Blob, - ObjectID: "0792c58905eff3432b721f8c4a64363d8e28d9ae", - Path: ".gitmodules", - }, - { - Mode: []byte("040000"), - Type: Tree, - ObjectID: "3c122d2b7830eca25235131070602575cf8b41a1", - Path: "encoding", - }, - { - Mode: []byte("160000"), - Type: Submodule, - ObjectID: "79bceae69cb5750d6567b223597999bfa91cb3b9", - Path: "gitlab-shell", - }, - }, - }, - { - desc: "irregular path", - filename: "testdata/z-lstree-irregular.txt", - entries: Entries{ - { - Mode: []byte("100644"), - Type: Blob, - ObjectID: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - Path: ".gitignore", - }, - { - Mode: []byte("100644"), - Type: Blob, - ObjectID: "0792c58905eff3432b721f8c4a64363d8e28d9ae", - Path: ".gitmodules", - }, - { - Mode: []byte("040000"), - Type: Tree, - ObjectID: "3c122d2b7830eca25235131070602575cf8b41a1", - Path: "some encoding", - }, - { - Mode: []byte("160000"), - Type: Submodule, - ObjectID: "79bceae69cb5750d6567b223597999bfa91cb3b9", - Path: "gitlab-shell", - }, - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - file, err := os.Open(testCase.filename) - - require.NoError(t, err) - defer file.Close() - - parsedEntries := Entries{} - - parser := NewParser(file) - for { - entry, err := parser.NextEntry() - if err == io.EOF { - break - } - - require.NoError(t, err) - parsedEntries = append(parsedEntries, *entry) - } - - expectedEntries := testCase.entries - require.Len(t, expectedEntries, len(parsedEntries)) - - for index, parsedEntry := range parsedEntries { - expectedEntry := expectedEntries[index] - - require.Equal(t, expectedEntry, parsedEntry) - } - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree-irregular.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree-irregular.txt deleted file mode 100644 index ed55df3a48..0000000000 Binary files a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree-irregular.txt and /dev/null differ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree.txt deleted file mode 100644 index 653a2f8b1b..0000000000 Binary files a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testdata/z-lstree.txt and /dev/null differ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone_test.go deleted file mode 100644 index 7b6b22d7af..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package objectpool - -import ( - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestClone(t *testing.T) { - ctx := testhelper.Context(t) - - cfg, pool, repoProto := setupObjectPool(t, ctx) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - require.NoError(t, pool.clone(ctx, repo)) - defer func() { - require.NoError(t, pool.Remove(ctx)) - }() - - require.DirExists(t, pool.FullPath()) - require.DirExists(t, filepath.Join(pool.FullPath(), "objects")) -} - -func TestCloneExistingPool(t *testing.T) { - ctx := testhelper.Context(t) - - cfg, pool, repoProto := setupObjectPool(t, ctx) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - require.NoError(t, pool.clone(ctx, repo)) - defer func() { - require.NoError(t, pool.Remove(ctx)) - }() - - // re-clone on the directory - require.Error(t, pool.clone(ctx, repo)) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch.go deleted file mode 100644 index f094cee733..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch.go +++ /dev/null @@ -1,255 +0,0 @@ -package objectpool - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io" - "os/exec" - "path/filepath" - "strconv" - "strings" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" -) - -const sourceRefNamespace = "refs/remotes/origin" - -// FetchFromOrigin initializes the pool and fetches the objects from its origin repository -func (o *ObjectPool) FetchFromOrigin(ctx context.Context, origin *localrepo.Repo) error { - if err := o.Init(ctx); err != nil { - return err - } - - originPath, err := origin.Path() - if err != nil { - return err - } - - if err := o.housekeepingManager.CleanStaleData(ctx, o.Repo); err != nil { - return err - } - - if err := o.logStats(ctx, "before fetch"); err != nil { - return err - } - - refSpec := fmt.Sprintf("+refs/*:%s/*", sourceRefNamespace) - var stderr bytes.Buffer - if err := o.Repo.ExecAndWait(ctx, - git.SubCmd{ - Name: "fetch", - Flags: []git.Option{ - git.Flag{Name: "--quiet"}, - git.Flag{Name: "--atomic"}, - // We already fetch tags via our refspec, so we don't - // want to fetch them a second time via Git's default - // tag refspec. - git.Flag{Name: "--no-tags"}, - // We don't need FETCH_HEAD, and it can potentially be hundreds of - // megabytes when doing a mirror-sync of repos with huge numbers of - // references. - git.Flag{Name: "--no-write-fetch-head"}, - }, - Args: []string{originPath, refSpec}, - }, - git.WithRefTxHook(o.Repo), - git.WithStderr(&stderr), - ); err != nil { - return helper.ErrInternalf("fetch into object pool: %w, stderr: %q", err, - stderr.String()) - } - - if err := o.rescueDanglingObjects(ctx); err != nil { - return err - } - - if err := o.logStats(ctx, "after fetch"); err != nil { - return err - } - - if err := o.Repo.ExecAndWait(ctx, git.SubCmd{ - Name: "pack-refs", - Flags: []git.Option{git.Flag{Name: "--all"}}, - }); err != nil { - return err - } - - return o.repackPool(ctx, o) -} - -const danglingObjectNamespace = "refs/dangling/" - -// rescueDanglingObjects creates refs for all dangling objects if finds -// with `git fsck`, which converts those objects from "dangling" to -// "not-dangling". This guards against any object ever being deleted from -// a pool repository. This is a defense in depth against accidental use -// of `git prune`, which could remove Git objects that a pool member -// relies on. There is currently no way for us to reliably determine if -// an object is still used anywhere, so the only safe thing to do is to -// assume that every object _is_ used. -func (o *ObjectPool) rescueDanglingObjects(ctx context.Context) error { - fsck, err := o.Repo.Exec(ctx, git.SubCmd{ - Name: "fsck", - Flags: []git.Option{git.Flag{Name: "--connectivity-only"}, git.Flag{Name: "--dangling"}}, - }) - if err != nil { - return err - } - - updater, err := updateref.New(ctx, o.Repo, updateref.WithDisabledTransactions()) - if err != nil { - return err - } - - scanner := bufio.NewScanner(fsck) - for scanner.Scan() { - split := strings.SplitN(scanner.Text(), " ", 3) - if len(split) != 3 { - continue - } - - if split[0] != "dangling" { - continue - } - - ref := git.ReferenceName(danglingObjectNamespace + split[2]) - if err := updater.Create(ref, split[2]); err != nil { - return err - } - } - - if err := scanner.Err(); err != nil { - return err - } - - if err := fsck.Wait(); err != nil { - return fmt.Errorf("git fsck: %v", err) - } - - return updater.Commit() -} - -func (o *ObjectPool) repackPool(ctx context.Context, pool repository.GitRepo) error { - config := []git.ConfigPair{ - {Key: "pack.island", Value: sourceRefNamespace + "/he(a)ds"}, - {Key: "pack.island", Value: sourceRefNamespace + "/t(a)gs"}, - {Key: "pack.islandCore", Value: "a"}, - {Key: "pack.writeBitmapHashCache", Value: "true"}, - } - - if err := o.Repo.ExecAndWait(ctx, git.SubCmd{ - Name: "repack", - Flags: []git.Option{ - git.Flag{Name: "-aidb"}, - // This can be removed as soon as we have upstreamed a - // `repack.updateServerInfo` config option. See gitlab-org/git#105 for more - // details. - git.Flag{Name: "-n"}, - }, - }, git.WithConfig(config...)); err != nil { - return err - } - - return nil -} - -func (o *ObjectPool) logStats(ctx context.Context, when string) error { - fields := logrus.Fields{ - "when": when, - } - - for key, dir := range map[string]string{ - "poolObjectsSize": "objects", - "poolRefsSize": "refs", - } { - var err error - fields[key], err = sizeDir(ctx, filepath.Join(o.FullPath(), dir)) - if err != nil { - return err - } - } - - forEachRef, err := o.Repo.Exec(ctx, git.SubCmd{ - Name: "for-each-ref", - Flags: []git.Option{git.Flag{Name: "--format=%(objecttype)%00%(refname)"}}, - Args: []string{"refs/"}, - }) - if err != nil { - return err - } - - danglingRefsByType := make(map[string]int) - normalRefsByType := make(map[string]int) - - scanner := bufio.NewScanner(forEachRef) - for scanner.Scan() { - line := bytes.SplitN(scanner.Bytes(), []byte{0}, 2) - if len(line) != 2 { - continue - } - - objectType := string(line[0]) - refname := string(line[1]) - - if strings.HasPrefix(refname, danglingObjectNamespace) { - danglingRefsByType[objectType]++ - } else { - normalRefsByType[objectType]++ - } - } - - if err := scanner.Err(); err != nil { - return err - } - if err := forEachRef.Wait(); err != nil { - return err - } - - for _, key := range []string{"blob", "commit", "tag", "tree"} { - fields["dangling."+key+".ref"] = danglingRefsByType[key] - fields["normal."+key+".ref"] = normalRefsByType[key] - } - - ctxlogrus.Extract(ctx).WithFields(fields).Info("pool dangling ref stats") - - return nil -} - -func sizeDir(ctx context.Context, dir string) (int64, error) { - // du -k reports size in KB - cmd, err := command.New(ctx, exec.Command("du", "-sk", dir), nil, nil, nil) - if err != nil { - return 0, err - } - - sizeLine, err := io.ReadAll(cmd) - if err != nil { - return 0, err - } - - if err := cmd.Wait(); err != nil { - return 0, err - } - - sizeParts := bytes.Split(sizeLine, []byte("\t")) - if len(sizeParts) != 2 { - return 0, fmt.Errorf("malformed du output: %q", sizeLine) - } - - size, err := strconv.ParseInt(string(sizeParts[0]), 10, 0) - if err != nil { - return 0, err - } - - // Convert KB to B - return size * 1024, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref_test.go deleted file mode 100644 index 67035866bb..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref_test.go +++ /dev/null @@ -1,288 +0,0 @@ -package updateref - -import ( - "context" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func setupUpdater(t *testing.T, ctx context.Context) (config.Cfg, *localrepo.Repo, *Updater) { - t.Helper() - - cfg, protoRepo, _ := testcfg.BuildWithRepo(t) - - repo := localrepo.NewTestRepo(t, cfg, protoRepo, git.WithSkipHooks()) - - updater, err := New(ctx, repo) - require.NoError(t, err) - - return cfg, repo, updater -} - -func TestCreate(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - headCommit, err := repo.ReadCommit(ctx, "HEAD") - require.NoError(t, err) - - ref := git.ReferenceName("refs/heads/_create") - sha := headCommit.Id - - require.NoError(t, updater.Create(ref, sha)) - require.NoError(t, updater.Commit()) - - // check the ref was created - commit, logErr := repo.ReadCommit(ctx, ref.Revision()) - require.NoError(t, logErr) - require.Equal(t, commit.Id, sha, "reference was created with the wrong SHA") -} - -func TestUpdate(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - headCommit, err := repo.ReadCommit(ctx, "HEAD") - require.NoError(t, err) - - ref := git.ReferenceName("refs/heads/feature") - sha := headCommit.Id - - // Sanity check: ensure the ref exists before we start - commit, logErr := repo.ReadCommit(ctx, ref.Revision()) - require.NoError(t, logErr) - require.NotEqual(t, commit.Id, sha, "%s points to HEAD: %s in the test repository", ref.String(), sha) - - require.NoError(t, updater.Update(ref, sha, "")) - require.NoError(t, updater.Prepare()) - require.NoError(t, updater.Commit()) - - // check the ref was updated - commit, logErr = repo.ReadCommit(ctx, ref.Revision()) - require.NoError(t, logErr) - require.Equal(t, commit.Id, sha, "reference was not updated") - - // since ref has been updated to HEAD, we know that it does not point to HEAD^. So, HEAD^ is an invalid "old value" for updating ref - parentCommit, err := repo.ReadCommit(ctx, "HEAD^") - require.NoError(t, err) - require.Error(t, updater.Update(ref, parentCommit.Id, parentCommit.Id)) - - // check the ref was not updated - commit, logErr = repo.ReadCommit(ctx, ref.Revision()) - require.NoError(t, logErr) - require.NotEqual(t, commit.Id, parentCommit.Id, "reference was updated when it shouldn't have been") -} - -func TestDelete(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - ref := git.ReferenceName("refs/heads/feature") - - require.NoError(t, updater.Delete(ref)) - require.NoError(t, updater.Commit()) - - // check the ref was removed - _, err := repo.ReadCommit(ctx, ref.Revision()) - require.Equal(t, localrepo.ErrObjectNotFound, err, "expected 'not found' error got %v", err) -} - -func TestUpdater_prepareLocksTransaction(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - commit, logErr := repo.ReadCommit(ctx, "refs/heads/master") - require.NoError(t, logErr) - - require.NoError(t, updater.Update("refs/heads/feature", commit.Id, "")) - require.NoError(t, updater.Prepare()) - require.NoError(t, updater.Update("refs/heads/feature", commit.Id, "")) - - err := updater.Commit() - require.Error(t, err, "cannot update after prepare") - require.Contains(t, err.Error(), "fatal: prepared transactions can only be closed") -} - -func TestUpdater_concurrentLocking(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - cfg, protoRepo, _ := testcfg.BuildWithRepo(t) - repo := localrepo.NewTestRepo(t, cfg, protoRepo, git.WithSkipHooks()) - - commit, logErr := repo.ReadCommit(ctx, "refs/heads/master") - require.NoError(t, logErr) - - firstUpdater, err := New(ctx, repo) - require.NoError(t, err) - require.NoError(t, firstUpdater.Update("refs/heads/master", "", commit.Id)) - require.NoError(t, firstUpdater.Prepare()) - - secondUpdater, err := New(ctx, repo) - require.NoError(t, err) - require.NoError(t, secondUpdater.Update("refs/heads/master", "", commit.Id)) - - // With flushing, we're able to detect concurrent locking at prepare time already instead of - // at commit time. - if gitSupportsStatusFlushing(t, ctx, cfg) { - err := secondUpdater.Prepare() - require.Error(t, err) - require.Contains(t, err.Error(), "fatal: prepare: cannot lock ref 'refs/heads/master'") - - require.NoError(t, firstUpdater.Commit()) - } else { - require.NoError(t, secondUpdater.Prepare()) - require.NoError(t, firstUpdater.Commit()) - - err := secondUpdater.Commit() - require.Error(t, err) - require.Contains(t, err.Error(), "fatal: prepare: cannot lock ref 'refs/heads/master'") - } -} - -func TestBulkOperation(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - headCommit, err := repo.ReadCommit(ctx, "HEAD") - require.NoError(t, err) - - for i := 0; i < 1000; i++ { - ref := fmt.Sprintf("refs/head/_test_%d", i) - require.NoError(t, updater.Create(git.ReferenceName(ref), headCommit.Id), "Failed to create ref %d", i) - } - - require.NoError(t, updater.Commit()) - - refs, err := repo.GetReferences(ctx, "refs/") - require.NoError(t, err) - require.Greater(t, len(refs), 1000, "At least 1000 refs should be present") -} - -func TestContextCancelAbortsRefChanges(t *testing.T) { - ctx := testhelper.Context(t) - - cfg, repo, _ := setupUpdater(t, ctx) - - headCommit, err := repo.ReadCommit(ctx, "HEAD") - require.NoError(t, err) - - childCtx, childCancel := context.WithCancel(ctx) - localRepo := localrepo.NewTestRepo(t, cfg, repo) - updater, err := New(childCtx, localRepo) - require.NoError(t, err) - - ref := git.ReferenceName("refs/heads/_shouldnotexist") - - require.NoError(t, updater.Create(ref, headCommit.Id)) - - // Force the update-ref process to terminate early - childCancel() - require.Error(t, updater.Commit()) - - // check the ref doesn't exist - _, err = repo.ReadCommit(ctx, ref.Revision()) - require.Equal(t, localrepo.ErrObjectNotFound, err, "expected 'not found' error got %v", err) -} - -func TestUpdater_cancel(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - require.NoError(t, updater.Delete(git.ReferenceName("refs/heads/master"))) - require.NoError(t, updater.Prepare()) - - // A concurrent update shouldn't be allowed. - concurrentUpdater, err := New(ctx, repo) - require.NoError(t, err) - require.NoError(t, concurrentUpdater.Delete(git.ReferenceName("refs/heads/master"))) - err = concurrentUpdater.Commit() - require.NotNil(t, err) - require.Contains(t, err.Error(), "fatal: commit: cannot lock ref 'refs/heads/master'") - - // We now cancel the initial updater. Afterwards, it should be possible again to update the - // ref because locks should have been released. - require.NoError(t, updater.Cancel()) - - concurrentUpdater, err = New(ctx, repo) - require.NoError(t, err) - require.NoError(t, concurrentUpdater.Delete(git.ReferenceName("refs/heads/master"))) - require.NoError(t, concurrentUpdater.Commit()) -} - -func TestUpdater_closingStdinAbortsChanges(t *testing.T) { - ctx := testhelper.Context(t) - - _, repo, updater := setupUpdater(t, ctx) - - headCommit, err := repo.ReadCommit(ctx, "HEAD") - require.NoError(t, err) - - ref := git.ReferenceName("refs/heads/shouldnotexist") - - require.NoError(t, updater.Create(ref, headCommit.Id)) - - // Note that we call `Wait()` on the command, not on the updater. This - // circumvents our usual semantics of sending "commit" and thus - // emulates that the command somehow terminates correctly without us - // terminating it intentionally. Previous to our use of the "start" - // verb, this would've caused the reference to be created... - require.NoError(t, updater.cmd.Wait()) - - // ... but as we now use explicit transactional behaviour, this is no - // longer the case. - _, err = repo.ReadCommit(ctx, ref.Revision()) - require.Equal(t, localrepo.ErrObjectNotFound, err, "expected 'not found' error got %v", err) -} - -func TestUpdater_capturesStderr(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - cfg, _, updater := setupUpdater(t, ctx) - - ref := "refs/heads/a" - newValue := strings.Repeat("1", 40) - oldValue := git.ZeroOID.String() - - require.NoError(t, updater.Update(git.ReferenceName(ref), newValue, oldValue)) - - var expectedErr string - if gitSupportsStatusFlushing(t, ctx, cfg) { - expectedErr = fmt.Sprintf("state update to \"commit\" failed: EOF, stderr: \"fatal: commit: cannot update ref '%s': "+ - "trying to write ref '%s' with nonexistent object %s\\n\"", ref, ref, newValue) - } else { - expectedErr = fmt.Sprintf("git update-ref: exit status 128, stderr: "+ - "\"fatal: commit: cannot update ref '%s': "+ - "trying to write ref '%s' with nonexistent object %s\\n\"", ref, ref, newValue) - } - - err := updater.Commit() - require.NotNil(t, err) - require.Equal(t, err.Error(), expectedErr) -} - -func gitSupportsStatusFlushing(t *testing.T, ctx context.Context, cfg config.Cfg) bool { - version, err := gittest.NewCommandFactory(t, cfg).GitVersion(ctx) - require.NoError(t, err) - return version.FlushesUpdaterefStatus() -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups/cgroups.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups/cgroups.go deleted file mode 100644 index dcfcdd5718..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups/cgroups.go +++ /dev/null @@ -1,32 +0,0 @@ -package cgroups - -// Config is a struct for cgroups config -type Config struct { - // Count is the number of cgroups to be created at startup - Count uint `toml:"count"` - // Mountpoint is where the cgroup filesystem is mounted, usually under /sys/fs/cgroup/ - Mountpoint string `toml:"mountpoint"` - // HierarchyRoot is the parent cgroup under which Gitaly creates of cgroups. - // A system administrator is expected to create such cgroup/directory under /memory - // and/or /cpu depending on which resource is enabled. HierarchyRoot is expected to - // be owned by the user and group Gitaly runs as. - HierarchyRoot string `toml:"hierarchy_root"` - // CPU holds CPU resource configurations - CPU CPU `toml:"cpu"` - // Memory holds memory resource configurations - Memory Memory `toml:"memory"` -} - -// Memory is a struct storing cgroups memory config -type Memory struct { - Enabled bool `toml:"enabled"` - // Limit is the memory limit in bytes. Could be -1 to indicate unlimited memory. - Limit int64 `toml:"limit"` -} - -// CPU is a struct storing cgroups CPU config -type CPU struct { - Enabled bool `toml:"enabled"` - // Shares is the number of CPU shares (relative weight (ratio) vs. other cgroups with CPU shares). - Shares uint64 `toml:"shares"` -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/ruby.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/ruby.go deleted file mode 100644 index 5bcc03ab8d..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/ruby.go +++ /dev/null @@ -1,82 +0,0 @@ -package config - -import ( - "fmt" - "path/filepath" - "time" -) - -// Ruby contains setting for Ruby worker processes -type Ruby struct { - Dir string `toml:"dir"` - MaxRSS int `toml:"max_rss"` - GracefulRestartTimeout Duration `toml:"graceful_restart_timeout"` - RestartDelay Duration `toml:"restart_delay"` - NumWorkers int `toml:"num_workers"` - LinguistLanguagesPath string `toml:"linguist_languages_path"` - RuggedGitConfigSearchPath string `toml:"rugged_git_config_search_path"` -} - -// Duration is a trick to let our TOML library parse durations from strings. -type Duration time.Duration - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (d *Duration) Duration() time.Duration { - if d != nil { - return time.Duration(*d) - } - return 0 -} - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (d *Duration) UnmarshalText(text []byte) error { - td, err := time.ParseDuration(string(text)) - if err == nil { - *d = Duration(td) - } - return err -} - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (d Duration) MarshalText() ([]byte, error) { - return []byte(time.Duration(d).String()), nil -} - -// ConfigureRuby validates the gitaly-ruby configuration and sets default values. -func (cfg *Cfg) ConfigureRuby() error { - if cfg.Ruby.GracefulRestartTimeout.Duration() == 0 { - cfg.Ruby.GracefulRestartTimeout = Duration(10 * time.Minute) - } - - if cfg.Ruby.MaxRSS == 0 { - cfg.Ruby.MaxRSS = 200 * 1024 * 1024 - } - - if cfg.Ruby.RestartDelay.Duration() == 0 { - cfg.Ruby.RestartDelay = Duration(5 * time.Minute) - } - - if len(cfg.Ruby.Dir) == 0 { - return fmt.Errorf("gitaly-ruby.dir: is not set") - } - - minWorkers := 2 - if cfg.Ruby.NumWorkers < minWorkers { - cfg.Ruby.NumWorkers = minWorkers - } - - var err error - cfg.Ruby.Dir, err = filepath.Abs(cfg.Ruby.Dir) - if err != nil { - return err - } - - if len(cfg.Ruby.RuggedGitConfigSearchPath) != 0 { - cfg.Ruby.RuggedGitConfigSearchPath, err = filepath.Abs(cfg.Ruby.RuggedGitConfigSearchPath) - if err != nil { - return err - } - } - - return validateIsDirectory(cfg.Ruby.Dir, "gitaly-ruby.dir") -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist.go deleted file mode 100644 index 9786e6547c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist.go +++ /dev/null @@ -1,186 +0,0 @@ -package linguist - -import ( - "context" - "crypto/sha256" - "encoding/json" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" -) - -var exportedEnvVars = []string{"HOME", "PATH", "GEM_HOME", "BUNDLE_PATH", "BUNDLE_APP_CONFIG", "BUNDLE_USER_CONFIG"} - -// Language is used to parse Linguist's language.json file. -type Language struct { - Color string `json:"color"` -} - -// ByteCountPerLanguage represents a counter value (bytes) per language. -type ByteCountPerLanguage map[string]uint64 - -// Instance is a holder of the defined in the system language settings. -type Instance struct { - cfg config.Cfg - colorMap map[string]Language - gitCmdFactory git.CommandFactory -} - -// New loads the name->color map from the Linguist gem and returns initialised instance -// to use back to the caller or an error. -func New(cfg config.Cfg, gitCmdFactory git.CommandFactory) (*Instance, error) { - jsonReader, err := openLanguagesJSON(cfg) - if err != nil { - return nil, err - } - defer jsonReader.Close() - - var colorMap map[string]Language - if err := json.NewDecoder(jsonReader).Decode(&colorMap); err != nil { - return nil, err - } - - return &Instance{ - cfg: cfg, - gitCmdFactory: gitCmdFactory, - colorMap: colorMap, - }, nil -} - -// Stats returns the repository's language stats as reported by 'git-linguist'. -func (inst *Instance) Stats(ctx context.Context, repoPath string, commitID string) (ByteCountPerLanguage, error) { - cmd, err := inst.startGitLinguist(ctx, repoPath, commitID, "stats") - if err != nil { - return nil, fmt.Errorf("starting linguist: %w", err) - } - - data, err := io.ReadAll(cmd) - if err != nil { - return nil, fmt.Errorf("reading linguist output: %w", err) - } - - if err := cmd.Wait(); err != nil { - return nil, fmt.Errorf("waiting for linguist: %w", err) - } - - stats := make(ByteCountPerLanguage) - if err := json.Unmarshal(data, &stats); err != nil { - return nil, fmt.Errorf("unmarshaling stats: %w", err) - } - - return stats, nil -} - -// Color returns the color Linguist has assigned to language. -func (inst *Instance) Color(language string) string { - if color := inst.colorMap[language].Color; color != "" { - return color - } - - colorSha := sha256.Sum256([]byte(language)) - return fmt.Sprintf("#%x", colorSha[0:3]) -} - -func (inst *Instance) startGitLinguist(ctx context.Context, repoPath string, commitID string, linguistCommand string) (*command.Command, error) { - bundle, err := exec.LookPath("bundle") - if err != nil { - return nil, fmt.Errorf("finding bundle executable: %w", err) - } - - args := []string{ - bundle, - "exec", - "bin/ruby-cd", - repoPath, - "git-linguist", - "--commit=" + commitID, - linguistCommand, - } - - gitExecEnv := inst.gitCmdFactory.GetExecutionEnvironment(ctx) - - // This is a horrible hack. git-linguist will execute `git rev-parse - // --git-dir` to check whether it is in a Git directory or not. We don't - // want to use the one provided by PATH, but instead the one specified - // via the configuration. git-linguist doesn't specify any way to choose - // a different Git implementation, so we need to prepend the configured - // Git's directory to PATH. But as our internal command interface will - // overwrite PATH even if we pass it in here, we need to work around it - // and instead execute the command with `env PATH=$GITDIR:$PATH`. - gitDir := filepath.Dir(gitExecEnv.BinaryPath) - if path, ok := os.LookupEnv("PATH"); ok && gitDir != "." { - args = append([]string{ - "env", fmt.Sprintf("PATH=%s:%s", gitDir, path), - }, args...) - } - - cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = inst.cfg.Ruby.Dir - - internalCmd, err := command.New(ctx, cmd, nil, nil, nil, exportEnvironment()...) - if err != nil { - return nil, fmt.Errorf("creating command: %w", err) - } - - internalCmd.SetMetricsCmd("git-linguist") - internalCmd.SetMetricsSubCmd(linguistCommand) - - return internalCmd, nil -} - -func openLanguagesJSON(cfg config.Cfg) (io.ReadCloser, error) { - if jsonPath := cfg.Ruby.LinguistLanguagesPath; jsonPath != "" { - // This is a fallback for environments where dynamic discovery of the - // linguist path via Bundler is not working for some reason, for example - // https://gitlab.com/gitlab-org/gitaly/issues/1119. - return os.Open(jsonPath) - } - - linguistPathSymlink, err := os.CreateTemp("", "gitaly-linguist-path") - if err != nil { - return nil, err - } - defer func() { _ = os.Remove(linguistPathSymlink.Name()) }() - - if err := linguistPathSymlink.Close(); err != nil { - return nil, err - } - - // We use a symlink because we cannot trust Bundler to not print garbage - // on its stdout. - rubyScript := `FileUtils.ln_sf(Bundler.rubygems.find_name('github-linguist').first.full_gem_path, ARGV.first)` - cmd := exec.Command("bundle", "exec", "ruby", "-rfileutils", "-e", rubyScript, linguistPathSymlink.Name()) - cmd.Dir = cfg.Ruby.Dir - - // We have learned that in practice the command we are about to run is a - // canary for Ruby/Bundler configuration problems. Including stderr and - // stdout in the gitaly log is useful for debugging such problems. - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - - if err := cmd.Run(); err != nil { - if exitError, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("%v; stderr: %q", exitError, exitError.Stderr) - } - return nil, err - } - - return os.Open(filepath.Join(linguistPathSymlink.Name(), "lib", "linguist", "languages.json")) -} - -func exportEnvironment() []string { - var env []string - for _, envVarName := range exportedEnvVars { - if val, ok := os.LookupEnv(envVarName); ok { - env = append(env, fmt.Sprintf("%s=%s", envVarName, val)) - } - } - - return env -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist_test.go deleted file mode 100644 index a0aea903b2..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/linguist_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package linguist - -import ( - "encoding/json" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func TestInstance_Stats_successful(t *testing.T) { - ctx := testhelper.Context(t) - - cfg, _, repoPath := testcfg.BuildWithRepo(t) - - ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) - require.NoError(t, err) - - counts, err := ling.Stats(ctx, repoPath, "1e292f8fedd741b75372e19097c76d327140c312") - require.NoError(t, err) - require.Equal(t, uint64(2943), counts["Ruby"]) -} - -func TestInstance_Stats_unmarshalJSONError(t *testing.T) { - cfg := testcfg.Build(t) - ctx := testhelper.Context(t) - - ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) - require.NoError(t, err) - - // When an error occurs, this used to trigger JSON marshelling of a plain string - // the new behaviour shouldn't do that, and return an command error - _, err = ling.Stats(ctx, "/var/empty", "deadbeef") - require.Error(t, err) - - _, ok := err.(*json.SyntaxError) - require.False(t, ok, "expected the error not be a json Syntax Error") -} - -func TestNew(t *testing.T) { - cfg := testcfg.Build(t, testcfg.WithRealLinguist()) - - ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) - require.NoError(t, err) - - require.Equal(t, "#701516", ling.Color("Ruby"), "color value for 'Ruby'") -} - -func TestNew_loadLanguagesCustomPath(t *testing.T) { - jsonPath, err := filepath.Abs("testdata/fake-languages.json") - require.NoError(t, err) - - cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{Ruby: config.Ruby{LinguistLanguagesPath: jsonPath}})) - - ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) - require.NoError(t, err) - - require.Equal(t, "foo color", ling.Color("FooBar")) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver_test.go deleted file mode 100644 index dceb98d177..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver_test.go +++ /dev/null @@ -1,131 +0,0 @@ -package rubyserver - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc/codes" -) - -func TestStopSafe(t *testing.T) { - badServers := []*Server{ - nil, - New(config.Cfg{}, nil), - } - - for _, bs := range badServers { - bs.Stop() - } -} - -func TestSetHeaders(t *testing.T) { - cfg, repo, _ := testcfg.BuildWithRepo(t) - ctx := testhelper.Context(t) - - locator := config.NewLocator(cfg) - - testCases := []struct { - desc string - repo *gitalypb.Repository - errType codes.Code - setter func(context.Context, storage.Locator, *gitalypb.Repository) (context.Context, error) - }{ - { - desc: "SetHeaders invalid storage", - repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, - errType: codes.InvalidArgument, - setter: SetHeaders, - }, - { - desc: "SetHeaders invalid rel path", - repo: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "bar.git"}, - errType: codes.NotFound, - setter: SetHeaders, - }, - { - desc: "SetHeaders OK", - repo: repo, - errType: codes.OK, - setter: SetHeaders, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - clientCtx, err := tc.setter(ctx, locator, tc.repo) - - if tc.errType != codes.OK { - testhelper.RequireGrpcCode(t, err, tc.errType) - assert.Nil(t, clientCtx) - } else { - assert.NoError(t, err) - assert.NotNil(t, clientCtx) - } - }) - } -} - -type mockGitCommandFactory struct { - git.CommandFactory -} - -func (mockGitCommandFactory) GetExecutionEnvironment(context.Context) git.ExecutionEnvironment { - return git.ExecutionEnvironment{ - BinaryPath: "/something", - EnvironmentVariables: []string{ - "FOO=bar", - }, - } -} - -func (mockGitCommandFactory) HooksPath(context.Context) string { - return "custom_hooks_path" -} - -func TestSetupEnv(t *testing.T) { - cfg := config.Cfg{ - BinDir: "/bin/dit", - InternalSocketDir: "/gitaly", - Logging: config.Logging{ - Config: log.Config{ - Dir: "/log/dir", - }, - RubySentryDSN: "testDSN", - Sentry: config.Sentry{ - Environment: "testEnvironment", - }, - }, - Auth: auth.Config{Token: "paswd"}, - Ruby: config.Ruby{RuggedGitConfigSearchPath: "/bin/rugged"}, - } - - env := setupEnv(cfg, mockGitCommandFactory{}) - - require.Contains(t, env, "FOO=bar") - require.Contains(t, env, "GITALY_LOG_DIR=/log/dir") - require.Contains(t, env, "GITALY_RUBY_GIT_BIN_PATH=/something") - require.Contains(t, env, fmt.Sprintf("GITALY_RUBY_WRITE_BUFFER_SIZE=%d", streamio.WriteBufferSize)) - require.Contains(t, env, fmt.Sprintf("GITALY_RUBY_MAX_COMMIT_OR_TAG_MESSAGE_SIZE=%d", helper.MaxCommitOrTagMessageSize)) - require.Contains(t, env, "GITALY_RUBY_GITALY_BIN_DIR=/bin/dit") - require.Contains(t, env, "GITALY_VERSION="+version.GetVersion()) - require.Contains(t, env, fmt.Sprintf("GITALY_SOCKET=%s", cfg.GitalyInternalSocketPath())) - require.Contains(t, env, "GITALY_TOKEN=paswd") - require.Contains(t, env, "GITALY_RUGGED_GIT_CONFIG_SEARCH_PATH=/bin/rugged") - require.Contains(t, env, "SENTRY_DSN=testDSN") - require.Contains(t, env, "SENTRY_ENVIRONMENT=testEnvironment") - require.Contains(t, env, "GITALY_GIT_HOOKS_DIR=custom_hooks_path") -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist.go deleted file mode 100644 index baab66f513..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist.go +++ /dev/null @@ -1,110 +0,0 @@ -package commit - -import ( - "context" - "io" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/protobuf/proto" -) - -func (s *server) CheckObjectsExist( - stream gitalypb.CommitService_CheckObjectsExistServer, -) error { - ctx := stream.Context() - - request, err := stream.Recv() - if err != nil { - return err - } - - if err := validateCheckObjectsExistRequest(request); err != nil { - return err - } - - objectInfoReader, err := s.catfileCache.ObjectInfoReader( - ctx, - s.localrepo(request.GetRepository()), - ) - if err != nil { - return err - } - - chunker := chunk.New(&checkObjectsExistSender{stream: stream}) - for { - request, err := stream.Recv() - if err != nil { - if err == io.EOF { - return chunker.Flush() - } - return err - } - - if err = checkObjectsExist(ctx, request, objectInfoReader, chunker); err != nil { - return err - } - } -} - -type checkObjectsExistSender struct { - stream gitalypb.CommitService_CheckObjectsExistServer - revisions []*gitalypb.CheckObjectsExistResponse_RevisionExistence -} - -func (c *checkObjectsExistSender) Send() error { - return c.stream.Send(&gitalypb.CheckObjectsExistResponse{ - Revisions: c.revisions, - }) -} - -func (c *checkObjectsExistSender) Reset() { - c.revisions = make([]*gitalypb.CheckObjectsExistResponse_RevisionExistence, 0) -} - -func (c *checkObjectsExistSender) Append(m proto.Message) { - c.revisions = append(c.revisions, m.(*gitalypb.CheckObjectsExistResponse_RevisionExistence)) -} - -func checkObjectsExist( - ctx context.Context, - request *gitalypb.CheckObjectsExistRequest, - objectInfoReader catfile.ObjectInfoReader, - chunker *chunk.Chunker, -) error { - revisions := request.GetRevisions() - - for _, revision := range revisions { - revisionExistence := gitalypb.CheckObjectsExistResponse_RevisionExistence{ - Name: revision, - Exists: true, - } - _, err := objectInfoReader.Info(ctx, git.Revision(revision)) - if err != nil { - if catfile.IsNotFound(err) { - revisionExistence.Exists = false - } else { - return err - } - } - - if err := chunker.Send(&revisionExistence); err != nil { - return err - } - } - - return nil -} - -func validateCheckObjectsExistRequest(in *gitalypb.CheckObjectsExistRequest) error { - for _, revision := range in.GetRevisions() { - if err := git.ValidateRevision(revision); err != nil { - return helper.ErrInvalidArgument(err) - } - } - - return nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist_test.go deleted file mode 100644 index 97fed524f4..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/check_objects_exist_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package commit - -import ( - "io" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" -) - -func TestCheckObjectsExist(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) - - // write a few commitIDs we can use - commitID1 := gittest.WriteCommit(t, cfg, repoPath) - commitID2 := gittest.WriteCommit(t, cfg, repoPath) - commitID3 := gittest.WriteCommit(t, cfg, repoPath) - - // remove a ref from the repository so we know it doesn't exist - gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "-d", "refs/heads/many_files") - - nonexistingObject := "abcdefg" - cmd := gittest.NewCommand(t, cfg, "-C", repoPath, "rev-parse", nonexistingObject) - require.Error(t, cmd.Wait(), "ensure the object doesn't exist") - - testCases := []struct { - desc string - input [][]byte - revisionsExistence map[string]bool - returnCode codes.Code - }{ - { - desc: "commit ids and refs that exist", - input: [][]byte{ - []byte(commitID1), - []byte("master"), - []byte(commitID2), - []byte(commitID3), - []byte("feature"), - }, - revisionsExistence: map[string]bool{ - "master": true, - commitID2.String(): true, - commitID3.String(): true, - "feature": true, - }, - returnCode: codes.OK, - }, - { - desc: "ref and objects missing", - input: [][]byte{ - []byte(commitID1), - []byte("master"), - []byte(commitID2), - []byte(commitID3), - []byte("feature"), - []byte("many_files"), - []byte(nonexistingObject), - }, - revisionsExistence: map[string]bool{ - "master": true, - commitID2.String(): true, - commitID3.String(): true, - "feature": true, - "many_files": false, - nonexistingObject: false, - }, - returnCode: codes.OK, - }, - { - desc: "empty input", - input: [][]byte{}, - returnCode: codes.OK, - revisionsExistence: map[string]bool{}, - }, - { - desc: "invalid input", - input: [][]byte{[]byte("-not-a-rev")}, - returnCode: codes.InvalidArgument, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - c, err := client.CheckObjectsExist(ctx) - require.NoError(t, err) - - require.NoError(t, c.Send( - &gitalypb.CheckObjectsExistRequest{ - Repository: repo, - Revisions: tc.input, - }, - )) - require.NoError(t, c.CloseSend()) - - for { - resp, err := c.Recv() - if tc.returnCode != codes.OK { - testhelper.RequireGrpcCode(t, err, tc.returnCode) - break - } else if err != nil { - require.Error(t, err, io.EOF) - break - } - - actualRevisionsExistence := make(map[string]bool) - for _, revisionExistence := range resp.GetRevisions() { - actualRevisionsExistence[string(revisionExistence.GetName())] = revisionExistence.GetExists() - } - assert.Equal(t, tc.revisionsExistence, actualRevisionsExistence) - } - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats_test.go deleted file mode 100644 index 2305eb13d2..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package commit - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" -) - -func TestCommitStatsSuccess(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) - - tests := []struct { - desc string - revision string - oid string - additions, deletions int32 - }{ - { - desc: "multiple changes, multiple files", - revision: "test-do-not-touch", - oid: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", - additions: 27, - deletions: 59, - }, - { - desc: "multiple changes, multiple files, reference by commit ID", - revision: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", - oid: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", - additions: 27, - deletions: 59, - }, - { - desc: "merge commit", - revision: "60ecb67", - oid: "60ecb67744cb56576c30214ff52294f8ce2def98", - additions: 1, - deletions: 0, - }, - { - desc: "binary file", - revision: "ae73cb0", - oid: "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", - additions: 0, - deletions: 0, - }, - { - desc: "initial commit", - revision: "1a0b36b3", - oid: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", - additions: 43, - deletions: 0, - }, - } - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - resp, err := client.CommitStats(ctx, &gitalypb.CommitStatsRequest{ - Repository: repo, - Revision: []byte(tc.revision), - }) - require.NoError(t, err) - - assert.Equal(t, tc.oid, resp.GetOid()) - assert.Equal(t, tc.additions, resp.GetAdditions()) - assert.Equal(t, tc.deletions, resp.GetDeletions()) - }) - } -} - -func TestCommitStatsFailure(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) - - tests := []struct { - desc string - repo *gitalypb.Repository - revision []byte - err codes.Code - }{ - { - desc: "repo not found", - repo: &gitalypb.Repository{StorageName: repo.GetStorageName(), RelativePath: "bar.git"}, - revision: []byte("test-do-not-touch"), - err: codes.NotFound, - }, - { - desc: "storage not found", - repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, - revision: []byte("test-do-not-touch"), - err: codes.InvalidArgument, - }, - { - desc: "ref not found", - repo: repo, - revision: []byte("non/existing"), - err: codes.Internal, - }, - { - desc: "invalid revision", - repo: repo, - revision: []byte("--outpu=/meow"), - err: codes.InvalidArgument, - }, - } - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - _, err := client.CommitStats(ctx, &gitalypb.CommitStatsRequest{Repository: tc.repo, Revision: tc.revision}) - testhelper.RequireGrpcCode(t, err, tc.err) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/testhelper_test.go deleted file mode 100644 index 853a0581eb..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/testhelper_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package conflicts - -import ( - "context" - "path/filepath" - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func SetupConflictsService(ctx context.Context, t testing.TB, bare bool, hookManager hook.Manager) (config.Cfg, *gitalypb.Repository, string, gitalypb.ConflictsServiceClient) { - cfg := testcfg.Build(t) - - testcfg.BuildGitalyGit2Go(t, cfg) - - serverSocketPath := runConflictsServer(t, cfg, hookManager) - cfg.SocketPath = serverSocketPath - - client, conn := NewConflictsClient(t, serverSocketPath) - t.Cleanup(func() { conn.Close() }) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - if !bare { - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") - // AddWorktree creates a detached worktree. Checkout master here so the - // branch pointer moves as we later commit. - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "master") - } - - return cfg, repo, repoPath, client -} - -func runConflictsServer(t testing.TB, cfg config.Cfg, hookManager hook.Manager) string { - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterConflictsServiceServer(srv, NewServer( - deps.GetHookManager(), - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetUpdaterWithHooks(), - )) - gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( - deps.GetCfg(), - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - gitalypb.RegisterSSHServiceServer(srv, ssh.NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - gitalypb.RegisterCommitServiceServer(srv, commit.NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetLinguist(), - deps.GetCatfileCache(), - )) - }, testserver.WithHookManager(hookManager)) -} - -func NewConflictsClient(t testing.TB, serverSocketPath string) (gitalypb.ConflictsServiceClient, *grpc.ClientConn) { - connOpts := []grpc.DialOption{ - grpc.WithInsecure(), - } - - conn, err := grpc.Dial(serverSocketPath, connOpts...) - if err != nil { - t.Fatal(err) - } - - return gitalypb.NewConflictsServiceClient(conn), conn -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths.go deleted file mode 100644 index 17841bc961..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths.go +++ /dev/null @@ -1,155 +0,0 @@ -package diff - -import ( - "bufio" - "context" - "fmt" - "io" - "strings" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -const ( - numStatDelimiter = 0 -) - -func (s *server) FindChangedPaths(in *gitalypb.FindChangedPathsRequest, stream gitalypb.DiffService_FindChangedPathsServer) error { - if err := s.validateFindChangedPathsRequestParams(stream.Context(), in); err != nil { - return err - } - - diffChunker := chunk.New(&findChangedPathsSender{stream: stream}) - - cmd, err := s.gitCmdFactory.New(stream.Context(), in.Repository, git.SubCmd{ - Name: "diff-tree", - Flags: []git.Option{ - git.Flag{Name: "-z"}, - git.Flag{Name: "--stdin"}, - git.Flag{Name: "-m"}, - git.Flag{Name: "-r"}, - git.Flag{Name: "--name-status"}, - git.Flag{Name: "--no-renames"}, - git.Flag{Name: "--no-commit-id"}, - git.Flag{Name: "--diff-filter=AMDTC"}, - }, - }, git.WithStdin(strings.NewReader(strings.Join(in.GetCommits(), "\n")+"\n"))) - if err != nil { - if _, ok := status.FromError(err); ok { - return fmt.Errorf("FindChangedPaths Stdin Err: %w", err) - } - return status.Errorf(codes.Internal, "FindChangedPaths: Cmd Err: %v", err) - } - - if err := parsePaths(bufio.NewReader(cmd), diffChunker); err != nil { - return fmt.Errorf("FindChangedPaths Parsing Err: %w", err) - } - - if err := cmd.Wait(); err != nil { - return status.Errorf(codes.Unavailable, "FindChangedPaths: Cmd Wait Err: %v", err) - } - - return diffChunker.Flush() -} - -func parsePaths(reader *bufio.Reader, chunker *chunk.Chunker) error { - for { - path, err := nextPath(reader) - if err != nil { - if err == io.EOF { - break - } - - return fmt.Errorf("FindChangedPaths Next Path Err: %w", err) - } - - if err := chunker.Send(path); err != nil { - return fmt.Errorf("FindChangedPaths: err sending to chunker: %v", err) - } - } - - return nil -} - -func nextPath(reader *bufio.Reader) (*gitalypb.ChangedPaths, error) { - pathStatus, err := reader.ReadBytes(numStatDelimiter) - if err != nil { - return nil, err - } - - path, err := reader.ReadBytes(numStatDelimiter) - if err != nil { - return nil, err - } - - statusTypeMap := map[string]gitalypb.ChangedPaths_Status{ - "M": gitalypb.ChangedPaths_MODIFIED, - "D": gitalypb.ChangedPaths_DELETED, - "T": gitalypb.ChangedPaths_TYPE_CHANGE, - "C": gitalypb.ChangedPaths_COPIED, - "A": gitalypb.ChangedPaths_ADDED, - } - - parsedPath, ok := statusTypeMap[string(pathStatus[:len(pathStatus)-1])] - if !ok { - return nil, status.Errorf(codes.Internal, "FindChangedPaths: Unknown changed paths returned: %v", string(pathStatus)) - } - - changedPath := &gitalypb.ChangedPaths{ - Status: parsedPath, - Path: path[:len(path)-1], - } - - return changedPath, nil -} - -// This sender implements the interface in the chunker class -type findChangedPathsSender struct { - paths []*gitalypb.ChangedPaths - stream gitalypb.DiffService_FindChangedPathsServer -} - -func (t *findChangedPathsSender) Reset() { - t.paths = nil -} - -func (t *findChangedPathsSender) Append(m proto.Message) { - t.paths = append(t.paths, m.(*gitalypb.ChangedPaths)) -} - -func (t *findChangedPathsSender) Send() error { - return t.stream.Send(&gitalypb.FindChangedPathsResponse{ - Paths: t.paths, - }) -} - -func (s *server) validateFindChangedPathsRequestParams(ctx context.Context, in *gitalypb.FindChangedPathsRequest) error { - repo := in.GetRepository() - if _, err := s.locator.GetRepoPath(repo); err != nil { - return err - } - - gitRepo := s.localrepo(in.GetRepository()) - - for _, commit := range in.GetCommits() { - if commit == "" { - return status.Errorf(codes.InvalidArgument, "FindChangedPaths: commits cannot contain an empty commit") - } - - containsRef, err := gitRepo.HasRevision(ctx, git.Revision(commit+"^{commit}")) - if err != nil { - return fmt.Errorf("contains ref err: %w", err) - } - - if !containsRef { - return status.Errorf(codes.NotFound, "FindChangedPaths: commit: %v can not be found", commit) - } - } - - return nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths_test.go deleted file mode 100644 index 5f672b2b77..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/find_changed_paths_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package diff - -import ( - "io" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -func TestFindChangedPathsRequest_success(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupDiffService(ctx, t) - - testCases := []struct { - desc string - commits []string - expectedPaths []*gitalypb.ChangedPaths - }{ - { - "Returns the expected results without a merge commit", - []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "57290e673a4c87f51294f5216672cbc58d485d25", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", "d59c60028b053793cecfb4022de34602e1a9218e"}, - []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("CONTRIBUTING.md"), - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("MAINTENANCE.md"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/テスト.txt"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/deleted-file"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/file-with-multiple-chunks"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/mode-file"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/mode-file-with-mods"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/named-file"), - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/named-file-with-mods"), - }, - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("files/js/commit.js.coffee"), - }, - }, - }, - { - "Returns the expected results with a merge commit", - []string{"7975be0116940bf2ad4321f79d02a55c5f7779aa", "55bc176024cfa3baaceb71db584c7e5df900ea65"}, - []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("files/images/emoji.png"), - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte(".gitattributes"), - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - rpcRequest := &gitalypb.FindChangedPathsRequest{Repository: repo, Commits: tc.commits} - - stream, err := client.FindChangedPaths(ctx, rpcRequest) - require.NoError(t, err) - - var paths []*gitalypb.ChangedPaths - for { - fetchedPaths, err := stream.Recv() - if err == io.EOF { - break - } - - require.NoError(t, err) - - paths = append(paths, fetchedPaths.GetPaths()...) - } - - require.Equal(t, tc.expectedPaths, paths) - }) - } -} - -func TestFindChangedPathsRequest_failing(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repo, _, client := setupDiffService(ctx, t, testserver.WithDisablePraefect()) - - tests := []struct { - desc string - repo *gitalypb.Repository - commits []string - err error - }{ - { - desc: "Repo not found", - repo: &gitalypb.Repository{StorageName: repo.GetStorageName(), RelativePath: "bar.git"}, - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: status.Errorf(codes.NotFound, "GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")), - }, - { - desc: "Storage not found", - repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: status.Error(codes.InvalidArgument, "GetStorageByName: no such storage: \"foo\""), - }, - { - desc: "Commits cannot contain an empty commit", - repo: repo, - commits: []string{""}, - err: status.Error(codes.InvalidArgument, "FindChangedPaths: commits cannot contain an empty commit"), - }, - { - desc: "Invalid commit", - repo: repo, - commits: []string{"invalidinvalidinvalid", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: status.Error(codes.NotFound, "FindChangedPaths: commit: invalidinvalidinvalid can not be found"), - }, - { - desc: "Commit not found", - repo: repo, - commits: []string{"z4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: status.Error(codes.NotFound, "FindChangedPaths: commit: z4003da16c1c2c3fc4567700121b17bf8e591c6c can not be found"), - }, - } - - for _, tc := range tests { - rpcRequest := &gitalypb.FindChangedPathsRequest{Repository: tc.repo, Commits: tc.commits} - stream, err := client.FindChangedPaths(ctx, rpcRequest) - require.NoError(t, err) - - t.Run(tc.desc, func(t *testing.T) { - _, err := stream.Recv() - testhelper.RequireGrpcError(t, tc.err, err) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw_test.go deleted file mode 100644 index b153b589c2..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package diff - -import ( - "fmt" - "io" - "regexp" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc/codes" -) - -func TestSuccessfulRawDiffRequest(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupDiffService(ctx, t) - - rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" - leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" - rpcRequest := &gitalypb.RawDiffRequest{Repository: repo, RightCommitId: rightCommit, LeftCommitId: leftCommit} - - c, err := client.RawDiff(ctx, rpcRequest) - require.NoError(t, err) - - _, sandboxRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - WithWorktree: true, - }) - - reader := streamio.NewReader(func() ([]byte, error) { - response, err := c.Recv() - return response.GetData(), err - }) - - committerName := "Scrooge McDuck" - committerEmail := "scrooge@mcduck.com" - gittest.Exec(t, cfg, "-C", sandboxRepoPath, "reset", "--hard", leftCommit) - - gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: reader}, "-C", sandboxRepoPath, "apply") - gittest.Exec(t, cfg, "-C", sandboxRepoPath, "add", ".") - gittest.Exec(t, cfg, "-C", sandboxRepoPath, - "-c", fmt.Sprintf("user.name=%s", committerName), - "-c", fmt.Sprintf("user.email=%s", committerEmail), - "commit", "-m", "Applying received raw diff") - - expectedTreeStructure := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-r", rightCommit) - actualTreeStructure := gittest.Exec(t, cfg, "-C", sandboxRepoPath, "ls-tree", "-r", "HEAD") - require.Equal(t, expectedTreeStructure, actualTreeStructure) -} - -func TestFailedRawDiffRequestDueToValidations(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupDiffService(ctx, t) - - testCases := []struct { - desc string - request *gitalypb.RawDiffRequest - code codes.Code - }{ - { - desc: "empty left commit", - request: &gitalypb.RawDiffRequest{ - Repository: repo, - LeftCommitId: "", - RightCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - { - desc: "empty right commit", - request: &gitalypb.RawDiffRequest{ - Repository: repo, - RightCommitId: "", - LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - { - desc: "empty repo", - request: &gitalypb.RawDiffRequest{ - Repository: nil, - RightCommitId: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", - LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - c, _ := client.RawDiff(ctx, testCase.request) - testhelper.RequireGrpcCode(t, drainRawDiffResponse(c), testCase.code) - }) - } -} - -func TestSuccessfulRawPatchRequest(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupDiffService(ctx, t) - - rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" - leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" - rpcRequest := &gitalypb.RawPatchRequest{Repository: repo, RightCommitId: rightCommit, LeftCommitId: leftCommit} - - c, err := client.RawPatch(ctx, rpcRequest) - require.NoError(t, err) - - reader := streamio.NewReader(func() ([]byte, error) { - response, err := c.Recv() - return response.GetData(), err - }) - - _, sandboxRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - WithWorktree: true, - }) - - gittest.Exec(t, cfg, "-C", sandboxRepoPath, "reset", "--hard", leftCommit) - gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: reader}, "-C", sandboxRepoPath, "am") - - expectedTreeStructure := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-r", rightCommit) - actualTreeStructure := gittest.Exec(t, cfg, "-C", sandboxRepoPath, "ls-tree", "-r", "HEAD") - require.Equal(t, expectedTreeStructure, actualTreeStructure) -} - -func TestFailedRawPatchRequestDueToValidations(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupDiffService(ctx, t) - - testCases := []struct { - desc string - request *gitalypb.RawPatchRequest - code codes.Code - }{ - { - desc: "empty left commit", - request: &gitalypb.RawPatchRequest{ - Repository: repo, - LeftCommitId: "", - RightCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - { - desc: "empty right commit", - request: &gitalypb.RawPatchRequest{ - Repository: repo, - RightCommitId: "", - LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - { - desc: "empty repo", - request: &gitalypb.RawPatchRequest{ - Repository: nil, - RightCommitId: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", - LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", - }, - code: codes.InvalidArgument, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - c, _ := client.RawPatch(ctx, testCase.request) - testhelper.RequireGrpcCode(t, drainRawPatchResponse(c), testCase.code) - }) - } -} - -func TestRawPatchContainsGitLabSignature(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupDiffService(ctx, t) - - rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" - leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" - rpcRequest := &gitalypb.RawPatchRequest{Repository: repo, RightCommitId: rightCommit, LeftCommitId: leftCommit} - - c, err := client.RawPatch(ctx, rpcRequest) - require.NoError(t, err) - - reader := streamio.NewReader(func() ([]byte, error) { - response, err := c.Recv() - return response.GetData(), err - }) - - patch, err := io.ReadAll(reader) - require.NoError(t, err) - - require.Regexp(t, regexp.MustCompile(`\n-- \nGitLab\s+$`), string(patch)) -} - -func drainRawDiffResponse(c gitalypb.DiffService_RawDiffClient) error { - var err error - for err == nil { - _, err = c.Recv() - } - return err -} - -func drainRawPatchResponse(c gitalypb.DiffService_RawPatchClient) error { - var err error - for err == nil { - _, err = c.Recv() - } - return err -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testhelper_test.go deleted file mode 100644 index c2b8f3b055..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testhelper_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package diff - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func setupDiffService(ctx context.Context, t testing.TB, opt ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.DiffServiceClient) { - cfg := testcfg.Build(t) - - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterDiffServiceServer(srv, NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - )) - gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( - cfg, - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }, opt...) - cfg.SocketPath = addr - - conn, err := grpc.Dial(addr, grpc.WithInsecure()) - require.NoError(t, err) - t.Cleanup(func() { testhelper.MustClose(t, conn) }) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - return cfg, repo, repoPath, gitalypb.NewDiffServiceClient(conn) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/server.go deleted file mode 100644 index 23e9c65c8e..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/server.go +++ /dev/null @@ -1,26 +0,0 @@ -package hook - -import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/streamcache" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -type server struct { - gitalypb.UnimplementedHookServiceServer - manager gitalyhook.Manager - gitCmdFactory git.CommandFactory - packObjectsCache streamcache.Cache -} - -// NewServer creates a new instance of a gRPC namespace server -func NewServer(manager gitalyhook.Manager, gitCmdFactory git.CommandFactory, packObjectsCache streamcache.Cache) gitalypb.HookServiceServer { - srv := &server{ - manager: manager, - gitCmdFactory: gitCmdFactory, - packObjectsCache: packObjectsCache, - } - - return srv -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/testhelper_test.go deleted file mode 100644 index 0c61df801a..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/testhelper_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package hook - -import ( - "context" - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func setupHookService(ctx context.Context, t testing.TB) (config.Cfg, *gitalypb.Repository, string, gitalypb.HookServiceClient) { - t.Helper() - - cfg := testcfg.Build(t) - cfg.SocketPath = runHooksServer(t, cfg, nil) - client, conn := newHooksClient(t, cfg.SocketPath) - t.Cleanup(func() { conn.Close() }) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - return cfg, repo, repoPath, client -} - -func newHooksClient(t testing.TB, serverSocketPath string) (gitalypb.HookServiceClient, *grpc.ClientConn) { - t.Helper() - - connOpts := []grpc.DialOption{ - grpc.WithInsecure(), - } - conn, err := grpc.Dial(serverSocketPath, connOpts...) - if err != nil { - t.Fatal(err) - } - - return gitalypb.NewHookServiceClient(conn), conn -} - -type serverOption func(*server) - -func runHooksServer(t testing.TB, cfg config.Cfg, opts []serverOption, serverOpts ...testserver.GitalyServerOpt) string { - t.Helper() - - serverOpts = append(serverOpts, testserver.WithDisablePraefect()) - - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - hookServer := NewServer( - gitalyhook.NewManager(deps.GetCfg(), deps.GetLocator(), deps.GetGitCmdFactory(), deps.GetTxManager(), deps.GetGitlabClient()), - deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - ) - for _, opt := range opts { - opt(hookServer.(*server)) - } - - gitalypb.RegisterHookServiceServer(srv, hookServer) - gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( - cfg, - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }, serverOpts...) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/testhelper_test.go deleted file mode 100644 index a37b5a03ad..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/testhelper_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package namespace - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" -) - -func setupNamespaceService(t testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, gitalypb.NamespaceServiceClient) { - cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages("default", "other")) - cfg := cfgBuilder.Build(t) - - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterNamespaceServiceServer(srv, NewServer(deps.GetLocator())) - }, opts...) - - conn, err := grpc.Dial(addr, grpc.WithInsecure()) - require.NoError(t, err) - t.Cleanup(func() { testhelper.MustClose(t, conn) }) - - return cfg, gitalypb.NewNamespaceServiceClient(conn) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go deleted file mode 100644 index 879c1cf1ac..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go +++ /dev/null @@ -1,252 +0,0 @@ -package objectpool - -import ( - "os" - "path/filepath" - "testing" - "time" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/labkit/log" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -func TestFetchIntoObjectPool_Success(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repo, repoPath, locator, client := setup(ctx, t) - - repoCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(t.Name())) - - pool := initObjectPool(t, cfg, cfg.Storages[0]) - _, err := client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - }) - require.NoError(t, err) - - req := &gitalypb.FetchIntoObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - Repack: true, - } - - _, err = client.FetchIntoObjectPool(ctx, req) - require.NoError(t, err) - - pool = rewrittenObjectPool(ctx, t, cfg, pool) - - require.True(t, pool.IsValid(), "ensure underlying repository is valid") - - // No problems - gittest.Exec(t, cfg, "-C", pool.FullPath(), "fsck") - - packFiles, err := filepath.Glob(filepath.Join(pool.FullPath(), "objects", "pack", "pack-*.pack")) - require.NoError(t, err) - require.Len(t, packFiles, 1, "ensure commits got packed") - - packContents := gittest.Exec(t, cfg, "-C", pool.FullPath(), "verify-pack", "-v", packFiles[0]) - require.Contains(t, string(packContents), repoCommit) - - _, err = client.FetchIntoObjectPool(ctx, req) - require.NoError(t, err, "calling FetchIntoObjectPool twice should be OK") - require.True(t, pool.IsValid(), "ensure that pool is valid") - - // Simulate a broken ref - poolPath, err := locator.GetRepoPath(pool) - require.NoError(t, err) - brokenRef := filepath.Join(poolPath, "refs", "heads", "broken") - require.NoError(t, os.MkdirAll(filepath.Dir(brokenRef), 0o755)) - require.NoError(t, os.WriteFile(brokenRef, []byte{}, 0o777)) - - oldTime := time.Now().Add(-25 * time.Hour) - require.NoError(t, os.Chtimes(brokenRef, oldTime, oldTime)) - - _, err = client.FetchIntoObjectPool(ctx, req) - require.NoError(t, err) - - _, err = os.Stat(brokenRef) - require.Error(t, err, "Expected refs/heads/broken to be deleted") -} - -func TestFetchIntoObjectPool_hooks(t *testing.T) { - cfg := testcfg.Build(t) - gitCmdFactory := gittest.NewCommandFactory(t, cfg, git.WithHooksPath(testhelper.TempDir(t))) - - cfg.SocketPath = runObjectPoolServer(t, cfg, config.NewLocator(cfg), testhelper.NewDiscardingLogger(t), testserver.WithGitCommandFactory(gitCmdFactory)) - - ctx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - conn, err := grpc.Dial(cfg.SocketPath, grpc.WithInsecure()) - require.NoError(t, err) - defer testhelper.MustClose(t, conn) - - client := gitalypb.NewObjectPoolServiceClient(conn) - - pool := initObjectPool(t, cfg, cfg.Storages[0]) - _, err = client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - }) - require.NoError(t, err) - - // Set up a custom reference-transaction hook which simply exits failure. This asserts that - // the RPC doesn't invoke any reference-transaction. - testhelper.WriteExecutable(t, filepath.Join(gitCmdFactory.HooksPath(ctx), "reference-transaction"), []byte("#!/bin/sh\nexit 1\n")) - - req := &gitalypb.FetchIntoObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - Repack: true, - } - - _, err = client.FetchIntoObjectPool(ctx, req) - testhelper.RequireGrpcError(t, status.Error(codes.Internal, "fetch into object pool: exit status 128, stderr: \"fatal: ref updates aborted by hook\\n\""), err) -} - -func TestFetchIntoObjectPool_CollectLogStatistics(t *testing.T) { - cfg := testcfg.Build(t) - - testcfg.BuildGitalyHooks(t, cfg) - - locator := config.NewLocator(cfg) - - logger, hook := test.NewNullLogger() - cfg.SocketPath = runObjectPoolServer(t, cfg, locator, logger) - - ctx := testhelper.Context(t) - ctx = ctxlogrus.ToContext(ctx, log.WithField("test", "logging")) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - conn, err := grpc.Dial(cfg.SocketPath, grpc.WithInsecure()) - require.NoError(t, err) - t.Cleanup(func() { testhelper.MustClose(t, conn) }) - client := gitalypb.NewObjectPoolServiceClient(conn) - - pool := initObjectPool(t, cfg, cfg.Storages[0]) - _, err = client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - }) - require.NoError(t, err) - - req := &gitalypb.FetchIntoObjectPoolRequest{ - ObjectPool: pool.ToProto(), - Origin: repo, - Repack: true, - } - - _, err = client.FetchIntoObjectPool(ctx, req) - require.NoError(t, err) - - const key = "count_objects" - for _, logEntry := range hook.AllEntries() { - if stats, ok := logEntry.Data[key]; ok { - require.IsType(t, map[string]interface{}{}, stats) - - var keys []string - for key := range stats.(map[string]interface{}) { - keys = append(keys, key) - } - - require.ElementsMatch(t, []string{ - "count", - "garbage", - "in-pack", - "packs", - "prune-packable", - "size", - "size-garbage", - "size-pack", - }, keys) - return - } - } - require.FailNow(t, "no info about statistics") -} - -func TestFetchIntoObjectPool_Failure(t *testing.T) { - cfgBuilder := testcfg.NewGitalyCfgBuilder() - cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - - locator := config.NewLocator(cfg) - gitCmdFactory := gittest.NewCommandFactory(t, cfg) - catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) - txManager := transaction.NewManager(cfg, backchannel.NewRegistry()) - - server := NewServer( - locator, - gitCmdFactory, - catfileCache, - txManager, - housekeeping.NewManager(cfg.Prometheus, txManager), - ) - ctx := testhelper.Context(t) - - pool := initObjectPool(t, cfg, cfg.Storages[0]) - - poolWithDifferentStorage := pool.ToProto() - poolWithDifferentStorage.Repository.StorageName = "some other storage" - - testCases := []struct { - description string - request *gitalypb.FetchIntoObjectPoolRequest - code codes.Code - errMsg string - }{ - { - description: "empty origin", - request: &gitalypb.FetchIntoObjectPoolRequest{ - ObjectPool: pool.ToProto(), - }, - code: codes.InvalidArgument, - errMsg: "origin is empty", - }, - { - description: "empty pool", - request: &gitalypb.FetchIntoObjectPoolRequest{ - Origin: repos[0], - }, - code: codes.InvalidArgument, - errMsg: "object pool is empty", - }, - { - description: "origin and pool do not share the same storage", - request: &gitalypb.FetchIntoObjectPoolRequest{ - Origin: repos[0], - ObjectPool: poolWithDifferentStorage, - }, - code: codes.InvalidArgument, - errMsg: "origin has different storage than object pool", - }, - } - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { - _, err := server.FetchIntoObjectPool(ctx, tc.request) - require.Error(t, err) - testhelper.RequireGrpcCode(t, err, tc.code) - assert.Contains(t, err.Error(), tc.errMsg) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick.go deleted file mode 100644 index 801ee93c1b..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick.go +++ /dev/null @@ -1,127 +0,0 @@ -package operations - -import ( - "context" - "errors" - "fmt" - "time" - - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (s *Server) UserCherryPick(ctx context.Context, req *gitalypb.UserCherryPickRequest) (*gitalypb.UserCherryPickResponse, error) { - if err := validateCherryPickOrRevertRequest(req); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "UserCherryPick: %v", err) - } - - quarantineDir, quarantineRepo, err := s.quarantinedRepo(ctx, req.GetRepository()) - if err != nil { - return nil, err - } - - startRevision, err := s.fetchStartRevision(ctx, quarantineRepo, req) - if err != nil { - return nil, err - } - - repoHadBranches, err := quarantineRepo.HasBranches(ctx) - if err != nil { - return nil, err - } - - repoPath, err := quarantineRepo.Path() - if err != nil { - return nil, err - } - - var mainline uint - if len(req.Commit.ParentIds) > 1 { - mainline = 1 - } - - committerDate := time.Now() - if req.Timestamp != nil { - committerDate = req.Timestamp.AsTime() - } - - newrev, err := s.git2goExecutor.CherryPick(ctx, quarantineRepo, git2go.CherryPickCommand{ - Repository: repoPath, - CommitterName: string(req.User.Name), - CommitterMail: string(req.User.Email), - CommitterDate: committerDate, - Message: string(req.Message), - Commit: req.Commit.Id, - Ours: startRevision.String(), - Mainline: mainline, - }) - if err != nil { - switch { - case errors.As(err, &git2go.HasConflictsError{}): - return &gitalypb.UserCherryPickResponse{ - CreateTreeError: err.Error(), - CreateTreeErrorCode: gitalypb.UserCherryPickResponse_CONFLICT, - }, nil - case errors.As(err, &git2go.EmptyError{}): - return &gitalypb.UserCherryPickResponse{ - CreateTreeError: err.Error(), - CreateTreeErrorCode: gitalypb.UserCherryPickResponse_EMPTY, - }, nil - case errors.Is(err, git2go.ErrInvalidArgument): - return nil, helper.ErrInvalidArgument(err) - default: - return nil, helper.ErrInternalf("cherry-pick command: %w", err) - } - } - - referenceName := git.NewReferenceNameFromBranchName(string(req.BranchName)) - - branchCreated := false - oldrev, err := quarantineRepo.ResolveRevision(ctx, referenceName.Revision()+"^{commit}") - if errors.Is(err, git.ErrReferenceNotFound) { - branchCreated = true - oldrev = git.ZeroOID - } else if err != nil { - return nil, helper.ErrInvalidArgumentf("resolve ref: %w", err) - } - - if req.DryRun { - newrev = startRevision - } - - if !branchCreated { - ancestor, err := quarantineRepo.IsAncestor(ctx, oldrev.Revision(), newrev.Revision()) - if err != nil { - return nil, err - } - if !ancestor { - return &gitalypb.UserCherryPickResponse{ - CommitError: "Branch diverged", - }, nil - } - } - - if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, newrev, oldrev); err != nil { - if errors.As(err, &updateref.HookError{}) { - return &gitalypb.UserCherryPickResponse{ - PreReceiveError: err.Error(), - }, nil - } - - return nil, fmt.Errorf("update reference with hooks: %w", err) - } - - return &gitalypb.UserCherryPickResponse{ - BranchUpdate: &gitalypb.OperationBranchUpdate{ - CommitId: newrev.String(), - BranchCreated: branchCreated, - RepoCreated: !repoHadBranches, - }, - }, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags_test.go deleted file mode 100644 index 9018e43458..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags_test.go +++ /dev/null @@ -1,1342 +0,0 @@ -package operations - -import ( - "fmt" - "os" - "path/filepath" - "testing" - "time" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func TestSuccessfulUserDeleteTagRequest(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - tagNameInput := "to-be-deleted-soon-tag" - - gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) - - request := &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte(tagNameInput), - User: gittest.TestUser, - } - - response, err := client.UserDeleteTag(ctx, request) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - - tags := gittest.Exec(t, cfg, "-C", repoPath, "tag") - require.NotContains(t, string(tags), tagNameInput, "tag name still exists in tags list") -} - -func TestSuccessfulGitHooksForUserDeleteTagRequest(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - tagNameInput := "to-be-déleted-soon-tag" - - request := &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte(tagNameInput), - User: gittest.TestUser, - } - - for _, hookName := range GitlabHooks { - t.Run(hookName, func(t *testing.T) { - gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) - - hookOutputTempPath := gittest.WriteEnvToCustomHook(t, repoPath, hookName) - - _, err := client.UserDeleteTag(ctx, request) - require.NoError(t, err) - - output := testhelper.MustReadFile(t, hookOutputTempPath) - require.Contains(t, string(output), "GL_USERNAME="+gittest.TestUser.GlUsername) - }) - } -} - -func writeAssertObjectTypePreReceiveHook(t *testing.T, repoPath, expectedObjectType string) { - t.Helper() - - gittest.WriteCustomHook(t, repoPath, "pre-receive", []byte(fmt.Sprintf( - `#!/usr/bin/env ruby - - # We match a non-ASCII ref_name below - Encoding.default_external = Encoding::UTF_8 - Encoding.default_internal = Encoding::UTF_8 - - expected_object_type = %q - commands = STDIN.each_line.map(&:chomp) - unless commands.size == 1 - abort "expected 1 ref update command, got #{commands.size}" - end - - old_value, new_value, ref_name = commands[0].split(' ', 3) - abort 'missing new_value' unless new_value - - out = IO.popen(%%W[git cat-file -t #{new_value}], &:read) - abort 'cat-file failed' unless $?.success? - - if ref_name =~ /^refs\/[^\/]+\/skip-type-check-/ - exit 0 - end - - unless out.chomp == expected_object_type - abort "pre-receive hook error: expected '#{ref_name}' update of '#{old_value}' (a) -> '#{new_value}' (b) for 'b' to be a '#{expected_object_type}' object, got '#{out}'" - end - `, expectedObjectType))) -} - -func writeAssertObjectTypeUpdateHook(t *testing.T, repoPath, expectedObjectType string) { - t.Helper() - - gittest.WriteCustomHook(t, repoPath, "update", []byte(fmt.Sprintf( - `#!/usr/bin/env ruby - - # We match a non-ASCII ref_name below - Encoding.default_external = Encoding::UTF_8 - Encoding.default_internal = Encoding::UTF_8 - - expected_object_type = %q - ref_name, old_value, new_value = ARGV[0..2] - - abort "missing new_value" unless new_value - - out = IO.popen(%%W[git cat-file -t #{new_value}], &:read) - abort 'cat-file failed' unless $?.success? - - if ref_name =~ /^refs\/[^\/]+\/skip-type-check-/ - exit 0 - end - - unless out.chomp == expected_object_type - abort "update hook error: expected '#{ref_name}' update of '#{old_value}' (a) -> '#{new_value}' (b) for 'b' to be a '#{expected_object_type}' object, got '#{out}'" - end - `, expectedObjectType))) -} - -func TestSuccessfulUserCreateTagRequest(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - targetRevision := "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd" - targetRevisionCommit, err := repo.ReadCommit(ctx, git.Revision(targetRevision)) - require.NoError(t, err) - - inputTagName := "to-be-créated-soon" - - testCases := []struct { - desc string - tagName string - message string - targetRevision string - expectedTag *gitalypb.Tag - expectedObjectType string - }{ - { - desc: "lightweight tag to commit", - tagName: inputTagName, - targetRevision: targetRevision, - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - Id: targetRevision, - TargetCommit: targetRevisionCommit, - }, - expectedObjectType: "commit", - }, - { - desc: "annotated tag to commit", - tagName: inputTagName, - targetRevision: targetRevision, - message: "This is an annotated tag", - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - // Id: is a new object, filled in below - TargetCommit: targetRevisionCommit, - Message: []byte("This is an annotated tag"), - MessageSize: 24, - }, - expectedObjectType: "tag", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - writeAssertObjectTypePreReceiveHook(t, repoPath, testCase.expectedObjectType) - writeAssertObjectTypeUpdateHook(t, repoPath, testCase.expectedObjectType) - - request := &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte(testCase.tagName), - TargetRevision: []byte(testCase.targetRevision), - User: gittest.TestUser, - Message: []byte(testCase.message), - } - - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err, "error from calling RPC") - require.Empty(t, response.PreReceiveError, "PreReceiveError must be empty, signalling the push was accepted") - - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", inputTagName) - - responseOk := &gitalypb.UserCreateTagResponse{ - Tag: testCase.expectedTag, - } - // Fake up *.Id for annotated tags - if len(testCase.expectedTag.Id) == 0 { - id := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", inputTagName) - responseOk.Tag.Id = text.ChompBytes(id) - } - - testhelper.ProtoEqual(t, responseOk, response) - - tag := gittest.Exec(t, cfg, "-C", repoPath, "tag") - require.Contains(t, string(tag), inputTagName) - }) - } -} - -func TestUserCreateTagWithTransaction(t *testing.T) { - t.Parallel() - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - hooksOutputDir := testhelper.TempDir(t) - hooksOutputPath := filepath.Join(hooksOutputDir, "output") - - // We're creating a set of custom hooks which simply - // write to a file. The intention is that we want to - // check that the hooks only run on the primary node. - hooks := []string{"pre-receive", "update", "post-receive"} - for _, hook := range hooks { - gittest.WriteCustomHook(t, repoPath, hook, - []byte(fmt.Sprintf("#!/bin/sh\necho %s >>%s\n", hook, hooksOutputPath)), - ) - } - - // We're creating a custom server with a fake transaction server which - // simply returns success for every call, but tracks the number of - // calls. The server is then injected into the client's context to make - // it available for transactional voting. We cannot use - // runOperationServiceServer as it puts a Praefect server in between if - // running Praefect tests, which would break our test setup. - transactionServer := &testTransactionServer{} - testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterOperationServiceServer(srv, NewServer( - deps.GetHookManager(), - deps.GetTxManager(), - deps.GetLocator(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetUpdaterWithHooks(), - )) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - }) - ctx := testhelper.Context(t) - - // We're using internal gitaly socket to connect to the server. - // This is kind of a hack when running tests with Praefect: - // if we directly connect to the server created above, then our call - // would be intercepted by Praefect, which would in turn replace the - // transaction information we inject further down below. So we instead - // use internal socket so we can circumvent Praefect and just talk - // to Gitaly directly. - client := newMuxedOperationClient(t, ctx, "unix://"+cfg.GitalyInternalSocketPath(), cfg.Auth.Token, - backchannel.NewClientHandshaker( - testhelper.NewDiscardingLogEntry(t), - func() backchannel.Server { - srv := grpc.NewServer() - gitalypb.RegisterRefTransactionServer(srv, transactionServer) - return srv - }, - ), - ) - - for i, testCase := range []struct { - desc string - primary bool - message string - }{ - { - desc: "primary creates a lightweight tag", - primary: true, - }, - { - desc: "secondary creates a lightweight tag", - primary: false, - }, - { - desc: "primary creates an annotated tag", - primary: true, - message: "foobar", - }, - { - desc: "secondary creates an annotated tag", - primary: false, - message: "foobar", - }, - } { - t.Run(testCase.desc, func(t *testing.T) { - *transactionServer = testTransactionServer{} - - if err := os.Remove(hooksOutputPath); err != nil { - require.True(t, os.IsNotExist(err), "error when cleaning up work area: %v", err) - } - - tagName := fmt.Sprintf("tag-%d", i) - targetRevision := "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd" - targetCommit, err := repo.ReadCommit(ctx, git.Revision(targetRevision)) - require.NoError(t, err) - - request := &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte(tagName), - Message: []byte(testCase.message), - TargetRevision: []byte(targetRevision), - User: gittest.TestUser, - } - - // We need to convert to an incoming context first in - // order to preserve the feature flag. - ctx = metadata.OutgoingToIncoming(ctx) - ctx, err = txinfo.InjectTransaction(ctx, 1, "node", testCase.primary) - require.NoError(t, err) - ctx = metadata.IncomingToOutgoing(ctx) - - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err) - - targetOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/tags/"+tagName)) - peeledOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", targetOID+"^{commit}")) - targetOIDOK := targetOID - if len(testCase.message) > 0 { - targetOIDOK = peeledOID - } - require.Equal(t, targetOIDOK, targetRevision) - - testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ - Tag: &gitalypb.Tag{ - Name: []byte(tagName), - Message: []byte(testCase.message), - MessageSize: int64(len(testCase.message)), - Id: targetOID, - TargetCommit: targetCommit, - }, - }, response) - - // Only the primary node should've executed hooks. - if testCase.primary { - contents := testhelper.MustReadFile(t, hooksOutputPath) - require.Equal(t, "pre-receive\nupdate\npost-receive\n", string(contents)) - } else { - require.NoFileExists(t, hooksOutputPath) - } - - require.Equal(t, 2, transactionServer.called) - transactionServer.called = 0 - }) - } -} - -func TestUserCreateTagQuarantine(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - // We set up a custom "pre-receive" hook which simply prints the new tag to stdout and then - // exits with an error. Like this, we can both assert that the hook can see the quarantined - // tag, and it allows us to fail the RPC before we migrate quarantined objects. Furthermore, - // we also try whether we can print the tag's tagged object to assert that we can see - // objects which are not part of the object quarantine. - gittest.WriteCustomHook(t, repoPath, "pre-receive", []byte( - `#!/bin/sh - read oldval newval ref && - git cat-file -p $newval^{commit} >/dev/null && - git cat-file -p $newval^{tag} && - exit 1 - `)) - - response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte("quarantined-tag"), - TargetRevision: []byte("c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd"), - User: gittest.TestUser, - Timestamp: timestamppb.New(time.Unix(1600000000, 0)), - Message: []byte("message"), - }) - require.NoError(t, err) - - // Conveniently, the pre-receive error will now contain output from our custom hook and thus - // the tag's contents. - testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ - PreReceiveError: `object c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd -type commit -tag quarantined-tag -tagger Jane Doe 1600000000 +0800 - -message`, - }, response) - - // In case we use an object quarantine directory, the tag should not exist in the target - // repository because the RPC failed to update the revision. - tagExists, err := repo.HasRevision(ctx, "85d279b2cc85df37992e08f84707987321e8ef47^{tag}") - require.NoError(t, err) - require.False(t, tagExists, "tag should not have been migrated") -} - -func TestSuccessfulUserCreateTagRequestAnnotatedLightweightDisambiguation(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - testCases := []struct { - desc string - message string - objType string - err error - }{ - { - desc: "error: contains null byte", - message: "\000", - err: status.Error(codes.Unknown, "ArgumentError: string contains null byte"), - }, - { - desc: "annotated: some control characters", - message: "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008", - objType: "tag", - }, - { - desc: "lightweight: empty message", - message: "", - objType: "commit", - }, - { - desc: "lightweight: simple whitespace", - message: " \t\t", - objType: "commit", - }, - { - desc: "lightweight: whitespace with newlines", - message: "\t\n\f\r ", - objType: "commit", - }, - { - desc: "lightweight: simple Unicode whitespace", - message: "\u00a0", - objType: "tag", - }, - { - desc: "lightweight: lots of Unicode whitespace", - message: "\u0020\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\ufeff", - objType: "tag", - }, - { - desc: "annotated: dot", - message: ".", - objType: "tag", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - writeAssertObjectTypePreReceiveHook(t, repoPath, testCase.objType) - writeAssertObjectTypeUpdateHook(t, repoPath, testCase.objType) - - tagName := "what-will-it-be" - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(tagName), - TargetRevision: []byte("c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd"), - User: gittest.TestUser, - Message: []byte(testCase.message), - } - - response, err := client.UserCreateTag(ctx, request) - - if testCase.err != nil { - testhelper.RequireGrpcError(t, testCase.err, err) - } else { - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagName) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - } - }) - } -} - -func TestSuccessfulUserCreateTagRequestWithParsedTargetRevision(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - gittest.Exec(t, cfg, "-C", repoPath, "branch", "heads/master", "master~1") - defer gittest.Exec(t, cfg, "-C", repoPath, "branch", "-d", "heads/master") - gittest.Exec(t, cfg, "-C", repoPath, "branch", "refs/heads/master", "master~2") - defer gittest.Exec(t, cfg, "-C", repoPath, "branch", "-d", "refs/heads/master") - - testCases := []struct { - desc string - targetRevision string - expectedRevision string - }{ - { - desc: "tag", - targetRevision: "v1.0.0", - expectedRevision: "refs/tags/v1.0.0", - }, - { - desc: "tag~", - targetRevision: "v1.0.0~", - expectedRevision: "refs/tags/v1.0.0~", - }, - { - desc: "tags/tag~", - targetRevision: "tags/v1.0.0~", - expectedRevision: "refs/tags/v1.0.0~", - }, - { - desc: "refs/tag~", - targetRevision: "refs/tags/v1.0.0~", - expectedRevision: "refs/tags/v1.0.0~", - }, - { - desc: "master", - targetRevision: "master", - expectedRevision: "master", - }, - { - desc: "heads/master", - targetRevision: "heads/master", - expectedRevision: "refs/heads/heads/master", - }, - { - desc: "refs/heads/master", - targetRevision: "refs/heads/master", - expectedRevision: "refs/heads/master", - }, - { - desc: "heads/refs/heads/master", - targetRevision: "heads/refs/heads/master", - expectedRevision: "refs/heads/refs/heads/master", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - tagName := "what-will-it-be" - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(tagName), - TargetRevision: []byte(testCase.targetRevision), - User: gittest.TestUser, - } - - response, err := client.UserCreateTag(ctx, request) - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagName) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - - parsedID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagName) - require.Equal(t, text.ChompBytes(parsedID), response.Tag.TargetCommit.Id) - }) - } -} - -func TestSuccessfulUserCreateTagRequestToNonCommit(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - inputTagName := "to-be-créated-soon" - - testCases := []struct { - desc string - tagName string - message string - targetRevision string - expectedTag *gitalypb.Tag - expectedObjectType string - }{ - { - desc: "lightweight tag to tree", - tagName: inputTagName, - targetRevision: "612036fac47c5d31c212b17268e2f3ba807bce1e", - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - Id: "612036fac47c5d31c212b17268e2f3ba807bce1e", - }, - expectedObjectType: "tree", - }, - { - desc: "lightweight tag to blob", - tagName: inputTagName, - targetRevision: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - Id: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - }, - expectedObjectType: "blob", - }, - { - desc: "annotated tag to tree", - tagName: inputTagName, - targetRevision: "612036fac47c5d31c212b17268e2f3ba807bce1e", - message: "This is an annotated tag", - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - // Id: is a new object, filled in below - TargetCommit: nil, - Message: []byte("This is an annotated tag"), - MessageSize: 24, - }, - expectedObjectType: "tag", - }, - { - desc: "annotated tag to blob", - tagName: inputTagName, - targetRevision: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - message: "This is an annotated tag", - expectedTag: &gitalypb.Tag{ - Name: []byte(inputTagName), - // Id: is a new object, filled in below - TargetCommit: nil, - Message: []byte("This is an annotated tag"), - MessageSize: 24, - }, - expectedObjectType: "tag", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - writeAssertObjectTypePreReceiveHook(t, repoPath, testCase.expectedObjectType) - writeAssertObjectTypeUpdateHook(t, repoPath, testCase.expectedObjectType) - - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(testCase.tagName), - TargetRevision: []byte(testCase.targetRevision), - User: gittest.TestUser, - Message: []byte(testCase.message), - } - - responseOk := &gitalypb.UserCreateTagResponse{ - Tag: testCase.expectedTag, - } - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", inputTagName) - - // Fake up *.Id for annotated tags - if len(testCase.expectedTag.Id) == 0 { - tagID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", inputTagName) - responseOk.Tag.Id = text.ChompBytes(tagID) - } - testhelper.ProtoEqual(t, responseOk, response) - - peeledID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", inputTagName+"^{}") - require.Equal(t, testCase.targetRevision, text.ChompBytes(peeledID)) - - objectType := gittest.Exec(t, cfg, "-C", repoPath, "cat-file", "-t", inputTagName) - require.Equal(t, testCase.expectedObjectType, text.ChompBytes(objectType)) - }) - } -} - -func TestSuccessfulUserCreateTagNestedTags(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - testCases := []struct { - desc string - targetObject string - targetObjectType string - expectedTag *gitalypb.Tag - }{ - { - desc: "nested tags to commit", - targetObject: "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", - targetObjectType: "commit", - }, - { - desc: "nested tags to tree", - targetObjectType: "tree", - targetObject: "612036fac47c5d31c212b17268e2f3ba807bce1e", - }, - { - desc: "nested tags to blob", - targetObject: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", - targetObjectType: "blob", - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - // We resolve down to commit/tree/blob, but we'll only ever push a "tag" - // here. - writeAssertObjectTypePreReceiveHook(t, repoPath, "tag") - writeAssertObjectTypeUpdateHook(t, repoPath, "tag") - - targetObject := testCase.targetObject - nestLevel := 2 - for i := 0; i <= nestLevel; i++ { - tagName := fmt.Sprintf("nested-tag-%v", i) - tagMessage := fmt.Sprintf("This is level %v of a nested annotated tag to %v", i, testCase.targetObject) - request := &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte(tagName), - TargetRevision: []byte(targetObject), - User: gittest.TestUser, - Message: []byte(tagMessage), - } - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagName) - - createdID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagName) - createdIDStr := text.ChompBytes(createdID) - responseOk := &gitalypb.UserCreateTagResponse{ - Tag: &gitalypb.Tag{ - Name: request.TagName, - Id: createdIDStr, - // TargetCommit: is dymamically determined, filled in below - Message: request.Message, - MessageSize: int64(len(request.Message)), - }, - } - // Fake it up for all levels, except for ^{} == "commit" - responseOk.Tag.TargetCommit = response.Tag.TargetCommit - if testCase.targetObjectType == "commit" { - responseOk.Tag.TargetCommit, err = repo.ReadCommit(ctx, git.Revision(testCase.targetObject)) - require.NoError(t, err) - } - testhelper.ProtoEqual(t, responseOk, response) - - peeledID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagName+"^{}") - peeledIDStr := text.ChompBytes(peeledID) - require.Equal(t, testCase.targetObject, peeledIDStr) - - // Set up the next level of nesting... - targetObject = response.Tag.Id - - // Create a *lightweight* tag pointing - // to our N-level - // tag->[commit|tree|blob]. The "tag" - // field name will not match the tag - // name. - tagNameLight := fmt.Sprintf("skip-type-check-light-%s", tagName) - request = &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte(tagNameLight), - TargetRevision: []byte(createdIDStr), - User: gittest.TestUser, - } - response, err = client.UserCreateTag(ctx, request) - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameLight) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - - responseOk = &gitalypb.UserCreateTagResponse{ - Tag: &gitalypb.Tag{ - Name: request.TagName, - Id: testCase.targetObject, - TargetCommit: responseOk.Tag.TargetCommit, - Message: nil, - MessageSize: 0, - }, - } - testhelper.ProtoEqual(t, responseOk, response) - - createdIDLight := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagNameLight) - createdIDLightStr := text.ChompBytes(createdIDLight) - require.Equal(t, testCase.targetObject, createdIDLightStr) - } - }) - } -} - -func TestUserCreateTagStableTagIDs(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, _, repo, _, client := setupOperationsService(t, ctx) - - response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte("happy-tag"), - TargetRevision: []byte("dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82"), - Message: []byte("my message"), - User: gittest.TestUser, - Timestamp: ×tamppb.Timestamp{Seconds: 12345}, - }) - require.NoError(t, err) - - require.Equal(t, &gitalypb.Tag{ - Id: "123b02f05cc249a7da87aae583babb8e4871cd65", - Name: []byte("happy-tag"), - Message: []byte("my message"), - MessageSize: 10, - }, response.Tag) -} - -func TestUserDeleteTagSuccessfulDeletionOfPrefixedTag(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - testCases := []struct { - desc string - tagNameInput string - tagCommit string - user *gitalypb.User - response *gitalypb.UserDeleteTagResponse - err error - }{ - { - desc: "possible to delete a tag called refs/tags/something", - tagNameInput: "refs/tags/can-find-this", - tagCommit: "c642fe9b8b9f28f9225d7ea953fe14e74748d53b", - user: gittest.TestUser, - response: &gitalypb.UserDeleteTagResponse{}, - err: nil, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - gittest.Exec(t, cfg, "-C", repoPath, "tag", testCase.tagNameInput, testCase.tagCommit) - - request := &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte(testCase.tagNameInput), - User: testCase.user, - } - - response, err := client.UserDeleteTag(ctx, request) - testhelper.RequireGrpcError(t, testCase.err, err) - testhelper.ProtoEqual(t, testCase.response, response) - - refs := gittest.Exec(t, cfg, "-C", repoPath, "for-each-ref", "--", "refs/tags/"+testCase.tagNameInput) - require.NotContains(t, string(refs), testCase.tagCommit, "tag kept because we stripped off refs/tags/*") - }) - } -} - -func TestUserCreateTagsuccessfulCreationOfPrefixedTag(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - testCases := []struct { - desc string - tagNameInput string - tagTargetRevisionInput string - user *gitalypb.User - err error - }{ - { - desc: "possible to create a tag called refs/tags/something", - tagNameInput: "refs/tags/can-create-this", - tagTargetRevisionInput: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", - user: gittest.TestUser, - err: nil, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", testCase.tagNameInput) - - request := &gitalypb.UserCreateTagRequest{ - Repository: repoProto, - TagName: []byte(testCase.tagNameInput), - TargetRevision: []byte(testCase.tagTargetRevisionInput), - User: testCase.user, - } - - response, err := client.UserCreateTag(ctx, request) - testhelper.RequireGrpcError(t, testCase.err, err) - commitOk, err := repo.ReadCommit(ctx, git.Revision(testCase.tagTargetRevisionInput)) - require.NoError(t, err) - - responseOk := &gitalypb.UserCreateTagResponse{ - Tag: &gitalypb.Tag{ - Name: []byte(testCase.tagNameInput), - Id: testCase.tagTargetRevisionInput, - TargetCommit: commitOk, - }, - } - - testhelper.ProtoEqual(t, responseOk, response) - - refs := gittest.Exec(t, cfg, "-C", repoPath, "for-each-ref", "--", "refs/tags/"+testCase.tagNameInput) - require.Contains(t, string(refs), testCase.tagTargetRevisionInput, "tag created, we did not strip off refs/tags/*") - }) - } -} - -func TestSuccessfulGitHooksForUserCreateTagRequest(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - projectPath := "project/path" - repo.GlProjectPath = projectPath - - tagName := "new-tag" - - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(tagName), - TargetRevision: []byte("c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd"), - User: gittest.TestUser, - } - - for _, hookName := range GitlabHooks { - t.Run(hookName, func(t *testing.T) { - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagName) - - hookOutputTempPath := gittest.WriteEnvToCustomHook(t, repoPath, hookName) - - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err) - require.Empty(t, response.PreReceiveError) - - output := string(testhelper.MustReadFile(t, hookOutputTempPath)) - require.Contains(t, output, "GL_USERNAME="+gittest.TestUser.GlUsername) - require.Contains(t, output, "GL_PROJECT_PATH="+projectPath) - }) - } -} - -func TestFailedUserDeleteTagRequestDueToValidation(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, _, repo, _, client := setupOperationsService(t, ctx) - - testCases := []struct { - desc string - request *gitalypb.UserDeleteTagRequest - response *gitalypb.UserDeleteTagResponse - err error - }{ - { - desc: "empty user", - request: &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte("does-matter-the-name-if-user-is-empty"), - }, - response: nil, - err: status.Error(codes.InvalidArgument, "empty user"), - }, - { - desc: "empty tag name", - request: &gitalypb.UserDeleteTagRequest{ - Repository: repo, - User: gittest.TestUser, - }, - response: nil, - err: status.Error(codes.InvalidArgument, "empty tag name"), - }, - { - desc: "non-existent tag name", - request: &gitalypb.UserDeleteTagRequest{ - Repository: repo, - User: gittest.TestUser, - TagName: []byte("i-do-not-exist"), - }, - response: nil, - err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "i-do-not-exist"), - }, - { - desc: "space in tag name", - request: &gitalypb.UserDeleteTagRequest{ - Repository: repo, - User: gittest.TestUser, - TagName: []byte("a tag"), - }, - response: nil, - err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a tag"), - }, - { - desc: "newline in tag name", - request: &gitalypb.UserDeleteTagRequest{ - Repository: repo, - User: gittest.TestUser, - TagName: []byte("a\ntag"), - }, - response: nil, - err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a\ntag"), - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - response, err := client.UserDeleteTag(ctx, testCase.request) - testhelper.RequireGrpcError(t, testCase.err, err) - testhelper.ProtoEqual(t, testCase.response, response) - }) - } -} - -func TestFailedUserDeleteTagDueToHooks(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - tagNameInput := "to-be-deleted-soon-tag" - gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameInput) - - request := &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte(tagNameInput), - User: gittest.TestUser, - } - - hookContent := []byte("#!/bin/sh\necho GL_ID=$GL_ID\nexit 1") - - for _, hookName := range gitlabPreHooks { - t.Run(hookName, func(t *testing.T) { - gittest.WriteCustomHook(t, repoPath, hookName, hookContent) - - response, err := client.UserDeleteTag(ctx, request) - require.NoError(t, err) - require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) - - tags := gittest.Exec(t, cfg, "-C", repoPath, "tag") - require.Contains(t, string(tags), tagNameInput, "tag name does not exist in tags list") - }) - } -} - -func TestFailedUserCreateTagDueToHooks(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, _, repo, repoPath, client := setupOperationsService(t, ctx) - - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte("new-tag"), - TargetRevision: []byte("c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd"), - User: gittest.TestUser, - } - - hookContent := []byte("#!/bin/sh\necho GL_ID=$GL_ID\nexit 1") - - for _, hookName := range gitlabPreHooks { - gittest.WriteCustomHook(t, repoPath, hookName, hookContent) - - response, err := client.UserCreateTag(ctx, request) - require.NoError(t, err) - require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) - } -} - -func TestFailedUserCreateTagRequestDueToTagExistence(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, _, repo, _, client := setupOperationsService(t, ctx) - - testCases := []struct { - desc string - tagName string - targetRevision string - user *gitalypb.User - response *gitalypb.UserCreateTagResponse - err error - }{ - { - desc: "simple existing tag", - tagName: "v1.1.0", - targetRevision: "master", - user: gittest.TestUser, - response: &gitalypb.UserCreateTagResponse{ - Tag: nil, - Exists: true, - }, - err: nil, - }, - { - desc: "existing tag nonexisting target revision", - tagName: "v1.1.0", - targetRevision: "does-not-exist", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.FailedPrecondition, "revspec '%s' not found", "does-not-exist"), - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(testCase.tagName), - TargetRevision: []byte(testCase.targetRevision), - User: testCase.user, - } - - response, err := client.UserCreateTag(ctx, request) - testhelper.RequireGrpcError(t, testCase.err, err) - testhelper.ProtoEqual(t, testCase.response, response) - }) - } -} - -func TestFailedUserCreateTagRequestDueToValidation(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, _, repo, _, client := setupOperationsService(t, ctx) - - injectedTag := "inject-tag\ntagger . <> 0 +0000\n\nInjected subject\n\n" - testCases := []struct { - desc string - tagName string - targetRevision string - message string - user *gitalypb.User - response *gitalypb.UserCreateTagResponse - err error - }{ - { - desc: "empty target revision", - tagName: "shiny-new-tag", - targetRevision: "", - user: gittest.TestUser, - response: nil, - err: status.Error(codes.InvalidArgument, "empty target revision"), - }, - { - desc: "empty user", - tagName: "shiny-new-tag", - targetRevision: "master", - user: nil, - response: nil, - err: status.Error(codes.InvalidArgument, "empty user"), - }, - { - desc: "empty starting point", - tagName: "new-tag", - targetRevision: "", - user: gittest.TestUser, - response: nil, - err: status.Error(codes.InvalidArgument, "empty target revision"), - }, - { - desc: "non-existing starting point", - tagName: "new-tag", - targetRevision: "i-dont-exist", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.FailedPrecondition, "revspec '%s' not found", "i-dont-exist"), - }, - { - desc: "space in lightweight tag name", - tagName: "a tag", - targetRevision: "master", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", "a tag"), - }, - { - desc: "space in annotated tag name", - tagName: "a tag", - targetRevision: "master", - message: "a message", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", "a tag"), - }, - { - desc: "newline in lightweight tag name", - tagName: "a\ntag", - targetRevision: "master", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", "a\ntag"), - }, - { - desc: "newline in annotated tag name", - tagName: "a\ntag", - targetRevision: "master", - message: "a message", - user: gittest.TestUser, - response: nil, - err: status.Error(codes.Unknown, "Rugged::InvalidError: failed to parse signature - expected prefix doesn't match actual"), - }, - { - desc: "injection in lightweight tag name", - tagName: injectedTag, - targetRevision: "master", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", injectedTag), - }, - { - desc: "injection in annotated tag name", - tagName: injectedTag, - targetRevision: "master", - message: "a message", - user: gittest.TestUser, - response: nil, - err: status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", injectedTag), - }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - request := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(testCase.tagName), - TargetRevision: []byte(testCase.targetRevision), - User: testCase.user, - Message: []byte(testCase.message), - } - - response, err := client.UserCreateTag(ctx, request) - testhelper.RequireGrpcError(t, testCase.err, err) - testhelper.ProtoEqual(t, testCase.response, response) - }) - } -} - -func TestTagHookOutput(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - - testCases := []struct { - desc string - hookContent string - output func(hookPath string) string - }{ - { - desc: "empty stdout and empty stderr", - hookContent: "#!/bin/sh\nexit 1", - output: func(hookPath string) string { - return fmt.Sprintf("executing custom hooks: error executing %q: exit status 1", hookPath) - }, - }, - { - desc: "empty stdout and some stderr", - hookContent: "#!/bin/sh\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, - }, - { - desc: "some stdout and empty stderr", - hookContent: "#!/bin/sh\necho stdout\nexit 1", - output: func(string) string { return "stdout\n" }, - }, - { - desc: "some stdout and some stderr", - hookContent: "#!/bin/sh\necho stdout\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, - }, - { - desc: "whitespace stdout and some stderr", - hookContent: "#!/bin/sh\necho ' '\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, - }, - { - desc: "some stdout and whitespace stderr", - hookContent: "#!/bin/sh\necho stdout\necho ' ' >&2\nexit 1", - output: func(string) string { return "stdout\n" }, - }, - } - - for _, hookName := range gitlabPreHooks { - for _, testCase := range testCases { - t.Run(hookName+"/"+testCase.desc, func(t *testing.T) { - tagNameInput := "some-tag" - createRequest := &gitalypb.UserCreateTagRequest{ - Repository: repo, - TagName: []byte(tagNameInput), - TargetRevision: []byte("master"), - User: gittest.TestUser, - } - deleteRequest := &gitalypb.UserDeleteTagRequest{ - Repository: repo, - TagName: []byte(tagNameInput), - User: gittest.TestUser, - } - - hookFilename := gittest.WriteCustomHook(t, repoPath, hookName, []byte(testCase.hookContent)) - expectedError := testCase.output(hookFilename) - - createResponse, err := client.UserCreateTag(ctx, createRequest) - require.NoError(t, err) - - createResponseOk := &gitalypb.UserCreateTagResponse{ - Tag: createResponse.Tag, - Exists: false, - PreReceiveError: expectedError, - } - testhelper.ProtoEqual(t, createResponseOk, createResponse) - - defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameInput) - gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) - - deleteResponse, err := client.UserDeleteTag(ctx, deleteRequest) - require.NoError(t, err) - deleteResponseOk := &gitalypb.UserDeleteTagResponse{ - PreReceiveError: expectedError, - } - testhelper.ProtoEqual(t, deleteResponseOk, deleteResponse) - }) - } - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath.go deleted file mode 100644 index d2fdbe86d8..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath.go +++ /dev/null @@ -1,33 +0,0 @@ -package repository - -import ( - "context" - - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -const fullPathKey = "gitlab.fullpath" - -// SetFullPath writes the provided path value into the repository's gitconfig under the -// "gitlab.fullpath" key. -func (s *server) SetFullPath( - ctx context.Context, - request *gitalypb.SetFullPathRequest, -) (*gitalypb.SetFullPathResponse, error) { - if request.GetRepository() == nil { - return nil, helper.ErrInvalidArgumentf("empty Repository") - } - - if len(request.GetPath()) == 0 { - return nil, helper.ErrInvalidArgumentf("no path provided") - } - - repo := s.localrepo(request.GetRepository()) - - if err := repo.SetConfig(ctx, fullPathKey, request.GetPath(), s.txManager); err != nil { - return nil, helper.ErrInternalf("setting config: %w", err) - } - - return &gitalypb.SetFullPathResponse{}, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license.go deleted file mode 100644 index ef798ce4b3..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license.go +++ /dev/null @@ -1,162 +0,0 @@ -package repository - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "regexp" - "strings" - - "github.com/go-enry/go-license-detector/v4/licensedb" - "github.com/go-enry/go-license-detector/v4/licensedb/filer" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func (s *server) FindLicense(ctx context.Context, req *gitalypb.FindLicenseRequest) (*gitalypb.FindLicenseResponse, error) { - if featureflag.GoFindLicense.IsEnabled(ctx) { - repo := localrepo.New(s.locator, s.gitCmdFactory, s.catfileCache, req.GetRepository()) - - hasHeadRevision, err := repo.HasRevision(ctx, "HEAD") - if err != nil { - return nil, helper.ErrInternalf("cannot check HEAD revision: %v", err) - } - if !hasHeadRevision { - return &gitalypb.FindLicenseResponse{}, nil - } - - repoFiler := &gitFiler{ctx, repo, false} - - licenses, err := licensedb.Detect(repoFiler) - if err != nil { - if errors.Is(err, licensedb.ErrNoLicenseFound) { - licenseShortName := "" - if repoFiler.foundLicense { - // The Ruby implementation of FindLicense returned 'other' when a license file - // was found and '' when no license file was found. `Detect` method returns ErrNoLicenseFound - // if it doesn't identify the license. To retain backwards compatibility, the repoFiler records - // whether it encountered any license files. That information is used here to then determine that - // we need to send back 'other'. - licenseShortName = "other" - } - - return &gitalypb.FindLicenseResponse{LicenseShortName: licenseShortName}, nil - } - return nil, helper.ErrInternal(fmt.Errorf("FindLicense: Err: %w", err)) - } - - var result string - var bestConfidence float32 - for candidate, match := range licenses { - if match.Confidence > bestConfidence { - result = candidate - bestConfidence = match.Confidence - } - } - - return &gitalypb.FindLicenseResponse{LicenseShortName: strings.ToLower(result)}, nil - } - - client, err := s.ruby.RepositoryServiceClient(ctx) - if err != nil { - return nil, err - } - clientCtx, err := rubyserver.SetHeaders(ctx, s.locator, req.GetRepository()) - if err != nil { - return nil, err - } - return client.FindLicense(clientCtx, req) -} - -var readmeRegexp = regexp.MustCompile(`(readme|guidelines)(\.md|\.rst|\.html|\.txt)?$`) - -type gitFiler struct { - ctx context.Context - repo *localrepo.Repo - foundLicense bool -} - -func (f *gitFiler) ReadFile(path string) ([]byte, error) { - var stdout, stderr bytes.Buffer - if err := f.repo.ExecAndWait(f.ctx, git.SubCmd{ - Name: "cat-file", - Args: []string{"blob", fmt.Sprintf("HEAD:%s", path)}, - }, git.WithStdout(&stdout), git.WithStderr(&stderr)); err != nil { - return nil, fmt.Errorf("cat-file failed: %w, stderr: %q", err, stderr.String()) - } - - // `licensedb.Detect` only opens files that look like licenses. Failing that, it will - // also open readme files to try to identify license files. The RPC handler needs the - // knowledge of whether any license files were encountered, so we filter out the - // readme files as defined in licensedb.Detect: - // https://github.com/go-enry/go-license-detector/blob/4f2ca6af2ab943d9b5fa3a02782eebc06f79a5f4/licensedb/internal/investigation.go#L61 - // - // This doesn't filter out the possible license files identified from the readme files which may infact not - // be licenses. - if !f.foundLicense { - f.foundLicense = !readmeRegexp.MatchString(strings.ToLower(path)) - } - - return stdout.Bytes(), nil -} - -func (f *gitFiler) ReadDir(string) ([]filer.File, error) { - // We're doing a recursive listing returning all files at once such that we do not have to - // call git-ls-tree(1) multiple times. - var stderr bytes.Buffer - cmd, err := f.repo.Exec(f.ctx, git.SubCmd{ - Name: "ls-tree", - Flags: []git.Option{ - git.Flag{Name: "--full-tree"}, - git.Flag{Name: "-z"}, - }, - Args: []string{"HEAD"}, - }, git.WithStderr(&stderr)) - if err != nil { - return nil, err - } - - tree := lstree.NewParser(cmd) - - var files []filer.File - for { - entry, err := tree.NextEntry() - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - - // Given that we're doing a recursive listing, we skip over all types which aren't - // blobs. - if entry.Type != lstree.Blob { - continue - } - - files = append(files, filer.File{ - Name: entry.Path, - IsDir: false, - }) - } - - if err := cmd.Wait(); err != nil { - return nil, fmt.Errorf("ls-tree failed: %w, stderr: %q", err, stderr.String()) - } - - return files, nil -} - -func (f *gitFiler) Close() {} - -func (f *gitFiler) PathsAreAlwaysSlash() bool { - // git ls-files uses unix slash `/` - return true -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license_test.go deleted file mode 100644 index bb24c93a58..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/license_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package repository - -import ( - "context" - "os" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func testSuccessfulFindLicenseRequest(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { - testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { - for _, tc := range []struct { - desc string - nonExistentRepository bool - files map[string]string - expectedLicense string - errorContains string - }{ - { - desc: "repository does not exist", - nonExistentRepository: true, - errorContains: "rpc error: code = NotFound desc = GetRepoPath: not a git repository", - }, - { - desc: "empty if no license file in repo", - files: map[string]string{ - "README.md": "readme content", - }, - expectedLicense: "", - }, - { - desc: "high confidence mit result and less confident mit-0 result", - files: map[string]string{ - "LICENSE": `MIT License - -Copyright (c) [year] [fullname] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.`, - }, - expectedLicense: "mit", - }, - { - desc: "unknown license", - files: map[string]string{ - "LICENSE.md": "this doesn't match any known license", - }, - expectedLicense: "other", - }, - } { - t.Run(tc.desc, func(t *testing.T) { - repo, repoPath := gittest.CreateRepository(ctx, t, cfg) - - var treeEntries []gittest.TreeEntry - for file, content := range tc.files { - treeEntries = append(treeEntries, gittest.TreeEntry{ - Mode: "100644", - Path: file, - Content: content, - }) - } - - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithTreeEntries(treeEntries...), gittest.WithParents()) - - if tc.nonExistentRepository { - require.NoError(t, os.RemoveAll(repoPath)) - } - - resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) - if tc.errorContains != "" { - require.Error(t, err) - require.Contains(t, err.Error(), tc.errorContains) - return - } - - require.NoError(t, err) - testhelper.ProtoEqual(t, &gitalypb.FindLicenseResponse{ - LicenseShortName: tc.expectedLicense, - }, resp) - }) - } - }) -} - -func testFindLicenseRequestEmptyRepo(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { - testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { - repo, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) - require.NoError(t, os.RemoveAll(repoPath)) - - _, err := client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{Repository: repo}) - require.NoError(t, err) - - resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) - require.NoError(t, err) - - require.Empty(t, resp.GetLicenseShortName()) - }) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size.go deleted file mode 100644 index 4d43dc2b19..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size.go +++ /dev/null @@ -1,82 +0,0 @@ -package repository - -import ( - "bytes" - "context" - "fmt" - "io" - "os/exec" - "strconv" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func (s *server) RepositorySize(ctx context.Context, in *gitalypb.RepositorySizeRequest) (*gitalypb.RepositorySizeResponse, error) { - repo := s.localrepo(in.GetRepository()) - var size int64 - var err error - - if featureflag.RevlistForRepoSize.IsEnabled(ctx) { - size, err = repo.Size(ctx) - if err != nil { - return nil, err - } - // return the size in kb to remain consistent - size = size / 1024 - } else { - path, err := repo.Path() - if err != nil { - return nil, err - } - size = getPathSize(ctx, path) - } - - return &gitalypb.RepositorySizeResponse{Size: size}, nil -} - -func (s *server) GetObjectDirectorySize(ctx context.Context, in *gitalypb.GetObjectDirectorySizeRequest) (*gitalypb.GetObjectDirectorySizeResponse, error) { - repo := s.localrepo(in.GetRepository()) - - path, err := repo.ObjectDirectoryPath() - if err != nil { - return nil, err - } - - return &gitalypb.GetObjectDirectorySizeResponse{Size: getPathSize(ctx, path)}, nil -} - -func getPathSize(ctx context.Context, path string) int64 { - cmd, err := command.New(ctx, exec.Command("du", "-sk", path), nil, nil, nil) - if err != nil { - ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring du command error") - return 0 - } - - sizeLine, err := io.ReadAll(cmd) - if err != nil { - ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring command read error") - return 0 - } - - if err := cmd.Wait(); err != nil { - ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring du wait error") - return 0 - } - - sizeParts := bytes.Split(sizeLine, []byte("\t")) - if len(sizeParts) != 2 { - ctxlogrus.Extract(ctx).Warn(fmt.Sprintf("ignoring du malformed output: %q", sizeLine)) - return 0 - } - - size, err := strconv.ParseInt(string(sizeParts[0]), 10, 0) - if err != nil { - ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring parsing size error") - return 0 - } - - return size -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref_test.go deleted file mode 100644 index 5e3b7f92af..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref_test.go +++ /dev/null @@ -1,158 +0,0 @@ -package repository - -import ( - "bytes" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" -) - -func TestWriteRefSuccessful(t *testing.T) { - txManager := transaction.NewTrackingManager() - cfg, repo, repoPath, client := setupRepositoryService(testhelper.Context(t), t, testserver.WithTransactionManager(txManager)) - - testCases := []struct { - desc string - req *gitalypb.WriteRefRequest - expectedVotes int - }{ - { - desc: "shell update HEAD to refs/heads/master", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("HEAD"), - Revision: []byte("refs/heads/master"), - }, - expectedVotes: 2, - }, - { - desc: "shell update refs/heads/master", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads/master"), - Revision: []byte("b83d6e391c22777fca1ed3012fce84f633d7fed0"), - }, - expectedVotes: 2, - }, - { - desc: "shell update refs/heads/master w/ validation", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads/master"), - Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), - OldRevision: []byte("b83d6e391c22777fca1ed3012fce84f633d7fed0"), - }, - expectedVotes: 2, - }, - } - - ctx, err := txinfo.InjectTransaction(testhelper.Context(t), 1, "node", true) - require.NoError(t, err) - ctx = metadata.IncomingToOutgoing(ctx) - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - txManager.Reset() - _, err = client.WriteRef(ctx, tc.req) - require.NoError(t, err) - - require.Len(t, txManager.Votes(), tc.expectedVotes) - - if bytes.Equal(tc.req.Ref, []byte("HEAD")) { - content := testhelper.MustReadFile(t, filepath.Join(repoPath, "HEAD")) - - refRevision := bytes.Join([][]byte{[]byte("ref: "), tc.req.Revision, []byte("\n")}, nil) - - require.EqualValues(t, refRevision, content) - return - } - rev := gittest.Exec(t, cfg, "--git-dir", repoPath, "log", "--pretty=%H", "-1", string(tc.req.Ref)) - - rev = bytes.Replace(rev, []byte("\n"), nil, 1) - - require.Equal(t, string(tc.req.Revision), string(rev)) - }) - } -} - -func TestWriteRefValidationError(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupRepositoryService(ctx, t) - - testCases := []struct { - desc string - req *gitalypb.WriteRefRequest - }{ - { - desc: "empty revision", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads/master"), - }, - }, - { - desc: "empty ref name", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), - }, - }, - { - desc: "non-prefixed ref name for shell", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("master"), - Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), - }, - }, - { - desc: "revision contains \\x00", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads/master"), - Revision: []byte("012301230123\x001243"), - }, - }, - { - desc: "ref contains \\x00", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/head\x00s/master\x00"), - Revision: []byte("0123012301231243"), - }, - }, - { - desc: "ref contains whitespace", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads /master"), - Revision: []byte("0123012301231243"), - }, - }, - { - desc: "invalid revision", - req: &gitalypb.WriteRefRequest{ - Repository: repo, - Ref: []byte("refs/heads/master"), - Revision: []byte("--output=/meow"), - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := client.WriteRef(ctx, tc.req) - - testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/clocksynced.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/clocksynced.go deleted file mode 100644 index 2ce1120964..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/clocksynced.go +++ /dev/null @@ -1,17 +0,0 @@ -package server - -import ( - "context" - "time" - - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func (s *server) ClockSynced(_ context.Context, req *gitalypb.ClockSyncedRequest) (*gitalypb.ClockSyncedResponse, error) { - synced, err := helper.CheckClockSync(req.NtpHost, time.Duration(req.DriftThresholdMillis*int64(time.Millisecond))) - if err != nil { - return nil, err - } - return &gitalypb.ClockSyncedResponse{Synced: synced}, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/testhelper_test.go deleted file mode 100644 index 736a4b9604..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/testhelper_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package ssh - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -func runSSHServer(t *testing.T, cfg config.Cfg, serverOpts ...testserver.GitalyServerOpt) string { - return runSSHServerWithOptions(t, cfg, nil, serverOpts...) -} - -func runSSHServerWithOptions(t *testing.T, cfg config.Cfg, opts []ServerOpt, serverOpts ...testserver.GitalyServerOpt) string { - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterSSHServiceServer(srv, NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - opts...)) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( - cfg, - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }, serverOpts...) -} - -func newSSHClient(t *testing.T, serverSocketPath string) (gitalypb.SSHServiceClient, *grpc.ClientConn) { - connOpts := []grpc.DialOption{ - grpc.WithInsecure(), - } - conn, err := grpc.Dial(serverSocketPath, connOpts...) - if err != nil { - t.Fatal(err) - } - - return gitalypb.NewSSHServiceClient(conn), conn -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack_test.go deleted file mode 100644 index e560cdf0d3..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack_test.go +++ /dev/null @@ -1,668 +0,0 @@ -package ssh - -import ( - "bytes" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/prometheus/client_golang/prometheus" - promtest "github.com/prometheus/client_golang/prometheus/testutil" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" - "google.golang.org/protobuf/encoding/protojson" -) - -type cloneCommand struct { - command git.Cmd - repository *gitalypb.Repository - server string - featureFlags []string - gitConfig string - gitProtocol string - cfg config.Cfg - sidechannel bool -} - -func runTestWithAndWithoutConfigOptions(t *testing.T, tf func(t *testing.T, opts ...testcfg.Option), opts ...testcfg.Option) { - t.Run("no config options", func(t *testing.T) { tf(t) }) - - if len(opts) > 0 { - t.Run("with config options", func(t *testing.T) { - tf(t, opts...) - }) - } -} - -func (cmd cloneCommand) execute(t *testing.T) error { - req := &gitalypb.SSHUploadPackRequest{ - Repository: cmd.repository, - GitProtocol: cmd.gitProtocol, - } - if cmd.gitConfig != "" { - req.GitConfigOptions = strings.Split(cmd.gitConfig, " ") - } - payload, err := protojson.Marshal(req) - require.NoError(t, err) - - var flagPairs []string - for _, flag := range cmd.featureFlags { - flagPairs = append(flagPairs, fmt.Sprintf("%s:true", flag)) - } - ctx := testhelper.Context(t) - - env := []string{ - fmt.Sprintf("GITALY_ADDRESS=%s", cmd.server), - fmt.Sprintf("GITALY_PAYLOAD=%s", payload), - fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(flagPairs, ",")), - fmt.Sprintf("PATH=.:%s", os.Getenv("PATH")), - fmt.Sprintf(`GIT_SSH_COMMAND=%s upload-pack`, filepath.Join(cmd.cfg.BinDir, "gitaly-ssh")), - } - if cmd.sidechannel { - env = append(env, "GITALY_USE_SIDECHANNEL=1") - } - - var output bytes.Buffer - gitCommand, err := gittest.NewCommandFactory(t, cmd.cfg).NewWithoutRepo(ctx, - cmd.command, git.WithStdout(&output), git.WithStderr(&output), git.WithEnv(env...), git.WithDisabledHooks(), - ) - require.NoError(t, err) - - if err := gitCommand.Wait(); err != nil { - return fmt.Errorf("Failed to run `git clone`: %q", output.Bytes()) - } - - return nil -} - -func (cmd cloneCommand) test(t *testing.T, cfg config.Cfg, repoPath string, localRepoPath string) (string, string, string, string) { - t.Helper() - - defer func() { require.NoError(t, os.RemoveAll(localRepoPath)) }() - - err := cmd.execute(t) - require.NoError(t, err) - - remoteHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "master")) - localHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", localRepoPath, "rev-parse", "master")) - - remoteTags := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "tag")) - localTags := text.ChompBytes(gittest.Exec(t, cfg, "-C", localRepoPath, "tag")) - - return localHead, remoteHead, localTags, remoteTags -} - -func TestFailedUploadPackRequestDueToTimeout(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testFailedUploadPackRequestDueToTimeout, testcfg.WithPackObjectsCacheEnabled()) -} - -func testFailedUploadPackRequestDueToTimeout(t *testing.T, opts ...testcfg.Option) { - cfg := testcfg.Build(t, opts...) - - cfg.SocketPath = runSSHServerWithOptions(t, cfg, []ServerOpt{WithUploadPackRequestTimeout(10 * time.Microsecond)}) - - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() - ctx := testhelper.Context(t) - - stream, err := client.SSHUploadPack(ctx) - require.NoError(t, err) - - // The first request is not limited by timeout, but also not under attacker control - require.NoError(t, stream.Send(&gitalypb.SSHUploadPackRequest{Repository: repo})) - - // Because the client says nothing, the server would block. Because of - // the timeout, it won't block forever, and return with a non-zero exit - // code instead. - requireFailedSSHStream(t, func() (int32, error) { - resp, err := stream.Recv() - if err != nil { - return 0, err - } - - var code int32 - if status := resp.GetExitStatus(); status != nil { - code = status.Value - } - - return code, nil - }) -} - -func requireFailedSSHStream(t *testing.T, recv func() (int32, error)) { - done := make(chan struct{}) - var code int32 - var err error - - go func() { - for err == nil { - code, err = recv() - } - close(done) - }() - - select { - case <-done: - testhelper.RequireGrpcCode(t, err, codes.Internal) - require.NotEqual(t, 0, code, "exit status") - case <-time.After(10 * time.Second): - t.Fatal("timeout waiting for SSH stream") - } -} - -func TestFailedUploadPackRequestDueToValidationError(t *testing.T) { - t.Parallel() - - cfg := testcfg.Build(t) - - serverSocketPath := runSSHServer(t, cfg) - - client, conn := newSSHClient(t, serverSocketPath) - defer conn.Close() - - tests := []struct { - Desc string - Req *gitalypb.SSHUploadPackRequest - Code codes.Code - }{ - { - Desc: "Repository.RelativePath is empty", - Req: &gitalypb.SSHUploadPackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: ""}}, - Code: codes.InvalidArgument, - }, - { - Desc: "Repository is nil", - Req: &gitalypb.SSHUploadPackRequest{Repository: nil}, - Code: codes.InvalidArgument, - }, - { - Desc: "Data exists on first request", - Req: &gitalypb.SSHUploadPackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "path/to/repo"}, Stdin: []byte("Fail")}, - Code: func() codes.Code { - if testhelper.IsPraefectEnabled() { - return codes.NotFound - } - - return codes.InvalidArgument - }(), - }, - } - - for _, test := range tests { - t.Run(test.Desc, func(t *testing.T) { - ctx := testhelper.Context(t) - stream, err := client.SSHUploadPack(ctx) - if err != nil { - t.Fatal(err) - } - - if err = stream.Send(test.Req); err != nil { - t.Fatal(err) - } - require.NoError(t, stream.CloseSend()) - - err = testPostUploadPackFailedResponse(t, stream) - testhelper.RequireGrpcCode(t, err, test.Code) - }) - } -} - -func TestUploadPackCloneSuccess(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testUploadPackCloneSuccess, testcfg.WithPackObjectsCacheEnabled()) -} - -func testUploadPackCloneSuccess(t *testing.T, opts ...testcfg.Option) { - testUploadPackCloneSuccess2(t, false, opts...) -} - -func TestUploadPackWithSidechannelCloneSuccess(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testUploadPackWithSidechannelCloneSuccess, testcfg.WithPackObjectsCacheEnabled()) -} - -func testUploadPackWithSidechannelCloneSuccess(t *testing.T, opts ...testcfg.Option) { - testUploadPackCloneSuccess2(t, true, opts...) -} - -func testUploadPackCloneSuccess2(t *testing.T, sidechannel bool, opts ...testcfg.Option) { - cfg := testcfg.Build(t, opts...) - - testcfg.BuildGitalyHooks(t, cfg) - testcfg.BuildGitalySSH(t, cfg) - - negotiationMetrics := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"feature"}) - - cfg.SocketPath = runSSHServerWithOptions(t, cfg, []ServerOpt{WithPackfileNegotiationMetrics(negotiationMetrics)}) - - repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - localRepoPath := testhelper.TempDir(t) - - tests := []struct { - cmd git.Cmd - desc string - deepen float64 - }{ - { - cmd: git.SubCmd{ - Name: "clone", - Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - desc: "full clone", - deepen: 0, - }, - { - cmd: git.SubCmd{ - Name: "clone", - Flags: []git.Option{ - git.ValueFlag{Name: "--depth", Value: "1"}, - }, - Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - desc: "shallow clone", - deepen: 1, - }, - } - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - negotiationMetrics.Reset() - - cmd := cloneCommand{ - repository: repo, - command: tc.cmd, - server: cfg.SocketPath, - cfg: cfg, - sidechannel: sidechannel, - } - lHead, rHead, _, _ := cmd.test(t, cfg, repoPath, localRepoPath) - require.Equal(t, lHead, rHead, "local and remote head not equal") - - metric, err := negotiationMetrics.GetMetricWithLabelValues("deepen") - require.NoError(t, err) - require.Equal(t, tc.deepen, promtest.ToFloat64(metric)) - }) - } -} - -func TestUploadPackWithPackObjectsHook(t *testing.T) { - t.Parallel() - - cfg := testcfg.Build(t, testcfg.WithPackObjectsCacheEnabled()) - - filterDir := testhelper.TempDir(t) - outputPath := filepath.Join(filterDir, "output") - cfg.BinDir = filterDir - - testcfg.BuildGitalySSH(t, cfg) - - // We're using a custom pack-objetcs hook for git-upload-pack. In order - // to assure that it's getting executed as expected, we're writing a - // custom script which replaces the hook binary. It doesn't do anything - // special, but writes an error message and errors out and should thus - // cause the clone to fail with this error message. - testhelper.WriteExecutable(t, filepath.Join(filterDir, "gitaly-hooks"), []byte(fmt.Sprintf( - `#!/bin/bash - set -eo pipefail - echo 'I was invoked' >'%s' - shift - exec git "$@" - `, outputPath))) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - localRepoPath := testhelper.TempDir(t) - - err := cloneCommand{ - repository: repo, - command: git.SubCmd{ - Name: "clone", Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - server: cfg.SocketPath, - cfg: cfg, - }.execute(t) - require.NoError(t, err) - - require.Equal(t, []byte("I was invoked\n"), testhelper.MustReadFile(t, outputPath)) -} - -func TestUploadPackWithoutSideband(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testUploadPackWithoutSideband, testcfg.WithPackObjectsCacheEnabled()) -} - -func testUploadPackWithoutSideband(t *testing.T, opts ...testcfg.Option) { - cfg := testcfg.Build(t, opts...) - - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - // While Git knows the side-band-64 capability, some other clients don't. There is no way - // though to have Git not use that capability, so we're instead manually crafting a packfile - // negotiation without that capability and send it along. - negotiation := bytes.NewBuffer([]byte{}) - gittest.WritePktlineString(t, negotiation, "want 1e292f8fedd741b75372e19097c76d327140c312 multi_ack_detailed thin-pack include-tag ofs-delta agent=git/2.29.1") - gittest.WritePktlineString(t, negotiation, "want 1e292f8fedd741b75372e19097c76d327140c312") - gittest.WritePktlineFlush(t, negotiation) - gittest.WritePktlineString(t, negotiation, "done") - - request := &gitalypb.SSHUploadPackRequest{ - Repository: repo, - } - payload, err := protojson.Marshal(request) - require.NoError(t, err) - - // As we're not using the sideband, the remote process will write both to stdout and stderr. - // Those simultaneous writes to both stdout and stderr created a race as we could've invoked - // two concurrent `SendMsg`s on the gRPC stream. And given that `SendMsg` is not thread-safe - // a deadlock would result. - uploadPack := exec.Command(filepath.Join(cfg.BinDir, "gitaly-ssh"), "upload-pack", "dontcare", "dontcare") - uploadPack.Env = []string{ - fmt.Sprintf("GITALY_ADDRESS=%s", cfg.SocketPath), - fmt.Sprintf("GITALY_PAYLOAD=%s", payload), - fmt.Sprintf("PATH=.:%s", os.Getenv("PATH")), - } - uploadPack.Stdin = negotiation - - out, err := uploadPack.CombinedOutput() - require.NoError(t, err) - require.True(t, uploadPack.ProcessState.Success()) - require.Contains(t, string(out), "refs/heads/master") - require.Contains(t, string(out), "Counting objects") - require.Contains(t, string(out), "PACK") -} - -func TestUploadPackCloneWithPartialCloneFilter(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testUploadPackCloneWithPartialCloneFilter, testcfg.WithPackObjectsCacheEnabled()) -} - -func testUploadPackCloneWithPartialCloneFilter(t *testing.T, opts ...testcfg.Option) { - cfg := testcfg.Build(t, opts...) - - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - // Ruby file which is ~1kB in size and not present in HEAD - blobLessThanLimit := git.ObjectID("6ee41e85cc9bf33c10b690df09ca735b22f3790f") - // Image which is ~100kB in size and not present in HEAD - blobGreaterThanLimit := git.ObjectID("18079e308ff9b3a5e304941020747e5c39b46c88") - - tests := []struct { - desc string - repoTest func(t *testing.T, repoPath string) - cmd git.SubCmd - }{ - { - desc: "full_clone", - repoTest: func(t *testing.T, repoPath string) { - gittest.RequireObjectExists(t, cfg, repoPath, blobGreaterThanLimit) - }, - cmd: git.SubCmd{ - Name: "clone", - }, - }, - { - desc: "partial_clone", - repoTest: func(t *testing.T, repoPath string) { - gittest.RequireObjectNotExists(t, cfg, repoPath, blobGreaterThanLimit) - }, - cmd: git.SubCmd{ - Name: "clone", - Flags: []git.Option{ - git.ValueFlag{Name: "--filter", Value: "blob:limit=2048"}, - }, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - // Run the clone with filtering enabled in both runs. The only - // difference is that in the first run, we have the - // UploadPackFilter flag disabled. - localPath := testhelper.TempDir(t) - - tc.cmd.Args = []string{"git@localhost:test/test.git", localPath} - - cmd := cloneCommand{ - repository: repo, - command: tc.cmd, - server: cfg.SocketPath, - cfg: cfg, - } - err := cmd.execute(t) - defer func() { require.NoError(t, os.RemoveAll(localPath)) }() - require.NoError(t, err, "clone failed") - - gittest.RequireObjectExists(t, cfg, localPath, blobLessThanLimit) - tc.repoTest(t, localPath) - }) - } -} - -func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { - t.Parallel() - - runTestWithAndWithoutConfigOptions(t, testUploadPackCloneSuccessWithGitProtocol, testcfg.WithPackObjectsCacheEnabled()) -} - -func testUploadPackCloneSuccessWithGitProtocol(t *testing.T, opts ...testcfg.Option) { - cfg := testcfg.Build(t, opts...) - ctx := testhelper.Context(t) - - gitCmdFactory, readProto := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) - - cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) - - localRepoPath := testhelper.TempDir(t) - - tests := []struct { - cmd git.Cmd - desc string - }{ - { - cmd: git.SubCmd{ - Name: "clone", - Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - desc: "full clone", - }, - { - cmd: git.SubCmd{ - Name: "clone", - Args: []string{"git@localhost:test/test.git", localRepoPath}, - Flags: []git.Option{ - git.ValueFlag{Name: "--depth", Value: "1"}, - }, - }, - desc: "shallow clone", - }, - } - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - cmd := cloneCommand{ - repository: repo, - command: tc.cmd, - server: cfg.SocketPath, - gitProtocol: git.ProtocolV2, - cfg: cfg, - } - - lHead, rHead, _, _ := cmd.test(t, cfg, repoPath, localRepoPath) - require.Equal(t, lHead, rHead, "local and remote head not equal") - - envData := readProto() - require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) - }) - } -} - -func TestUploadPackCloneHideTags(t *testing.T) { - t.Parallel() - - cfg := testcfg.Build(t) - - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - localRepoPath := testhelper.TempDir(t) - - cloneCmd := cloneCommand{ - repository: repo, - command: git.SubCmd{ - Name: "clone", - Flags: []git.Option{ - git.Flag{Name: "--mirror"}, - }, - Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - server: cfg.SocketPath, - gitConfig: "transfer.hideRefs=refs/tags", - cfg: cfg, - } - _, _, lTags, rTags := cloneCmd.test(t, cfg, repoPath, localRepoPath) - - if lTags == rTags { - t.Fatalf("local and remote tags are equal. clone failed: %q != %q", lTags, rTags) - } - if tag := "v1.0.0"; !strings.Contains(rTags, tag) { - t.Fatalf("sanity check failed, tag %q not found in %q", tag, rTags) - } -} - -func TestUploadPackCloneFailure(t *testing.T) { - t.Parallel() - - cfg := testcfg.Build(t) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - localRepoPath := testhelper.TempDir(t) - - cmd := cloneCommand{ - repository: &gitalypb.Repository{ - StorageName: "foobar", - RelativePath: repo.GetRelativePath(), - }, - command: git.SubCmd{ - Name: "clone", - Args: []string{"git@localhost:test/test.git", localRepoPath}, - }, - server: cfg.SocketPath, - cfg: cfg, - } - err := cmd.execute(t) - require.Error(t, err, "clone didn't fail") -} - -func TestUploadPackCloneGitFailure(t *testing.T) { - t.Parallel() - - cfg := testcfg.Build(t) - - cfg.SocketPath = runSSHServer(t, cfg) - - repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() - - configPath := filepath.Join(repoPath, "config") - gitconfig, err := os.Create(configPath) - require.NoError(t, err) - - // Writing an invalid config will allow repo to pass the `IsGitDirectory` check but still - // trigger an error when git tries to access the repo. - _, err = gitconfig.WriteString("Not a valid git config") - require.NoError(t, err) - - require.NoError(t, gitconfig.Close()) - ctx := testhelper.Context(t) - stream, err := client.SSHUploadPack(ctx) - if err != nil { - t.Fatal(err) - } - - if err = stream.Send(&gitalypb.SSHUploadPackRequest{Repository: repo}); err != nil { - t.Fatal(err) - } - require.NoError(t, stream.CloseSend()) - - err = testPostUploadPackFailedResponse(t, stream) - testhelper.RequireGrpcCode(t, err, codes.Internal) - require.EqualError(t, err, "rpc error: code = Internal desc = cmd wait: exit status 128, stderr: \"fatal: bad config line 1 in file ./config\\n\"") -} - -func testPostUploadPackFailedResponse(t *testing.T, stream gitalypb.SSHService_SSHUploadPackClient) error { - var err error - var res *gitalypb.SSHUploadPackResponse - - for err == nil { - res, err = stream.Recv() - require.Nil(t, res.GetStdout()) - } - - return err -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env_test.go deleted file mode 100644 index 10e68c143a..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env_test.go +++ /dev/null @@ -1,207 +0,0 @@ -package env_test - -import ( - "errors" - "fmt" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -func TestGetBool(t *testing.T) { - for _, tc := range []struct { - value string - fallback bool - expected bool - expectedErrIs error - }{ - { - value: "true", - expected: true, - }, - { - value: "false", - expected: false, - }, - { - value: "1", - expected: true, - }, - { - value: "0", - expected: false, - }, - { - value: "", - expected: false, - }, - { - value: "", - fallback: true, - expected: true, - }, - { - value: "bad", - expected: false, - expectedErrIs: strconv.ErrSyntax, - }, - { - value: "bad", - fallback: true, - expected: true, - expectedErrIs: strconv.ErrSyntax, - }, - } { - t.Run(fmt.Sprintf("value=%s,fallback=%t", tc.value, tc.fallback), func(t *testing.T) { - testhelper.ModifyEnvironment(t, "TEST_BOOL", tc.value) - - result, err := env.GetBool("TEST_BOOL", tc.fallback) - - if tc.expectedErrIs != nil { - assert.Error(t, err) - assert.True(t, errors.Is(err, tc.expectedErrIs), err) - } else { - assert.NoError(t, err) - } - - assert.Equal(t, tc.expected, result) - }) - } -} - -func TestGetInt(t *testing.T) { - for _, tc := range []struct { - value string - fallback int - expected int - expectedErrIs error - }{ - { - value: "3", - expected: 3, - }, - { - value: "", - expected: 0, - }, - { - value: "", - fallback: 3, - expected: 3, - }, - { - value: "bad", - expected: 0, - expectedErrIs: strconv.ErrSyntax, - }, - { - value: "bad", - fallback: 3, - expected: 3, - expectedErrIs: strconv.ErrSyntax, - }, - } { - t.Run(fmt.Sprintf("value=%s,fallback=%d", tc.value, tc.fallback), func(t *testing.T) { - testhelper.ModifyEnvironment(t, "TEST_INT", tc.value) - - result, err := env.GetInt("TEST_INT", tc.fallback) - - if tc.expectedErrIs != nil { - assert.Error(t, err) - assert.True(t, errors.Is(err, tc.expectedErrIs), err) - } else { - assert.NoError(t, err) - } - - assert.Equal(t, tc.expected, result) - }) - } -} - -func TestGetDuration(t *testing.T) { - for _, tc := range []struct { - value string - fallback time.Duration - expected time.Duration - expectedErr string - }{ - { - value: "3m", - fallback: 0, - expected: 3 * time.Minute, - }, - { - value: "", - expected: 0, - }, - { - value: "", - fallback: 3, - expected: 3, - }, - { - value: "bad", - expected: 0, - expectedErr: `get duration TEST_DURATION: time: invalid duration "bad"`, - }, - { - value: "bad", - fallback: 3, - expected: 3, - expectedErr: `get duration TEST_DURATION: time: invalid duration "bad"`, - }, - } { - t.Run(fmt.Sprintf("value=%s,fallback=%d", tc.value, tc.fallback), func(t *testing.T) { - testhelper.ModifyEnvironment(t, "TEST_DURATION", tc.value) - - result, err := env.GetDuration("TEST_DURATION", tc.fallback) - - if tc.expectedErr != "" { - assert.Error(t, err) - assert.EqualError(t, err, tc.expectedErr) - } else { - assert.NoError(t, err) - } - - assert.Equal(t, tc.expected, result) - }) - } -} - -func TestGetString(t *testing.T) { - for _, tc := range []struct { - value string - fallback string - expected string - }{ - { - value: "Hello", - expected: "Hello", - }, - { - value: "hello ", - expected: "hello", - }, - { - fallback: "fallback value", - expected: "fallback value", - }, - { - value: " ", - fallback: "fallback value", - expected: "", - }, - } { - t.Run(fmt.Sprintf("value=%s,fallback=%s", tc.value, tc.fallback), func(t *testing.T) { - testhelper.ModifyEnvironment(t, "TEST_STRING", tc.value) - - result := env.GetString("TEST_STRING", tc.fallback) - - assert.Equal(t, tc.expected, result) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag.go deleted file mode 100644 index a129143356..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag.go +++ /dev/null @@ -1,128 +0,0 @@ -package featureflag - -import ( - "context" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - "google.golang.org/grpc/metadata" -) - -var ( - // featureFlagsOverride allows to enable all feature flags with a - // single environment variable. If the value of - // GITALY_TESTING_ENABLE_ALL_FEATURE_FLAGS is set to "true", then all - // feature flags will be enabled. This is only used for testing - // purposes such that we can run integration tests with feature flags. - featureFlagsOverride, _ = env.GetBool("GITALY_TESTING_ENABLE_ALL_FEATURE_FLAGS", false) - - flagChecks = promauto.NewCounterVec( - prometheus.CounterOpts{ - Name: "gitaly_feature_flag_checks_total", - Help: "Number of enabled/disabled checks for Gitaly server side feature flags", - }, - []string{"flag", "enabled"}, - ) - - // All is the list of all registered feature flags. - All = []FeatureFlag{} -) - -const explicitFeatureFlagKey = "require_explicit_feature_flag_checks" - -func injectIntoIncomingAndOutgoingContext(ctx context.Context, key string, enabled bool) context.Context { - incomingMD, ok := metadata.FromIncomingContext(ctx) - if !ok { - incomingMD = metadata.New(map[string]string{}) - } - - incomingMD.Set(key, strconv.FormatBool(enabled)) - - ctx = metadata.NewIncomingContext(ctx, incomingMD) - - return metadata.AppendToOutgoingContext(ctx, key, strconv.FormatBool(enabled)) -} - -// ContextWithExplicitFeatureFlags marks the context such that all feature flags which are checked -// must have been explicitly set in that context. If a feature flag wasn't set to an explicit value, -// then checking this feature flag will panic. This is not for use in production systems, but is -// intended for tests to verify that we test each feature flag properly. -func ContextWithExplicitFeatureFlags(ctx context.Context) context.Context { - return injectIntoIncomingAndOutgoingContext(ctx, explicitFeatureFlagKey, true) -} - -// FeatureFlag gates the implementation of new or changed functionality. -type FeatureFlag struct { - // Name is the name of the feature flag. - Name string `json:"name"` - // OnByDefault is the default value if the feature flag is not explicitly set in - // the incoming context. - OnByDefault bool `json:"on_by_default"` -} - -// NewFeatureFlag creates a new feature flag and adds it to the array of all existing feature flags. -func NewFeatureFlag(name string, onByDefault bool) FeatureFlag { - featureFlag := FeatureFlag{ - Name: name, - OnByDefault: onByDefault, - } - All = append(All, featureFlag) - return featureFlag -} - -// IsEnabled checks if the feature flag is enabled for the passed context. -// Only returns true if the metadata for the feature flag is set to "true" -func (ff FeatureFlag) IsEnabled(ctx context.Context) bool { - if featureFlagsOverride { - return true - } - - val, ok := ff.valueFromContext(ctx) - if !ok { - if md, ok := metadata.FromIncomingContext(ctx); ok { - if _, ok := md[explicitFeatureFlagKey]; ok { - panic(fmt.Sprintf("checking for feature %q without use of feature sets", ff.Name)) - } - } - - return ff.OnByDefault - } - - enabled := val == "true" - - flagChecks.WithLabelValues(ff.Name, strconv.FormatBool(enabled)).Inc() - - return enabled -} - -// IsDisabled determines whether the feature flag is disabled in the incoming context. -func (ff FeatureFlag) IsDisabled(ctx context.Context) bool { - return !ff.IsEnabled(ctx) -} - -// MetadataKey returns the key of the feature flag as it is present in the metadata map. -func (ff FeatureFlag) MetadataKey() string { - return ffPrefix + strings.ReplaceAll(ff.Name, "_", "-") -} - -func (ff FeatureFlag) valueFromContext(ctx context.Context) (string, bool) { - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return "", false - } - - val, ok := md[ff.MetadataKey()] - if !ok { - return "", false - } - - if len(val) == 0 { - return "", false - } - - return val[0], true -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag_test.go deleted file mode 100644 index 8944e21fdd..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/featureflag_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package featureflag - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/metadata" -) - -func TestFeatureFlag_enabled(t *testing.T) { - for _, tc := range []struct { - desc string - flag string - headers map[string]string - enabled bool - onByDefault bool - }{ - { - desc: "empty name and no headers", - flag: "", - headers: nil, - enabled: false, - onByDefault: false, - }, - { - desc: "no headers", - flag: "flag", - headers: nil, - enabled: false, - onByDefault: false, - }, - { - desc: "no 'gitaly-feature' prefix in flag name", - flag: "flag", - headers: map[string]string{"flag": "true"}, - enabled: false, - onByDefault: false, - }, - { - desc: "not valid header value", - flag: "flag", - headers: map[string]string{"gitaly-feature-flag": "TRUE"}, - enabled: false, - onByDefault: false, - }, - { - desc: "flag name with underscores", - flag: "flag_under_score", - headers: map[string]string{"gitaly-feature-flag-under-score": "true"}, - enabled: true, - onByDefault: false, - }, - { - desc: "flag name with dashes", - flag: "flag-dash-ok", - headers: map[string]string{"gitaly-feature-flag-dash-ok": "true"}, - enabled: true, - onByDefault: false, - }, - { - desc: "flag explicitly disabled", - flag: "flag", - headers: map[string]string{"gitaly-feature-flag": "false"}, - enabled: false, - onByDefault: true, - }, - { - desc: "flag enabled by default but missing", - flag: "flag", - headers: map[string]string{}, - enabled: true, - onByDefault: true, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - ctx := metadata.NewIncomingContext(createContext(), metadata.New(tc.headers)) - - ff := FeatureFlag{tc.flag, tc.onByDefault} - require.Equal(t, tc.enabled, ff.IsEnabled(ctx)) - require.Equal(t, tc.enabled, !ff.IsDisabled(ctx)) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_command_stats_metrics.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_command_stats_metrics.go deleted file mode 100644 index a11206c52a..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_command_stats_metrics.go +++ /dev/null @@ -1,4 +0,0 @@ -package featureflag - -// CommandStatsMetrics tracks additional prometheus metrics for each shelled out command -var CommandStatsMetrics = NewFeatureFlag("command_stats_metrics", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_exact_pagination_token_match.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_exact_pagination_token_match.go deleted file mode 100644 index 16912a85aa..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_exact_pagination_token_match.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// ExactPaginationTokenMatch enables exact matching for provided pagination tokens and -// returns an error if the match is not found. -var ExactPaginationTokenMatch = NewFeatureFlag("exact_pagination_token_match", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_go_find_license.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_go_find_license.go deleted file mode 100644 index 95639870e8..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_go_find_license.go +++ /dev/null @@ -1,4 +0,0 @@ -package featureflag - -// GoFindLicense enables Go implementation of FindLicense -var GoFindLicense = NewFeatureFlag("go_find_license", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_max_queue_wait_time.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_max_queue_wait_time.go deleted file mode 100644 index 2cd281a5bc..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_max_queue_wait_time.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// ConcurrencyQueueMaxWait will enable the concurrency limiter to drop requests that are waiting in -// the concurrency queue for longer than the configured time. -var ConcurrencyQueueMaxWait = NewFeatureFlag("concurrency_queue_max_wait", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_queue_max.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_queue_max.go deleted file mode 100644 index 4b92a4f0fb..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_queue_max.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// ConcurrencyQueueEnforceMax enforces a maximum number of items that are waiting in a concurrency queue. -// when this flag is turned on, subsequent requests that come in will be rejected with an error. -var ConcurrencyQueueEnforceMax = NewFeatureFlag("concurrency_queue_enforce_max", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_rate_limiter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_rate_limiter.go deleted file mode 100644 index 7207e4b377..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_rate_limiter.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// RateLimit will enable the rate limiter to reject requests beyond a configured -// rate. -var RateLimit = NewFeatureFlag("rate_limit", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_repo_size_revlist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_repo_size_revlist.go deleted file mode 100644 index 8be87e482b..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_repo_size_revlist.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// RevlistForRepoSize enables the RepositorySize RPC to use git rev-list to -// calculate the disk usage of the repository. -var RevlistForRepoSize = NewFeatureFlag("revlist_for_repo_size", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go deleted file mode 100644 index 75d6656c36..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go +++ /dev/null @@ -1,4 +0,0 @@ -package featureflag - -// RunCommandsInCGroup allows all commands to be run within a cgroup -var RunCommandsInCGroup = NewFeatureFlag("run_cmds_in_cgroup", true) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go deleted file mode 100644 index 8f3e2337d4..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// TransactionalRestoreCustomHooks will use transactional voting in the -// RestoreCustomHooks RPC -var TransactionalRestoreCustomHooks = NewFeatureFlag("tx_restore_custom_hooks", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_user_rebase_confirmable_improved_error_handling.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_user_rebase_confirmable_improved_error_handling.go deleted file mode 100644 index 9f49b45592..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/ff_user_rebase_confirmable_improved_error_handling.go +++ /dev/null @@ -1,7 +0,0 @@ -package featureflag - -// UserRebaseConfirmableImprovedErrorHandling enables proper error handling in the UserRebaseConfirmable -// RPC. When this flag is disabled many error cases were returning successfully with an error message -// embedded in the response. With this flag enabled, this is converted to return real gRPC errors with -// structured errors. -var UserRebaseConfirmableImprovedErrorHandling = NewFeatureFlag("user_rebase_confirmable_improved_error_handling", false) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_ext_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_ext_test.go deleted file mode 100644 index da8d5d8f99..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_ext_test.go +++ /dev/null @@ -1,498 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package proxy_test - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "net/http" - "net/http/httptest" - "net/url" - "path/filepath" - "testing" - - "github.com/getsentry/sentry-go" - grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" - grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - pb "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - grpc_metadata "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -const ( - pingDefaultValue = "I like kittens." - clientMdKey = "test-client-header" - serverHeaderMdKey = "test-client-header" - serverTrailerMdKey = "test-client-trailer" - - rejectingMdKey = "test-reject-rpc-if-in-context" - - countListResponses = 20 -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} - -// asserting service is implemented on the server side and serves as a handler for stuff -type assertingService struct { - pb.UnimplementedTestServiceServer - t *testing.T -} - -func (s *assertingService) PingEmpty(ctx context.Context, _ *pb.Empty) (*pb.PingResponse, error) { - // Check that this call has client's metadata. - md, ok := grpc_metadata.FromIncomingContext(ctx) - assert.True(s.t, ok, "PingEmpty call must have metadata in context") - _, ok = md[clientMdKey] - assert.True(s.t, ok, "PingEmpty call must have clients's custom headers in metadata") - return &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, nil -} - -func (s *assertingService) Ping(ctx context.Context, ping *pb.PingRequest) (*pb.PingResponse, error) { - // Send user trailers and headers. - require.NoError(s.t, grpc.SendHeader(ctx, grpc_metadata.Pairs(serverHeaderMdKey, "I like turtles."))) - require.NoError(s.t, grpc.SetTrailer(ctx, grpc_metadata.Pairs(serverTrailerMdKey, "I like ending turtles."))) - return &pb.PingResponse{Value: ping.Value, Counter: 42}, nil -} - -func (s *assertingService) PingError(ctx context.Context, ping *pb.PingRequest) (*pb.Empty, error) { - return nil, status.Errorf(codes.ResourceExhausted, "Userspace error.") -} - -func (s *assertingService) PingList(ping *pb.PingRequest, stream pb.TestService_PingListServer) error { - // Send user trailers and headers. - require.NoError(s.t, stream.SendHeader(grpc_metadata.Pairs(serverHeaderMdKey, "I like turtles."))) - for i := 0; i < countListResponses; i++ { - require.NoError(s.t, stream.Send(&pb.PingResponse{Value: ping.Value, Counter: int32(i)})) - } - stream.SetTrailer(grpc_metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) - return nil -} - -func (s *assertingService) PingStream(stream pb.TestService_PingStreamServer) error { - require.NoError(s.t, stream.SendHeader(grpc_metadata.Pairs(serverHeaderMdKey, "I like turtles."))) - counter := int32(0) - for { - ping, err := stream.Recv() - if err == io.EOF { - break - } else if err != nil { - require.NoError(s.t, err, "can't fail reading stream") - return err - } - pong := &pb.PingResponse{Value: ping.Value, Counter: counter} - if err := stream.Send(pong); err != nil { - require.NoError(s.t, err, "can't fail sending back a pong") - } - counter++ - } - stream.SetTrailer(grpc_metadata.Pairs(serverTrailerMdKey, "I like ending turtles.")) - return nil -} - -// ProxyHappySuite tests the "happy" path of handling: that everything works in absence of connection issues. -type ProxyHappySuite struct { - suite.Suite - ctx context.Context - cancel context.CancelFunc - server *grpc.Server - proxy *grpc.Server - connProxy2Server *grpc.ClientConn - client pb.TestServiceClient - connClient2Proxy *grpc.ClientConn -} - -func (s *ProxyHappySuite) TestPingEmptyCarriesClientMetadata() { - ctx := grpc_metadata.NewOutgoingContext(s.ctx, grpc_metadata.Pairs(clientMdKey, "true")) - out, err := s.client.PingEmpty(ctx, &pb.Empty{}) - require.NoError(s.T(), err, "PingEmpty should succeed without errors") - testhelper.ProtoEqual(s.T(), &pb.PingResponse{Value: pingDefaultValue, Counter: 42}, out) -} - -func (s *ProxyHappySuite) TestPingEmpty_StressTest() { - for i := 0; i < 50; i++ { - s.TestPingEmptyCarriesClientMetadata() - } -} - -func (s *ProxyHappySuite) TestPingCarriesServerHeadersAndTrailers() { - headerMd := make(grpc_metadata.MD) - trailerMd := make(grpc_metadata.MD) - // This is an awkward calling convention... but meh. - out, err := s.client.Ping(s.ctx, &pb.PingRequest{Value: "foo"}, grpc.Header(&headerMd), grpc.Trailer(&trailerMd)) - require.NoError(s.T(), err, "Ping should succeed without errors") - testhelper.ProtoEqual(s.T(), &pb.PingResponse{Value: "foo", Counter: 42}, out) - assert.Contains(s.T(), headerMd, serverHeaderMdKey, "server response headers must contain server data") - assert.Len(s.T(), trailerMd, 1, "server response trailers must contain server data") -} - -func (s *ProxyHappySuite) TestPingErrorPropagatesAppError() { - sentryTriggered := 0 - sentrySrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sentryTriggered++ - })) - defer sentrySrv.Close() - - // minimal required sentry client configuration - sentryURL, err := url.Parse(sentrySrv.URL) - require.NoError(s.T(), err) - sentryURL.User = url.UserPassword("stub", "stub") - sentryURL.Path = "/stub/1" - - require.NoError(s.T(), sentry.Init(sentry.ClientOptions{ - Dsn: sentryURL.String(), - Transport: sentry.NewHTTPSyncTransport(), - })) - - sentry.CaptureEvent(sentry.NewEvent()) - require.Equal(s.T(), 1, sentryTriggered, "sentry configured incorrectly") - - _, err = s.client.PingError(s.ctx, &pb.PingRequest{Value: "foo"}) - require.Error(s.T(), err, "PingError should never succeed") - assert.Equal(s.T(), codes.ResourceExhausted, status.Code(err)) - assert.Equal(s.T(), "Userspace error.", status.Convert(err).Message()) - require.Equal(s.T(), 1, sentryTriggered, "sentry must not be triggered because errors from remote must be just propagated") -} - -func (s *ProxyHappySuite) TestDirectorErrorIsPropagated() { - // See SetupSuite where the StreamDirector has a special case. - ctx := grpc_metadata.NewOutgoingContext(s.ctx, grpc_metadata.Pairs(rejectingMdKey, "true")) - _, err := s.client.Ping(ctx, &pb.PingRequest{Value: "foo"}) - require.Error(s.T(), err, "Director should reject this RPC") - assert.Equal(s.T(), codes.PermissionDenied, status.Code(err)) - assert.Equal(s.T(), "testing rejection", status.Convert(err).Message()) -} - -func (s *ProxyHappySuite) TestPingStream_FullDuplexWorks() { - stream, err := s.client.PingStream(s.ctx) - require.NoError(s.T(), err, "PingStream request should be successful.") - - for i := 0; i < countListResponses; i++ { - ping := &pb.PingRequest{Value: fmt.Sprintf("foo:%d", i)} - require.NoError(s.T(), stream.Send(ping), "sending to PingStream must not fail") - resp, err := stream.Recv() - if err == io.EOF { - break - } - if i == 0 { - // Check that the header arrives before all entries. - headerMd, err := stream.Header() - require.NoError(s.T(), err, "PingStream headers should not error.") - assert.Contains(s.T(), headerMd, serverHeaderMdKey, "PingStream response headers user contain metadata") - } - assert.EqualValues(s.T(), i, resp.Counter, "ping roundtrip must succeed with the correct id") - } - require.NoError(s.T(), stream.CloseSend(), "no error on close send") - _, err = stream.Recv() - require.Equal(s.T(), io.EOF, err, "stream should close with io.EOF, meaining OK") - // Check that the trailer headers are here. - trailerMd := stream.Trailer() - assert.Len(s.T(), trailerMd, 1, "PingList trailer headers user contain metadata") -} - -func (s *ProxyHappySuite) TestPingStream_StressTest() { - for i := 0; i < 50; i++ { - s.TestPingStream_FullDuplexWorks() - } -} - -func (s *ProxyHappySuite) SetupSuite() { - s.ctx, s.cancel = context.WithCancel(testhelper.Context(s.T())) - - listenerProxy, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(s.T(), err, "must be able to allocate a port for listenerProxy") - listenerServer, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(s.T(), err, "must be able to allocate a port for listenerServer") - - // Setup of the proxy's Director. - s.connProxy2Server, err = grpc.Dial(listenerServer.Addr().String(), grpc.WithInsecure(), grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec()))) - require.NoError(s.T(), err, "must not error on deferred client Dial") - director := func(ctx context.Context, fullName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { - payload, err := peeker.Peek() - if err != nil { - return nil, err - } - - md, ok := grpc_metadata.FromIncomingContext(ctx) - if ok { - if _, exists := md[rejectingMdKey]; exists { - return proxy.NewStreamParameters(proxy.Destination{Ctx: metadata.IncomingToOutgoing(ctx), Msg: payload}, nil, nil, nil), status.Errorf(codes.PermissionDenied, "testing rejection") - } - } - - // Explicitly copy the metadata, otherwise the tests will fail. - return proxy.NewStreamParameters(proxy.Destination{Ctx: metadata.IncomingToOutgoing(ctx), Conn: s.connProxy2Server, Msg: payload}, nil, nil, nil), nil - } - - // Setup backend server for test suite - s.server = grpc.NewServer() - pb.RegisterTestServiceServer(s.server, &assertingService{t: s.T()}) - go func() { - s.server.Serve(listenerServer) - }() - - // Setup grpc-proxy server for test suite - s.proxy = grpc.NewServer( - grpc.ForceServerCodec(proxy.NewCodec()), - grpc.StreamInterceptor( - grpcmw.ChainStreamServer( - // context tags usage is required by sentryhandler.StreamLogHandler - grpcmwtags.StreamServerInterceptor(grpcmwtags.WithFieldExtractorForInitialReq(fieldextractors.FieldExtractor)), - // sentry middleware to capture errors - sentryhandler.StreamLogHandler, - ), - ), - grpc.UnknownServiceHandler(proxy.TransparentHandler(director)), - ) - // Ping handler is handled as an explicit registration and not as a TransparentHandler. - proxy.RegisterService(s.proxy, director, "mwitkow.testproto.TestService", "Ping") - go func() { - s.proxy.Serve(listenerProxy) - }() - - // Setup client for test suite - ctx := testhelper.Context(s.T()) - - s.connClient2Proxy, err = grpc.DialContext(ctx, listenerProxy.Addr().String(), grpc.WithInsecure()) - require.NoError(s.T(), err, "must not error on deferred client Dial") - s.client = pb.NewTestServiceClient(s.connClient2Proxy) -} - -func (s *ProxyHappySuite) TearDownSuite() { - if s.cancel != nil { - s.cancel() - } - if s.connClient2Proxy != nil { - s.connClient2Proxy.Close() - } - if s.connProxy2Server != nil { - s.connProxy2Server.Close() - } - if s.proxy != nil { - s.proxy.Stop() - } - if s.server != nil { - s.server.Stop() - } -} - -func TestProxyHappySuite(t *testing.T) { - suite.Run(t, &ProxyHappySuite{}) -} - -func TestProxyErrorPropagation(t *testing.T) { - errBackend := status.Error(codes.InvalidArgument, "backend error") - errDirector := status.Error(codes.FailedPrecondition, "director error") - errRequestFinalizer := status.Error(codes.Internal, "request finalizer error") - - for _, tc := range []struct { - desc string - backendError error - directorError error - requestFinalizerError error - returnedError error - errHandler func(error) error - }{ - { - desc: "backend error is propagated", - backendError: errBackend, - returnedError: errBackend, - }, - { - desc: "director error is propagated", - directorError: errDirector, - returnedError: errDirector, - }, - { - desc: "request finalizer error is propagated", - requestFinalizerError: errRequestFinalizer, - returnedError: errRequestFinalizer, - }, - { - desc: "director error cancels proxying", - backendError: errBackend, - requestFinalizerError: errRequestFinalizer, - directorError: errDirector, - returnedError: errDirector, - }, - { - desc: "backend error prioritized over request finalizer error", - backendError: errBackend, - requestFinalizerError: errRequestFinalizer, - returnedError: errBackend, - }, - { - desc: "err handler gets error", - backendError: errBackend, - requestFinalizerError: errRequestFinalizer, - returnedError: errBackend, - errHandler: func(err error) error { - testhelper.RequireGrpcError(t, errBackend, err) - return errBackend - }, - }, - { - desc: "err handler can swallow error", - backendError: errBackend, - returnedError: io.EOF, - errHandler: func(err error) error { - testhelper.RequireGrpcError(t, errBackend, err) - return nil - }, - }, - { - desc: "swallowed error surfaces request finalizer error", - backendError: errBackend, - requestFinalizerError: errRequestFinalizer, - returnedError: errRequestFinalizer, - errHandler: func(err error) error { - testhelper.RequireGrpcError(t, errBackend, err) - return nil - }, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - tmpDir := testhelper.TempDir(t) - - backendListener, err := net.Listen("unix", filepath.Join(tmpDir, "backend")) - require.NoError(t, err) - - backendServer := grpc.NewServer(grpc.UnknownServiceHandler(func(interface{}, grpc.ServerStream) error { - return tc.backendError - })) - go func() { backendServer.Serve(backendListener) }() - defer backendServer.Stop() - ctx := testhelper.Context(t) - - backendClientConn, err := grpc.DialContext(ctx, "unix://"+backendListener.Addr().String(), - grpc.WithInsecure(), grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec()))) - require.NoError(t, err) - defer func() { - require.NoError(t, backendClientConn.Close()) - }() - - proxyListener, err := net.Listen("unix", filepath.Join(tmpDir, "proxy")) - require.NoError(t, err) - - proxyServer := grpc.NewServer( - grpc.ForceServerCodec(proxy.NewCodec()), - grpc.UnknownServiceHandler(proxy.TransparentHandler(func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { - return proxy.NewStreamParameters( - proxy.Destination{ - Ctx: ctx, - Conn: backendClientConn, - ErrHandler: tc.errHandler, - }, - nil, - func() error { return tc.requestFinalizerError }, - nil, - ), tc.directorError - })), - ) - - go func() { proxyServer.Serve(proxyListener) }() - defer proxyServer.Stop() - - proxyClientConn, err := grpc.DialContext(ctx, "unix://"+proxyListener.Addr().String(), grpc.WithInsecure()) - require.NoError(t, err) - defer func() { - require.NoError(t, proxyClientConn.Close()) - }() - - resp, err := pb.NewTestServiceClient(proxyClientConn).Ping(ctx, &pb.PingRequest{}) - testhelper.RequireGrpcError(t, tc.returnedError, err) - require.Nil(t, resp) - }) - } -} - -func TestRegisterStreamHandlers(t *testing.T) { - directorCalledError := errors.New("director was called") - - server := grpc.NewServer( - grpc.ForceServerCodec(proxy.NewCodec()), - grpc.UnknownServiceHandler(proxy.TransparentHandler(func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { - return nil, directorCalledError - })), - ) - - var pingStreamHandlerCalled, pingEmptyStreamHandlerCalled bool - - pingValue := "hello" - - pingStreamHandler := func(srv interface{}, stream grpc.ServerStream) error { - pingStreamHandlerCalled = true - var req pb.PingRequest - - if err := stream.RecvMsg(&req); err != nil { - return err - } - - require.Equal(t, pingValue, req.Value) - - return stream.SendMsg(nil) - } - - pingEmptyStreamHandler := func(srv interface{}, stream grpc.ServerStream) error { - pingEmptyStreamHandlerCalled = true - var req pb.Empty - - if err := stream.RecvMsg(&req); err != nil { - return err - } - - return stream.SendMsg(nil) - } - - streamers := map[string]grpc.StreamHandler{ - "Ping": pingStreamHandler, - "PingEmpty": pingEmptyStreamHandler, - } - - proxy.RegisterStreamHandlers(server, "mwitkow.testproto.TestService", streamers) - - serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(t) - - listener, err := net.Listen("unix", serverSocketPath) - if err != nil { - t.Fatal(err) - } - - go server.Serve(listener) - defer server.Stop() - - cc, err := client.Dial("unix://"+serverSocketPath, []grpc.DialOption{grpc.WithBlock()}) - require.NoError(t, err) - defer cc.Close() - - testServiceClient := pb.NewTestServiceClient(cc) - ctx := testhelper.Context(t) - - _, err = testServiceClient.Ping(ctx, &pb.PingRequest{Value: pingValue}) - require.NoError(t, err) - require.True(t, pingStreamHandlerCalled) - - _, err = testServiceClient.PingEmpty(ctx, &pb.Empty{}) - require.NoError(t, err) - require.True(t, pingEmptyStreamHandlerCalled) - - // since PingError was never registered with its own streamer, it should get sent to the UnknownServiceHandler - _, err = testServiceClient.PingError(ctx, &pb.PingRequest{}) - testhelper.RequireGrpcError(t, status.Error(codes.Unknown, directorCalledError.Error()), err) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/helper_test.go deleted file mode 100644 index 5cf60d7d88..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/helper_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package proxy_test - -import ( - "context" - "net" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - testservice "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata" - "google.golang.org/grpc" -) - -func newListener(tb testing.TB) net.Listener { - listener, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(tb, err, "must be able to allocate a port for listener") - - return listener -} - -func newBackendPinger(tb testing.TB, ctx context.Context) (*grpc.ClientConn, *interceptPinger, func()) { - ip := &interceptPinger{} - - done := make(chan struct{}) - srvr := grpc.NewServer() - listener := newListener(tb) - - testservice.RegisterTestServiceServer(srvr, ip) - - go func() { - defer close(done) - srvr.Serve(listener) - }() - - cc, err := grpc.DialContext( - ctx, - listener.Addr().String(), - grpc.WithInsecure(), - grpc.WithBlock(), - grpc.WithDefaultCallOptions( - grpc.ForceCodec(proxy.NewCodec()), - ), - ) - require.NoError(tb, err) - - cleanup := func() { - srvr.GracefulStop() - require.NoError(tb, cc.Close()) - <-done - } - - return cc, ip, cleanup -} - -func newProxy(tb testing.TB, ctx context.Context, director proxy.StreamDirector, svc, method string) (*grpc.ClientConn, func()) { - proxySrvr := grpc.NewServer( - grpc.ForceServerCodec(proxy.NewCodec()), - grpc.UnknownServiceHandler(proxy.TransparentHandler(director)), - ) - - proxy.RegisterService(proxySrvr, director, svc, method) - - done := make(chan struct{}) - listener := newListener(tb) - - go func() { - defer close(done) - proxySrvr.Serve(listener) - }() - - proxyCC, err := grpc.DialContext( - ctx, - listener.Addr().String(), - grpc.WithInsecure(), - grpc.WithBlock(), - ) - require.NoError(tb, err) - - cleanup := func() { - proxySrvr.GracefulStop() - require.NoError(tb, proxyCC.Close()) - <-done - } - - return proxyCC, cleanup -} - -// interceptPinger allows an RPC to be intercepted with a custom -// function defined in each unit test -type interceptPinger struct { - testservice.UnimplementedTestServiceServer - pingStream func(testservice.TestService_PingStreamServer) error - pingEmpty func(context.Context, *testservice.Empty) (*testservice.PingResponse, error) - ping func(context.Context, *testservice.PingRequest) (*testservice.PingResponse, error) - pingError func(context.Context, *testservice.PingRequest) (*testservice.Empty, error) - pingList func(*testservice.PingRequest, testservice.TestService_PingListServer) error -} - -func (ip *interceptPinger) PingStream(stream testservice.TestService_PingStreamServer) error { - return ip.pingStream(stream) -} - -func (ip *interceptPinger) PingEmpty(ctx context.Context, req *testservice.Empty) (*testservice.PingResponse, error) { - return ip.pingEmpty(ctx, req) -} - -func (ip *interceptPinger) Ping(ctx context.Context, req *testservice.PingRequest) (*testservice.PingResponse, error) { - return ip.ping(ctx, req) -} - -func (ip *interceptPinger) PingError(ctx context.Context, req *testservice.PingRequest) (*testservice.Empty, error) { - return ip.pingError(ctx, req) -} - -func (ip *interceptPinger) PingList(req *testservice.PingRequest, stream testservice.TestService_PingListServer) error { - return ip.pingList(req, stream) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/peeker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/peeker_test.go deleted file mode 100644 index aaa396735d..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/peeker_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package proxy_test - -import ( - "context" - "io" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - testservice "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "google.golang.org/protobuf/proto" -) - -// TestStreamPeeking demonstrates that a director function is able to peek -// into a stream. Further more, it demonstrates that peeking into a stream -// will not disturb the stream sent from the proxy client to the backend. -func TestStreamPeeking(t *testing.T) { - ctx := testhelper.Context(t) - - backendCC, backendSrvr, cleanupPinger := newBackendPinger(t, ctx) - defer cleanupPinger() - - pingReqSent := &testservice.PingRequest{Value: "hi"} - - // director will peek into stream before routing traffic - director := func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { - peekedMsg, err := peeker.Peek() - require.NoError(t, err) - - peekedRequest := &testservice.PingRequest{} - err = proto.Unmarshal(peekedMsg, peekedRequest) - require.NoError(t, err) - require.True(t, proto.Equal(pingReqSent, peekedRequest), "expected to be the same") - - return proxy.NewStreamParameters(proxy.Destination{Ctx: metadata.IncomingToOutgoing(ctx), Conn: backendCC, Msg: peekedMsg}, nil, nil, nil), nil - } - - pingResp := &testservice.PingResponse{ - Counter: 1, - } - - // we expect the backend server to receive the peeked message - backendSrvr.pingStream = func(stream testservice.TestService_PingStreamServer) error { - pingReqReceived, err := stream.Recv() - assert.NoError(t, err) - assert.True(t, proto.Equal(pingReqSent, pingReqReceived), "expected to be the same") - - return stream.Send(pingResp) - } - - proxyCC, cleanupProxy := newProxy(t, ctx, director, "mwitkow.testproto.TestService", "PingStream") - defer cleanupProxy() - - proxyClient := testservice.NewTestServiceClient(proxyCC) - - proxyClientPingStream, err := proxyClient.PingStream(ctx) - require.NoError(t, err) - defer func() { - require.NoError(t, proxyClientPingStream.CloseSend()) - }() - - require.NoError(t, - proxyClientPingStream.Send(pingReqSent), - ) - - resp, err := proxyClientPingStream.Recv() - require.NoError(t, err) - require.True(t, proto.Equal(resp, pingResp), "expected to be the same") - - _, err = proxyClientPingStream.Recv() - require.Equal(t, io.EOF, err) -} - -func TestStreamInjecting(t *testing.T) { - ctx := testhelper.Context(t) - - backendCC, backendSrvr, cleanupPinger := newBackendPinger(t, ctx) - defer cleanupPinger() - - pingReqSent := &testservice.PingRequest{Value: "hi"} - newValue := "bye" - - // director will peek into stream and change some frames - director := func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { - peekedMsg, err := peeker.Peek() - require.NoError(t, err) - - peekedRequest := &testservice.PingRequest{} - require.NoError(t, proto.Unmarshal(peekedMsg, peekedRequest)) - require.Equal(t, "hi", peekedRequest.GetValue()) - - peekedRequest.Value = newValue - - newPayload, err := proto.Marshal(peekedRequest) - require.NoError(t, err) - - return proxy.NewStreamParameters(proxy.Destination{Ctx: metadata.IncomingToOutgoing(ctx), Conn: backendCC, Msg: newPayload}, nil, nil, nil), nil - } - - pingResp := &testservice.PingResponse{ - Counter: 1, - } - - // we expect the backend server to receive the modified message - backendSrvr.pingStream = func(stream testservice.TestService_PingStreamServer) error { - pingReqReceived, err := stream.Recv() - assert.NoError(t, err) - assert.Equal(t, newValue, pingReqReceived.GetValue()) - - return stream.Send(pingResp) - } - - proxyCC, cleanupProxy := newProxy(t, ctx, director, "mwitkow.testproto.TestService", "PingStream") - defer cleanupProxy() - - proxyClient := testservice.NewTestServiceClient(proxyCC) - - proxyClientPingStream, err := proxyClient.PingStream(ctx) - require.NoError(t, err) - defer func() { - require.NoError(t, proxyClientPingStream.CloseSend()) - }() - - require.NoError(t, - proxyClientPingStream.Send(pingReqSent), - ) - - resp, err := proxyClientPingStream.Recv() - require.NoError(t, err) - require.True(t, proto.Equal(resp, pingResp), "expected to be the same") - - _, err = proxyClientPingStream.Recv() - require.Equal(t, io.EOF, err) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.pb.go deleted file mode 100644 index 61fb9cb5bc..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.pb.go +++ /dev/null @@ -1,306 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: praefect/grpc-proxy/testdata/test.proto - -package testdata - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Empty struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Empty) Reset() { - *x = Empty{} - if protoimpl.UnsafeEnabled { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_praefect_grpc_proxy_testdata_test_proto_rawDescGZIP(), []int{0} -} - -type PingRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *PingRequest) Reset() { - *x = PingRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingRequest) ProtoMessage() {} - -func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. -func (*PingRequest) Descriptor() ([]byte, []int) { - return file_praefect_grpc_proxy_testdata_test_proto_rawDescGZIP(), []int{1} -} - -func (x *PingRequest) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type PingResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` - Counter int32 `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` -} - -func (x *PingResponse) Reset() { - *x = PingResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingResponse) ProtoMessage() {} - -func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_praefect_grpc_proxy_testdata_test_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. -func (*PingResponse) Descriptor() ([]byte, []int) { - return file_praefect_grpc_proxy_testdata_test_proto_rawDescGZIP(), []int{2} -} - -func (x *PingResponse) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -func (x *PingResponse) GetCounter() int32 { - if x != nil { - return x.Counter - } - return 0 -} - -var File_praefect_grpc_proxy_testdata_test_proto protoreflect.FileDescriptor - -var file_praefect_grpc_proxy_testdata_test_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x70, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x6d, 0x77, 0x69, 0x74, 0x6b, - 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x05, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x23, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3e, 0x0a, 0x0c, 0x50, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x32, 0x91, 0x03, 0x0a, 0x0b, 0x54, - 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x50, 0x69, - 0x6e, 0x67, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x18, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, - 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x1f, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x6d, - 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, - 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x47, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1e, 0x2e, 0x6d, - 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d, - 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x08, 0x50, 0x69, 0x6e, 0x67, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x53, 0x0a, 0x0a, 0x50, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1e, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, - 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, - 0x77, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x48, - 0x5a, 0x46, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, - 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, - 0x31, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x61, 0x65, - 0x66, 0x65, 0x63, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, - 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_praefect_grpc_proxy_testdata_test_proto_rawDescOnce sync.Once - file_praefect_grpc_proxy_testdata_test_proto_rawDescData = file_praefect_grpc_proxy_testdata_test_proto_rawDesc -) - -func file_praefect_grpc_proxy_testdata_test_proto_rawDescGZIP() []byte { - file_praefect_grpc_proxy_testdata_test_proto_rawDescOnce.Do(func() { - file_praefect_grpc_proxy_testdata_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_praefect_grpc_proxy_testdata_test_proto_rawDescData) - }) - return file_praefect_grpc_proxy_testdata_test_proto_rawDescData -} - -var file_praefect_grpc_proxy_testdata_test_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_praefect_grpc_proxy_testdata_test_proto_goTypes = []interface{}{ - (*Empty)(nil), // 0: mwitkow.testproto.Empty - (*PingRequest)(nil), // 1: mwitkow.testproto.PingRequest - (*PingResponse)(nil), // 2: mwitkow.testproto.PingResponse -} -var file_praefect_grpc_proxy_testdata_test_proto_depIdxs = []int32{ - 0, // 0: mwitkow.testproto.TestService.PingEmpty:input_type -> mwitkow.testproto.Empty - 1, // 1: mwitkow.testproto.TestService.Ping:input_type -> mwitkow.testproto.PingRequest - 1, // 2: mwitkow.testproto.TestService.PingError:input_type -> mwitkow.testproto.PingRequest - 1, // 3: mwitkow.testproto.TestService.PingList:input_type -> mwitkow.testproto.PingRequest - 1, // 4: mwitkow.testproto.TestService.PingStream:input_type -> mwitkow.testproto.PingRequest - 2, // 5: mwitkow.testproto.TestService.PingEmpty:output_type -> mwitkow.testproto.PingResponse - 2, // 6: mwitkow.testproto.TestService.Ping:output_type -> mwitkow.testproto.PingResponse - 0, // 7: mwitkow.testproto.TestService.PingError:output_type -> mwitkow.testproto.Empty - 2, // 8: mwitkow.testproto.TestService.PingList:output_type -> mwitkow.testproto.PingResponse - 2, // 9: mwitkow.testproto.TestService.PingStream:output_type -> mwitkow.testproto.PingResponse - 5, // [5:10] is the sub-list for method output_type - 0, // [0:5] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_praefect_grpc_proxy_testdata_test_proto_init() } -func file_praefect_grpc_proxy_testdata_test_proto_init() { - if File_praefect_grpc_proxy_testdata_test_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_praefect_grpc_proxy_testdata_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Empty); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_praefect_grpc_proxy_testdata_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_praefect_grpc_proxy_testdata_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_praefect_grpc_proxy_testdata_test_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_praefect_grpc_proxy_testdata_test_proto_goTypes, - DependencyIndexes: file_praefect_grpc_proxy_testdata_test_proto_depIdxs, - MessageInfos: file_praefect_grpc_proxy_testdata_test_proto_msgTypes, - }.Build() - File_praefect_grpc_proxy_testdata_test_proto = out.File - file_praefect_grpc_proxy_testdata_test_proto_rawDesc = nil - file_praefect_grpc_proxy_testdata_test_proto_goTypes = nil - file_praefect_grpc_proxy_testdata_test_proto_depIdxs = nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.proto deleted file mode 100644 index 6ece93086c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; - -package mwitkow.testproto; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata"; - -message Empty { -} - -message PingRequest { - string value = 1; -} - -message PingResponse { - string Value = 1; - int32 counter = 2; -} - -service TestService { - rpc PingEmpty(Empty) returns (PingResponse) {} - - rpc Ping(PingRequest) returns (PingResponse) {} - - rpc PingError(PingRequest) returns (Empty) {} - - rpc PingList(PingRequest) returns (stream PingResponse) {} - - rpc PingStream(stream PingRequest) returns (stream PingResponse) {} - -} - diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test_grpc.pb.go deleted file mode 100644 index e697996442..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata/test_grpc.pb.go +++ /dev/null @@ -1,305 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package testdata - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// TestServiceClient is the client API for TestService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type TestServiceClient interface { - PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) - PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) - PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) -} - -type testServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { - return &testServiceClient{cc} -} - -func (c *testServiceClient) PingEmpty(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/mwitkow.testproto.TestService/PingEmpty", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/mwitkow.testproto.TestService/Ping", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) PingError(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/mwitkow.testproto.TestService/PingError", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) PingList(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (TestService_PingListClient, error) { - stream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[0], "/mwitkow.testproto.TestService/PingList", opts...) - if err != nil { - return nil, err - } - x := &testServicePingListClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type TestService_PingListClient interface { - Recv() (*PingResponse, error) - grpc.ClientStream -} - -type testServicePingListClient struct { - grpc.ClientStream -} - -func (x *testServicePingListClient) Recv() (*PingResponse, error) { - m := new(PingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *testServiceClient) PingStream(ctx context.Context, opts ...grpc.CallOption) (TestService_PingStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &TestService_ServiceDesc.Streams[1], "/mwitkow.testproto.TestService/PingStream", opts...) - if err != nil { - return nil, err - } - x := &testServicePingStreamClient{stream} - return x, nil -} - -type TestService_PingStreamClient interface { - Send(*PingRequest) error - Recv() (*PingResponse, error) - grpc.ClientStream -} - -type testServicePingStreamClient struct { - grpc.ClientStream -} - -func (x *testServicePingStreamClient) Send(m *PingRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *testServicePingStreamClient) Recv() (*PingResponse, error) { - m := new(PingResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// TestServiceServer is the server API for TestService service. -// All implementations must embed UnimplementedTestServiceServer -// for forward compatibility -type TestServiceServer interface { - PingEmpty(context.Context, *Empty) (*PingResponse, error) - Ping(context.Context, *PingRequest) (*PingResponse, error) - PingError(context.Context, *PingRequest) (*Empty, error) - PingList(*PingRequest, TestService_PingListServer) error - PingStream(TestService_PingStreamServer) error - mustEmbedUnimplementedTestServiceServer() -} - -// UnimplementedTestServiceServer must be embedded to have forward compatible implementations. -type UnimplementedTestServiceServer struct { -} - -func (UnimplementedTestServiceServer) PingEmpty(context.Context, *Empty) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingEmpty not implemented") -} -func (UnimplementedTestServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedTestServiceServer) PingError(context.Context, *PingRequest) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method PingError not implemented") -} -func (UnimplementedTestServiceServer) PingList(*PingRequest, TestService_PingListServer) error { - return status.Errorf(codes.Unimplemented, "method PingList not implemented") -} -func (UnimplementedTestServiceServer) PingStream(TestService_PingStreamServer) error { - return status.Errorf(codes.Unimplemented, "method PingStream not implemented") -} -func (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {} - -// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to TestServiceServer will -// result in compilation errors. -type UnsafeTestServiceServer interface { - mustEmbedUnimplementedTestServiceServer() -} - -func RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) { - s.RegisterService(&TestService_ServiceDesc, srv) -} - -func _TestService_PingEmpty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).PingEmpty(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/mwitkow.testproto.TestService/PingEmpty", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).PingEmpty(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/mwitkow.testproto.TestService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_PingError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).PingError(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/mwitkow.testproto.TestService/PingError", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).PingError(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_PingList_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(PingRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(TestServiceServer).PingList(m, &testServicePingListServer{stream}) -} - -type TestService_PingListServer interface { - Send(*PingResponse) error - grpc.ServerStream -} - -type testServicePingListServer struct { - grpc.ServerStream -} - -func (x *testServicePingListServer) Send(m *PingResponse) error { - return x.ServerStream.SendMsg(m) -} - -func _TestService_PingStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).PingStream(&testServicePingStreamServer{stream}) -} - -type TestService_PingStreamServer interface { - Send(*PingResponse) error - Recv() (*PingRequest, error) - grpc.ServerStream -} - -type testServicePingStreamServer struct { - grpc.ServerStream -} - -func (x *testServicePingStreamServer) Send(m *PingResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *testServicePingStreamServer) Recv() (*PingRequest, error) { - m := new(PingRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var TestService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "mwitkow.testproto.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "PingEmpty", - Handler: _TestService_PingEmpty_Handler, - }, - { - MethodName: "Ping", - Handler: _TestService_Ping_Handler, - }, - { - MethodName: "PingError", - Handler: _TestService_PingError_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "PingList", - Handler: _TestService_PingList_Handler, - ServerStreams: true, - }, - { - StreamName: "PingStream", - Handler: _TestService_PingStream_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "praefect/grpc-proxy/testdata/test.proto", -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/helper_test.go deleted file mode 100644 index 5a63654163..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/helper_test.go +++ /dev/null @@ -1,299 +0,0 @@ -package praefect - -import ( - "context" - "fmt" - "net" - "testing" - "time" - - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - gitalycfgauth "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - correlation "gitlab.com/gitlab-org/labkit/correlation/grpc" - "google.golang.org/grpc" - "google.golang.org/grpc/health" - healthpb "google.golang.org/grpc/health/grpc_health_v1" -) - -// generates a praefect configuration with the specified number of backend -// nodes -func testConfig(backends int) config.Config { - var nodes []*config.Node - - for i := 0; i < backends; i++ { - n := &config.Node{ - Storage: fmt.Sprintf("praefect-internal-%d", i), - Token: fmt.Sprintf("%d", i), - } - - nodes = append(nodes, n) - } - cfg := config.Config{ - VirtualStorages: []*config.VirtualStorage{ - { - Name: "praefect", - Nodes: nodes, - }, - }, - } - - return cfg -} - -type noopBackoffFactory struct{} - -func (noopBackoffFactory) Create() (Backoff, BackoffReset) { - return func() time.Duration { - return 0 - }, func() {} -} - -type nullNodeMgr struct{} - -func (nullNodeMgr) GetShard(ctx context.Context, virtualStorageName string) (nodes.Shard, error) { - return nodes.Shard{Primary: &nodes.MockNode{}}, nil -} - -func (nullNodeMgr) GetSyncedNode(ctx context.Context, virtualStorageName, repoPath string) (nodes.Node, error) { - return nil, nil -} - -func (nullNodeMgr) HealthyNodes() map[string][]string { - return nil -} - -func (nullNodeMgr) Nodes() map[string][]nodes.Node { - return nil -} - -type buildOptions struct { - withQueue datastore.ReplicationEventQueue - withTxMgr *transactions.Manager - withBackends func([]*config.VirtualStorage) []testhelper.Cleanup - withAnnotations *protoregistry.Registry - withLogger *logrus.Entry - withNodeMgr nodes.Manager - withRepoStore datastore.RepositoryStore - withAssignmentStore AssignmentStore - withConnections Connections - withPrimaryGetter PrimaryGetter - withRouter Router -} - -func withMockBackends(t testing.TB, backends map[string]mock.SimpleServiceServer) func([]*config.VirtualStorage) []testhelper.Cleanup { - return func(virtualStorages []*config.VirtualStorage) []testhelper.Cleanup { - var cleanups []testhelper.Cleanup - - for _, vs := range virtualStorages { - require.Equal(t, len(backends), len(vs.Nodes), - "mock server count doesn't match config nodes") - - for i, node := range vs.Nodes { - backend, ok := backends[node.Storage] - require.True(t, ok, "missing backend server for node %s", node.Storage) - - backendAddr, cleanup := newMockDownstream(t, node.Token, backend) - cleanups = append(cleanups, cleanup) - - node.Address = backendAddr - vs.Nodes[i] = node - } - } - - return cleanups - } -} - -func defaultQueue(t testing.TB) datastore.ReplicationEventQueue { - return datastore.NewPostgresReplicationEventQueue(testdb.New(t)) -} - -func defaultTxMgr(conf config.Config) *transactions.Manager { - return transactions.NewManager(conf) -} - -func defaultNodeMgr(t testing.TB, conf config.Config, rs datastore.RepositoryStore) nodes.Manager { - nodeMgr, err := nodes.NewManager(testhelper.NewDiscardingLogEntry(t), conf, nil, rs, promtest.NewMockHistogramVec(), protoregistry.GitalyProtoPreregistered, nil, nil, nil) - require.NoError(t, err) - nodeMgr.Start(0, time.Hour) - t.Cleanup(nodeMgr.Stop) - return nodeMgr -} - -func defaultRepoStore(conf config.Config) datastore.RepositoryStore { - return datastore.MockRepositoryStore{} -} - -func runPraefectServer(t testing.TB, ctx context.Context, conf config.Config, opt buildOptions) (*grpc.ClientConn, *grpc.Server, testhelper.Cleanup) { - var cleanups []testhelper.Cleanup - - if opt.withQueue == nil { - opt.withQueue = defaultQueue(t) - } - if opt.withRepoStore == nil { - opt.withRepoStore = defaultRepoStore(conf) - } - if opt.withTxMgr == nil { - opt.withTxMgr = defaultTxMgr(conf) - } - if opt.withBackends != nil { - cleanups = append(cleanups, opt.withBackends(conf.VirtualStorages)...) - } - if opt.withAnnotations == nil { - opt.withAnnotations = protoregistry.GitalyProtoPreregistered - } - if opt.withLogger == nil { - opt.withLogger = log.Default() - } - if opt.withNodeMgr == nil { - opt.withNodeMgr = defaultNodeMgr(t, conf, opt.withRepoStore) - } - if opt.withAssignmentStore == nil { - opt.withAssignmentStore = NewDisabledAssignmentStore(conf.StorageNames()) - } - if opt.withRouter == nil { - opt.withRouter = NewNodeManagerRouter(opt.withNodeMgr, opt.withRepoStore) - } - - coordinator := NewCoordinator( - opt.withQueue, - opt.withRepoStore, - opt.withRouter, - opt.withTxMgr, - conf, - opt.withAnnotations, - ) - - // TODO: run a replmgr for EVERY virtual storage - replmgr := NewReplMgr( - opt.withLogger, - conf.StorageNames(), - opt.withQueue, - opt.withRepoStore, - opt.withNodeMgr, - NodeSetFromNodeManager(opt.withNodeMgr), - ) - - prf := NewGRPCServer( - conf, - opt.withLogger, - protoregistry.GitalyProtoPreregistered, - coordinator.StreamDirector, - opt.withTxMgr, - opt.withRepoStore, - opt.withAssignmentStore, - opt.withConnections, - opt.withPrimaryGetter, - nil, - ) - - listener, port := listenAvailPort(t) - - errQ := make(chan error) - ctx, cancel := context.WithCancel(ctx) - - go func() { - errQ <- prf.Serve(listener) - close(errQ) - }() - replMgrDone := startProcessBacklog(ctx, replmgr) - - // dial client to praefect - cc := dialLocalPort(t, port, false) - - cleanup := func() { - cc.Close() - - for _, cu := range cleanups { - cu() - } - - prf.Stop() - - cancel() - <-replMgrDone - require.NoError(t, <-errQ) - } - - return cc, prf, cleanup -} - -func listenAvailPort(tb testing.TB) (net.Listener, int) { - listener, err := net.Listen("tcp", "localhost:0") - require.NoError(tb, err) - - return listener, listener.Addr().(*net.TCPAddr).Port -} - -func dialLocalPort(tb testing.TB, port int, backend bool) *grpc.ClientConn { - opts := []grpc.DialOption{ - grpc.WithBlock(), - grpc.WithUnaryInterceptor(correlation.UnaryClientCorrelationInterceptor()), - grpc.WithStreamInterceptor(correlation.StreamClientCorrelationInterceptor()), - } - if backend { - opts = append( - opts, - grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec())), - ) - } - - cc, err := client.Dial( - fmt.Sprintf("tcp://localhost:%d", port), - opts, - ) - require.NoError(tb, err) - - return cc -} - -func newMockDownstream(tb testing.TB, token string, m mock.SimpleServiceServer) (string, func()) { - srv := grpc.NewServer(grpc.UnaryInterceptor(auth.UnaryServerInterceptor(gitalycfgauth.Config{Token: token}))) - mock.RegisterSimpleServiceServer(srv, m) - healthpb.RegisterHealthServer(srv, health.NewServer()) - - // client to backend service - lis, port := listenAvailPort(tb) - - errQ := make(chan error) - - go func() { - errQ <- srv.Serve(lis) - }() - - cleanup := func() { - srv.GracefulStop() - lis.Close() - - // If the server is shutdown before Serve() is called on it - // the Serve() calls will return the ErrServerStopped - if err := <-errQ; err != nil && err != grpc.ErrServerStopped { - require.NoError(tb, err) - } - } - - return fmt.Sprintf("tcp://localhost:%d", port), cleanup -} - -func startProcessBacklog(ctx context.Context, replMgr ReplMgr) <-chan struct{} { - done := make(chan struct{}) - go func() { - defer close(done) - replMgr.ProcessBacklog(ctx, noopBackoffFactory{}) - }() - return done -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path.go deleted file mode 100644 index 5f35e1e814..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path.go +++ /dev/null @@ -1,20 +0,0 @@ -package praefectutil - -import ( - "crypto/sha256" - "fmt" - "strconv" -) - -// DeriveReplicaPath derives a repository's disk storage path from its repository ID. The repository ID -// is hashed with SHA256 and the first four hex digits of the hash are used as the two subdirectories to -// ensure even distribution into subdirectories. The format is @repositories/ab/cd/. -func DeriveReplicaPath(repositoryID int64) string { - hasher := sha256.New() - // String representation of the ID is used to make it easier to derive the replica paths with - // external tools. The error is ignored as the hash.Hash interface is documented to never return - // an error. - hasher.Write([]byte(strconv.FormatInt(repositoryID, 10))) - hash := hasher.Sum(nil) - return fmt.Sprintf("@repositories/%x/%x/%d", hash[0:1], hash[1:2], repositoryID) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path_test.go deleted file mode 100644 index 6084c13aea..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil/replica_path_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package praefectutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestDeriveReplicaPath(t *testing.T) { - require.Equal(t, "@repositories/6b/86/1", DeriveReplicaPath(1)) - require.Equal(t, "@repositories/d4/73/2", DeriveReplicaPath(2)) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/clocksynced.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/clocksynced.go deleted file mode 100644 index c7edd8be32..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/clocksynced.go +++ /dev/null @@ -1,18 +0,0 @@ -package server - -import ( - "context" - "time" - - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -// ClockSynced checks if system clock is synced. -func (s *Server) ClockSynced(_ context.Context, req *gitalypb.ClockSyncedRequest) (*gitalypb.ClockSyncedResponse, error) { - synced, err := helper.CheckClockSync(req.NtpHost, time.Duration(req.DriftThresholdMillis*int64(time.Millisecond))) - if err != nil { - return nil, err - } - return &gitalypb.ClockSyncedResponse{Synced: synced}, nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/server.go deleted file mode 100644 index b6b14f63bf..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/server.go +++ /dev/null @@ -1,24 +0,0 @@ -package server - -import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -// Server is a ServerService server -type Server struct { - gitalypb.UnimplementedServerServiceServer - conf config.Config - conns service.Connections -} - -// NewServer creates a new instance of a grpc ServerServiceServer -func NewServer(conf config.Config, conns service.Connections) gitalypb.ServerServiceServer { - s := &Server{ - conf: conf, - conns: conns, - } - - return s -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/build.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/build.go deleted file mode 100644 index 8aec16f112..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/build.go +++ /dev/null @@ -1,104 +0,0 @@ -package testcfg - -import ( - "fmt" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" -) - -var buildOnceByName sync.Map - -// BuildGitalyGit2Go builds the gitaly-git2go command and installs it into the binary directory. -func BuildGitalyGit2Go(t testing.TB, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("gitaly-git2go-v14")) -} - -// BuildGitalyWrapper builds the gitaly-wrapper command and installs it into the binary directory. -func BuildGitalyWrapper(t *testing.T, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("gitaly-wrapper")) -} - -// BuildGitalyLFSSmudge builds the gitaly-lfs-smudge command and installs it into the binary -// directory. -func BuildGitalyLFSSmudge(t *testing.T, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("gitaly-lfs-smudge")) -} - -// BuildGitalyHooks builds the gitaly-hooks command and installs it into the binary directory. -func BuildGitalyHooks(t testing.TB, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("gitaly-hooks")) -} - -// BuildGitalySSH builds the gitaly-ssh command and installs it into the binary directory. -func BuildGitalySSH(t testing.TB, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("gitaly-ssh")) -} - -// BuildPraefect builds the praefect command and installs it into the binary directory. -func BuildPraefect(t testing.TB, cfg config.Cfg) string { - return BuildBinary(t, cfg.BinDir, gitalyCommandPath("praefect")) -} - -var ( - sharedBinariesDir string - createGlobalBinaryDirectoryOnce sync.Once -) - -// BuildBinary builds a Go binary once and copies it into the target directory. The source path can -// either be a ".go" file or a directory containing Go files. Returns the path to the executable in -// the destination directory. -func BuildBinary(t testing.TB, targetDir, sourcePath string) string { - createGlobalBinaryDirectoryOnce.Do(func() { - sharedBinariesDir = testhelper.CreateGlobalDirectory(t, "bins") - }) - require.NotEmpty(t, sharedBinariesDir, "creation of shared binary directory failed") - - var ( - // executableName is the name of the executable. - executableName = filepath.Base(sourcePath) - // sharedBinaryPath is the path to the binary shared between all tests. - sharedBinaryPath = filepath.Join(sharedBinariesDir, executableName) - // targetPath is the final path where the binary should be copied to. - targetPath = filepath.Join(targetDir, executableName) - ) - - buildOnceInterface, _ := buildOnceByName.LoadOrStore(executableName, &sync.Once{}) - buildOnce, ok := buildOnceInterface.(*sync.Once) - require.True(t, ok) - - buildOnce.Do(func() { - require.NoFileExists(t, sharedBinaryPath, "binary has already been built") - - testhelper.MustRunCommand(t, nil, - "go", - "build", - "-tags", "static,system_libgit2", - "-o", sharedBinaryPath, - sourcePath, - ) - }) - - require.FileExists(t, sharedBinaryPath, "%s does not exist", executableName) - require.NoFileExists(t, targetPath, "%s exists already -- do you try to build it twice?", executableName) - - require.NoError(t, os.MkdirAll(targetDir, os.ModePerm)) - - // We hard-link the file into place instead of copying it because copying used to cause - // ETXTBSY errors in CI. This is likely caused by a bug in the overlay filesystem used by - // Docker, so we just work around this by linking the file instead. It's more efficient - // anyway, the only thing is that no test must modify the binary directly. But let's count - // on that. - require.NoError(t, os.Link(sharedBinaryPath, targetPath)) - - return targetPath -} - -func gitalyCommandPath(command string) string { - return fmt.Sprintf("gitlab.com/gitlab-org/gitaly/v14/cmd/%s", command) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/CONTRIBUTING.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/CONTRIBUTING.md deleted file mode 100644 index 442c2b00c5..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/CONTRIBUTING.md +++ /dev/null @@ -1,12 +0,0 @@ -## Developer Certificate of Origin + License - -By contributing to GitLab B.V., You accept and agree to the following terms and -conditions for Your present and future Contributions submitted to GitLab B.V. -Except for the license granted herein to GitLab B.V. and recipients of software -distributed by GitLab B.V., You reserve all right, title, and interest in and to -Your Contributions. All Contributions are subject to the following DCO + License -terms. - -[DCO + License](https://gitlab.com/gitlab-org/dco/blob/master/README.md) - -_This notice should stay as the first item in the CONTRIBUTING.md file._ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/DEPRECATION.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/DEPRECATION.md deleted file mode 100644 index 18bd0b44ec..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/DEPRECATION.md +++ /dev/null @@ -1,16 +0,0 @@ -# RPC deprecation process for gitaly-proto - -First create a deprecation issue at -https://gitlab.com/gitlab-org/gitaly/issues with the title `Deprecate -RPC FooBar`. Use label `Deprecation`. Below is a template for the -issue description. - -``` -We are deprecating RPC FooBar because **REASONS**. - -- [ ] put a deprecation comment `// DEPRECATED: ` in ./proto **Merge Request LINK** -- [ ] find all client-side uses of RPC and list below -- [ ] update all client-side uses to no longer use RPC **ADD Merge Request LINKS** -- [ ] wait for a GitLab release in which the RPC is no longer occurring in client side code **LINK TO GITLAB-CE RELEASE TAG** -- [ ] delete the server side implementation of the old RPC in https://gitlab.com/gitlab-org/gitaly **Merge Request LINK** -``` diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/README.md deleted file mode 100644 index 933233f431..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/README.md +++ /dev/null @@ -1,337 +0,0 @@ -# Protobuf specifications and client libraries for Gitaly - -> This directory was previously hosted at https://gitlab.com/gitlab-org/gitaly-proto. As of Gitaly 1.58.0 and gitaly-proto 1.39.0, all further proto changes will be made here, in `gitaly/proto`. - -Gitaly is part of GitLab. It is a [server -application](https://gitlab.com/gitlab-org/gitaly) that uses its own -gRPC protocol to communicate with its clients. This repository -contains the protocol definition and automatically generated wrapper -code for Go and Ruby. - -The `.proto` files define the remote procedure calls for interacting -with Gitaly. We keep auto-generated client libraries for Ruby and Go -in their respective subdirectories. The list of RPCs can be -[found here](https://gitlab-org.gitlab.io/gitaly-proto/). - -Run `make proto` from the root of the repository to regenerate the client -libraries after updating .proto files. - -See -[developers.google.com](https://developers.google.com/protocol-buffers/docs/proto3) -for documentation of the 'proto3' Protocol buffer specification -language. - -## Issues - -We have disabled the issue tracker of the gitaly-proto project. Please use the -[Gitaly issue tracker](https://gitlab.com/gitlab-org/gitaly/issues). - -## gRPC/Protobuf concepts - -The core Protobuf concepts we use are rpc, service and message. We use -these to define the Gitaly **protocol**. - -- **rpc** a function that can be called from the client and that gets - executed on the server. Belongs to a service. Can have one of four - request/response signatures: message/message (example: get metadata for - commit xxx), message/stream (example: get contents of blob xxx), - stream/message (example: create new blob with contents xxx), - stream/stream (example: git SSH session). -- **service** a logical group of RPC's. -- **message** like a JSON object except it has pre-defined types. -- **stream** an unbounded sequence of messages. In the Ruby clients - this looks like an Enumerator. - -gRPC provides an implementation framework based on these Protobuf concepts. - -- A gRPC **server** implements one or more services behind a network - listener. Example: the Gitaly server application. -- The gRPC toolchain automatically generates **client libraries** that - handle serialization and connection management. Example: the Go - client package and Ruby gem in this repository. -- gRPC **clients** use the client libraries to make remote procedure - calls. These clients must decide what network address to reach their - gRPC servers on and handle connection reuse: it is possible to - spread different gRPC services over multiple connections to the same - gRPC server. -- Officially a gRPC connection is called a **channel**. In the Go gRPC - library these channels are called **client connections** because - 'channel' is already a concept in Go itself. In Ruby a gRPC channel - is an instance of GRPC::Core::Channel. We use the word 'connection' - in this document. The underlying transport of gRPC, HTTP/2, allows - multiple remote procedure calls to happen at the same time on a - single connection to a gRPC server. In principle, a multi-threaded - gRPC client needs only one connection to a gRPC server. - -## Design decisions - -1. In Gitaly's case there is one server application - https://gitlab.com/gitlab-org/gitaly which implements all services - in the protocol. -1. In default GitLab installations each Gitaly client interacts with - exactly 1 Gitaly server, on the same host, via a Unix domain socket. - In a larger installation each Gitaly client will interact with many - different Gitaly servers (one per GitLab storage shard) via TCP - connections. -1. Gitaly uses - [grpc.Errorf](https://godoc.org/google.golang.org/grpc#Errorf) to - return meaningful - [errors](https://godoc.org/google.golang.org/grpc/codes#Code) to its - clients. -1. Each RPC `FooBar` has its own `FooBarRequest` and `FooBarResponse` - message types. Try to keep the structure of these messages as flat as - possible. Only add abstractions when they have a practical benefit. -1. We never make backwards incompatible changes to an RPC that is - already implemented on either the client side or server side. - Instead we just create a new RPC call and start a deprecation - procedure (see below) for the old one. -1. It is encouraged to put comments (starting with `//`) in .proto files. - Please put comments on their own lines. This will cause them to be - treated as documentation by the protoc compiler. -1. When choosing an RPC name don't use the service name as context. - Good: `service CommitService { rpc CommitExists }`. Bad: - `service CommitService { rpc Exists }`. - -### RPC naming conventions - -Gitaly-Proto has RPCs that are resource based, for example when querying for a -commit. Another class of RPCs are operations, where the result might be empty -or one of the RPC error codes but the fact that the operation took place is -of importance. - -For all RPCs, start the name with a verb, followed by an entity, and if required -followed by a further specification. For example: -- GetCommit -- RepackRepositoryIncremental -- CreateRepositoryFromBundle - -For resource RPCs the verbs in use are limited to: Get, List, Create, Update, -Delete, or Is. Where both Get and List as verbs denote these operations have no side -effects. These verbs differ in terms of the expected number of results the query -yields. Get queries are limited to one result, and are expected to return one -result to the client. List queries have zero or more results, and generally will -create a gRPC stream for their results. When the `Is` verb is used, this RPC -is expected to return a boolean, or an error. For example: `IsRepositoryEmpty`. - - -When an operation based RPC is defined, the verb should map to the first verb in -the Git command it represents. Example; FetchRemote. - -Note that the current interface defined in this repository does not yet abide -fully to these conventions. Newly defined RPCs should, though, so eventually -gitaly-proto converges to a common standard. - -### Common field names and types - -As a general principle, remember that Git does not enforce encodings on -most data inside repositories, so we can rarely assume data to be a -Protobuf "string" (which implies UTF-8). - -1. `bytes revision`: for fields that accept any of branch names / tag - names / commit ID's. Uses `bytes` to be encoding agnostic. -2. `string commit_id`: for fields that accept a commit ID. -3. `bytes ref`: for fields that accept a refname. -4. `bytes path`: for paths inside Git repositories, i.e., inside Git - `tree` objects. -5. `string relative_path`: for paths on disk on a Gitaly server, - created by "us" (GitLab the application) instead of the user, we - want to use UTF-8, or better, ASCII. - -### Stream patterns - -These are some patterns we already use, or want to use going forward. - -#### Stream response of many small items - -``` -rpc FooBar(FooBarRequest) returns (stream FooBarResponse); - -message FooBarResponse { - message Item { - // ... - } - repeated Item items = 1; -} -``` - -A typical example of an "Item" would be a commit. To avoid the penalty -of network IO for each Item we return, we batch them together. You can -think of this as a kind of buffered IO at the level of the Item -messages. In Go, to ease the bookkeeping you can use -[gitlab.com/gitlab-org/gitaly/internal/helper/chunker](https://godoc.org/gitlab.com/gitlab-org/gitaly/internal/helper/chunker). - -#### Single large item split over multiple messages - -``` -rpc FooBar(FooBarRequest) returns (stream FooBarResponse); - -message FooBarResponse { - message Header { - // ... - } - - oneof payload { - Header header = 1; - bytes data = 2; - } -} -``` - -A typical example of a large item would be the contents of a Git blob. -The header might contain the blob OID and the blob size. Only the first -message in the response stream has `header` set, all others have `data` -but no `header`. - -In the particular case where you're sending back raw binary data from -Go, you can use -[gitlab.com/gitlab-org/gitaly/streamio](https://godoc.org/gitlab.com/gitlab-org/gitaly/streamio) -to turn your gRPC response stream into an `io.Writer`. - -> Note that a number of existing RPC's do not use this pattern exactly; -> they don't use `oneof`. In practice this creates ambiguity (does the -> first message contain non-empty `data`?) and encourages complex -> optimization in the server implementation (trying to squeeze data into -> the first response message). Using `oneof` avoids this ambiguity. - -#### Many large items split over multiple messages - -``` -rpc FooBar(FooBarRequest) returns (stream FooBarResponse); - -message FooBarResponse { - message Header { - // ... - } - - oneof payload { - Header header = 1; - bytes data = 2; - } -} -``` - -This looks the same as the "single large item" case above, except -whenever a new large item begins, we send a new message with a non-empty -`header` field. - -#### Footers - -If the RPC requires it we can also send a footer using `oneof`. But by -default, we prefer headers. - -### RPC Annotations - -In preparation for Gitaly Cluster, we are now requiring all RPC's to be annotated -with an appropriate designation. All methods must contain one of the following lines: - -- `option (op_type).op = ACCESSOR;` - - Designates an RPC as being read-only (i.e. side effect free) -- `option (op_type).op = MUTATOR;` - - Designates that an RPC modifies the repository - -Failing to designate an RPC correctly will result in a CI error. For example: - -`--gitaly_out: server.proto: Method ServerInfo missing op_type option` - -Additionally, all mutator RPC's require additional annotations to clearly -indicate what is being modified: - -- When an RPC modifies a server-wide resource, the scope should specify `SERVER`. -- When an RPC modifies a storage-wide resource, the scope should specify `STORAGE`. - - Additionally, every request should contain field marked with `storage` annotation. -- When an RPC modifies a specific repository, the scope should specify `REPOSITORY`. - - Additionally, every RPC with `REPOSITORY` scope, should also specify the target repository - and may specify the additional repository. - -The target repository represents the location or address of the repository -being modified by the operation. This is needed by Praefect (Gitaly Cluster) in -order to properly schedule replications to keep repository replicas up to date. - -The target repository annotation marks where the target repository can be -found in the message. The annotation is added near `gitaly.Repository` field -(e.g. `Repository repository = 1 [(target_repository)=true];`). If annotated field isn't -`gitaly.Repository` type then it has to contain field annotated `[(repository)=true]` with -correct type. Having separate `repository` annotation allows to have same field in child -message annotated as both `target_repository` and `additional_repository` depending on parent -message. - -The additional repository is annotated similarly to target repository but annotation -is named `additional_repository` - -See our examples of [valid](go/internal/linter/testdata/valid.proto) and -[invalid](go/internal/linter/testdata/invalid.proto) proto annotations. - -### Go Package - -If adding new protobuf files, make sure to correctly set the `go_package` option -near the top of the file: - -`option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb";` - -This allows other protobuf files to locate and import the Go generated stubs. If -you forget to add a `go_package` option, you may receive an error similar to: - -`blob.proto is missing the go_package option` - -### Documentation - -New or updated RPCs and message types should be accompanied by comment strings. -Good comment strings will explain why the RPC exists and how it behaves. Good -message type comments will explain what the message is communicating. Each updated -message field should have a comment. - -Refer to official protobuf documentation for -[how to add comments](https://developers.google.com/protocol-buffers/docs/proto#adding_comments). - -## Contributing - -The CI at https://gitlab.com/gitlab-org/gitaly-proto regenerates the -client libraries to guard against the mistake of updating the .proto -files but not the client libraries. This check uses `git diff` to look -for changes. Some of the code in the Go client libraries is sensitive -to implementation details of the Go standard library (specifically, -the output of gzip). **Use the same Go version as .gitlab-ci.yml (Go -1.13)** when generating new client libraries for a merge request. - -[DCO + License](CONTRIBUTING.md) - -### Build process - -After you change or add a .proto file you need to re-generate the Go -and Ruby libraries before committing your change. - -```shell -# Re-generate Go and Ruby libraries -make proto -``` - -## How to deprecate an RPC call - -See [DEPRECATION.md](DEPRECATION.md). - -## Release - -This will tag and release the gitaly-proto library, including -pushing the gem to rubygems.org - -```shell -make release version=X.Y.Z -``` - -## How to manually push the gem - -If the release script fails the gem may not be pushed. This is how you can do that after the fact: - -```shell -# Use a sub-shell to limit scope of 'set -e' -( - set -e - - # Replace X.Y.Z with the version you are pushing - GEM_VERSION=X.Y.Z - - git checkout v$GEM_VERSION - gem build gitaly.gemspec - gem push gitaly-$GEM_VERSION.gem -) -``` diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/diff.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/diff.proto deleted file mode 100644 index cb6941db01..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/diff.proto +++ /dev/null @@ -1,188 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; -import "shared.proto"; - -service DiffService { - // Returns stream of CommitDiffResponse with patches chunked over messages - rpc CommitDiff(CommitDiffRequest) returns (stream CommitDiffResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - // Return a stream so we can divide the response in chunks of deltas - rpc CommitDelta(CommitDeltaRequest) returns (stream CommitDeltaResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc RawDiff(RawDiffRequest) returns (stream RawDiffResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc RawPatch(RawPatchRequest) returns (stream RawPatchResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc DiffStats(DiffStatsRequest) returns (stream DiffStatsResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - // Return a list of files changed along with the status of each file - rpc FindChangedPaths(FindChangedPathsRequest) returns (stream FindChangedPathsResponse) { - option (op_type) = { - op: ACCESSOR - }; - } -} - -message CommitDiffRequest { - enum DiffMode { - // DEFAULT is the standard diff mode and results in a linewise diff for textfiles. - DEFAULT = 0; - // WORDDIFF is a word diff and computes the diff for whitespace separated words instead of for whole lines. - WORDDIFF = 1; - } - - Repository repository = 1 [(target_repository)=true]; - string left_commit_id = 2; - string right_commit_id = 3; - bool ignore_whitespace_change = 4; - repeated bytes paths = 5; - bool collapse_diffs = 6; - bool enforce_limits = 7; - - // These limits are only enforced when enforce_limits == true. - int32 max_files = 8; - int32 max_lines = 9; - int32 max_bytes = 10; - // Limitation of a single diff patch, - // patches surpassing this limit are pruned by default. - // If this is 0 you will get back empty patches. - int32 max_patch_bytes = 14; - - // These limits are only enforced if collapse_diffs == true. - int32 safe_max_files = 11; - int32 safe_max_lines = 12; - int32 safe_max_bytes = 13; - - // DiffMode is the mode used for generating the diff. Please refer to the enum declaration for supported modes. - DiffMode diff_mode = 15; -} - -// A CommitDiffResponse corresponds to a single changed file in a commit. -message CommitDiffResponse { - reserved 8; - - bytes from_path = 1; - bytes to_path = 2; - // Blob ID as returned via `git diff --full-index` - string from_id = 3; - string to_id = 4; - int32 old_mode = 5; - int32 new_mode = 6; - bool binary = 7; - bytes raw_patch_data = 9; - bool end_of_patch = 10; - // Indicates the diff file at which we overflow according to the limitations sent, - // in which case only this attribute will be set. - bool overflow_marker = 11; - // Indicates the patch surpassed a "safe" limit and was therefore pruned, but - // the client may still request the full patch on a separate request. - bool collapsed = 12; - // Indicates the patch was pruned since it surpassed a hard limit, and can - // therefore not be expanded. - bool too_large = 13; -} - -message CommitDeltaRequest { - Repository repository = 1 [(target_repository)=true]; - string left_commit_id = 2; - string right_commit_id = 3; - repeated bytes paths = 4; -} - -message CommitDelta { - bytes from_path = 1; - bytes to_path = 2; - // Blob ID as returned via `git diff --full-index` - string from_id = 3; - string to_id = 4; - int32 old_mode = 5; - int32 new_mode = 6; -} - -message CommitDeltaResponse { - repeated CommitDelta deltas = 1; -} - -message RawDiffRequest { - Repository repository = 1 [(target_repository)=true]; - string left_commit_id = 2; - string right_commit_id = 3; -} - -message RawDiffResponse { - bytes data = 1; -} - -message RawPatchRequest { - Repository repository = 1 [(target_repository)=true]; - string left_commit_id = 2; - string right_commit_id = 3; -} - -message RawPatchResponse { - bytes data = 1; -} - -message DiffStatsRequest { - Repository repository = 1 [(target_repository)=true]; - string left_commit_id = 2; - string right_commit_id = 3; -} - -message DiffStats { - bytes path = 1; - int32 additions = 2; - int32 deletions = 3; - bytes old_path = 4; -} - -message DiffStatsResponse { - repeated DiffStats stats = 1; -} - -// Given a list of commits, return the files changed. Each commit is compared -// to its parent. Merge commits will show files which are different to all of -// its parents. -message FindChangedPathsRequest { - Repository repository = 1 [(target_repository)=true]; - repeated string commits = 2; -} - -// Returns a list of files that have been changed in the commits given -message FindChangedPathsResponse { - repeated ChangedPaths paths = 1; -} - -// Includes the path of the file, and the status of the change -message ChangedPaths { - enum Status { - ADDED = 0; - MODIFIED = 1; - DELETED = 2; - TYPE_CHANGE = 3; - COPIED = 4; - } - - bytes path = 1; - Status status = 2; -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/errors.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/errors.proto deleted file mode 100644 index 101c58bf79..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/errors.proto +++ /dev/null @@ -1,56 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "google/protobuf/duration.proto"; - -// AccessCheckError is an error returned by GitLab's `/internal/allowed` -// endpoint. -message AccessCheckError { - // ErrorMessage is the error message as returned by the endpoint. - string error_message = 1; - // Protocol is the protocol used. - string protocol = 2; - // UserId is the user ID as which changes had been pushed. - string user_id = 3; - // Changes is the set of changes which have failed the access check. - bytes changes = 4; -} - -// MergeConflictError is an error returned in the case when merging two commits -// fails due to a merge conflict. -message MergeConflictError { - // ConflictingFiles is the set of files which have been conflicting. If this - // field is empty, then there has still been a merge conflict, but it wasn't - // able to determine which files have been conflicting. - repeated bytes conflicting_files = 1; -} - -// ReferenceUpdateError is an error returned when updating a reference has -// failed. -message ReferenceUpdateError { - // ReferenceName is the name of the reference that failed to be updated. - bytes reference_name = 1; - // OldOid is the object ID the reference should have pointed to before the update. - string old_oid = 2; - // NewOid is the object ID the reference should have pointed to after the update. - string new_oid = 3; -} - -// ResolveRevisionError is an error returned when resolving a specific revision -// has failed. -message ResolveRevisionError { - // Revision is the name of the revision that was tried to be resolved. - bytes revision = 1; -} - -// LimitError is an error returned when Gitaly enforces request limits. -message LimitError { - // ErrorMessage provides context into why a limit was enforced. - string error_message = 1; - // RetryAfter provides the duration after which a retry is safe. - // 0 indicates non-retryable. - google.protobuf.Duration retry_after = 2; -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/errors.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/errors.pb.go deleted file mode 100644 index 6443c2825c..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/errors.pb.go +++ /dev/null @@ -1,488 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: errors.proto - -package gitalypb - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// AccessCheckError is an error returned by GitLab's `/internal/allowed` -// endpoint. -type AccessCheckError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ErrorMessage is the error message as returned by the endpoint. - ErrorMessage string `protobuf:"bytes,1,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - // Protocol is the protocol used. - Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` - // UserId is the user ID as which changes had been pushed. - UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - // Changes is the set of changes which have failed the access check. - Changes []byte `protobuf:"bytes,4,opt,name=changes,proto3" json:"changes,omitempty"` -} - -func (x *AccessCheckError) Reset() { - *x = AccessCheckError{} - if protoimpl.UnsafeEnabled { - mi := &file_errors_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AccessCheckError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccessCheckError) ProtoMessage() {} - -func (x *AccessCheckError) ProtoReflect() protoreflect.Message { - mi := &file_errors_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccessCheckError.ProtoReflect.Descriptor instead. -func (*AccessCheckError) Descriptor() ([]byte, []int) { - return file_errors_proto_rawDescGZIP(), []int{0} -} - -func (x *AccessCheckError) GetErrorMessage() string { - if x != nil { - return x.ErrorMessage - } - return "" -} - -func (x *AccessCheckError) GetProtocol() string { - if x != nil { - return x.Protocol - } - return "" -} - -func (x *AccessCheckError) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *AccessCheckError) GetChanges() []byte { - if x != nil { - return x.Changes - } - return nil -} - -// MergeConflictError is an error returned in the case when merging two commits -// fails due to a merge conflict. -type MergeConflictError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ConflictingFiles is the set of files which have been conflicting. If this - // field is empty, then there has still been a merge conflict, but it wasn't - // able to determine which files have been conflicting. - ConflictingFiles [][]byte `protobuf:"bytes,1,rep,name=conflicting_files,json=conflictingFiles,proto3" json:"conflicting_files,omitempty"` -} - -func (x *MergeConflictError) Reset() { - *x = MergeConflictError{} - if protoimpl.UnsafeEnabled { - mi := &file_errors_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MergeConflictError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MergeConflictError) ProtoMessage() {} - -func (x *MergeConflictError) ProtoReflect() protoreflect.Message { - mi := &file_errors_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MergeConflictError.ProtoReflect.Descriptor instead. -func (*MergeConflictError) Descriptor() ([]byte, []int) { - return file_errors_proto_rawDescGZIP(), []int{1} -} - -func (x *MergeConflictError) GetConflictingFiles() [][]byte { - if x != nil { - return x.ConflictingFiles - } - return nil -} - -// ReferenceUpdateError is an error returned when updating a reference has -// failed. -type ReferenceUpdateError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ReferenceName is the name of the reference that failed to be updated. - ReferenceName []byte `protobuf:"bytes,1,opt,name=reference_name,json=referenceName,proto3" json:"reference_name,omitempty"` - // OldOid is the object ID the reference should have pointed to before the update. - OldOid string `protobuf:"bytes,2,opt,name=old_oid,json=oldOid,proto3" json:"old_oid,omitempty"` - // NewOid is the object ID the reference should have pointed to after the update. - NewOid string `protobuf:"bytes,3,opt,name=new_oid,json=newOid,proto3" json:"new_oid,omitempty"` -} - -func (x *ReferenceUpdateError) Reset() { - *x = ReferenceUpdateError{} - if protoimpl.UnsafeEnabled { - mi := &file_errors_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReferenceUpdateError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReferenceUpdateError) ProtoMessage() {} - -func (x *ReferenceUpdateError) ProtoReflect() protoreflect.Message { - mi := &file_errors_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReferenceUpdateError.ProtoReflect.Descriptor instead. -func (*ReferenceUpdateError) Descriptor() ([]byte, []int) { - return file_errors_proto_rawDescGZIP(), []int{2} -} - -func (x *ReferenceUpdateError) GetReferenceName() []byte { - if x != nil { - return x.ReferenceName - } - return nil -} - -func (x *ReferenceUpdateError) GetOldOid() string { - if x != nil { - return x.OldOid - } - return "" -} - -func (x *ReferenceUpdateError) GetNewOid() string { - if x != nil { - return x.NewOid - } - return "" -} - -// ResolveRevisionError is an error returned when resolving a specific revision -// has failed. -type ResolveRevisionError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Revision is the name of the revision that was tried to be resolved. - Revision []byte `protobuf:"bytes,1,opt,name=revision,proto3" json:"revision,omitempty"` -} - -func (x *ResolveRevisionError) Reset() { - *x = ResolveRevisionError{} - if protoimpl.UnsafeEnabled { - mi := &file_errors_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResolveRevisionError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResolveRevisionError) ProtoMessage() {} - -func (x *ResolveRevisionError) ProtoReflect() protoreflect.Message { - mi := &file_errors_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResolveRevisionError.ProtoReflect.Descriptor instead. -func (*ResolveRevisionError) Descriptor() ([]byte, []int) { - return file_errors_proto_rawDescGZIP(), []int{3} -} - -func (x *ResolveRevisionError) GetRevision() []byte { - if x != nil { - return x.Revision - } - return nil -} - -// LimitError is an error returned when Gitaly enforces request limits. -type LimitError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ErrorMessage provides context into why a limit was enforced. - ErrorMessage string `protobuf:"bytes,1,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - // RetryAfter provides the duration after which a retry is safe. - // 0 indicates non-retryable. - RetryAfter *durationpb.Duration `protobuf:"bytes,2,opt,name=retry_after,json=retryAfter,proto3" json:"retry_after,omitempty"` -} - -func (x *LimitError) Reset() { - *x = LimitError{} - if protoimpl.UnsafeEnabled { - mi := &file_errors_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LimitError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LimitError) ProtoMessage() {} - -func (x *LimitError) ProtoReflect() protoreflect.Message { - mi := &file_errors_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LimitError.ProtoReflect.Descriptor instead. -func (*LimitError) Descriptor() ([]byte, []int) { - return file_errors_proto_rawDescGZIP(), []int{4} -} - -func (x *LimitError) GetErrorMessage() string { - if x != nil { - return x.ErrorMessage - } - return "" -} - -func (x *LimitError) GetRetryAfter() *durationpb.Duration { - if x != nil { - return x.RetryAfter - } - return nil -} - -var File_errors_proto protoreflect.FileDescriptor - -var file_errors_proto_rawDesc = []byte{ - 0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x17, 0x0a, 0x07, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, - 0x41, 0x0a, 0x12, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, - 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x22, 0x6f, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x6c, 0x64, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x6c, 0x64, 0x4f, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x65, - 0x77, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x65, 0x77, - 0x4f, 0x69, 0x64, 0x22, 0x32, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x6d, 0x0a, 0x0a, 0x4c, 0x69, 0x6d, 0x69, 0x74, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x72, 0x65, - 0x74, 0x72, 0x79, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x72, - 0x79, 0x41, 0x66, 0x74, 0x65, 0x72, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_errors_proto_rawDescOnce sync.Once - file_errors_proto_rawDescData = file_errors_proto_rawDesc -) - -func file_errors_proto_rawDescGZIP() []byte { - file_errors_proto_rawDescOnce.Do(func() { - file_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_errors_proto_rawDescData) - }) - return file_errors_proto_rawDescData -} - -var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_errors_proto_goTypes = []interface{}{ - (*AccessCheckError)(nil), // 0: gitaly.AccessCheckError - (*MergeConflictError)(nil), // 1: gitaly.MergeConflictError - (*ReferenceUpdateError)(nil), // 2: gitaly.ReferenceUpdateError - (*ResolveRevisionError)(nil), // 3: gitaly.ResolveRevisionError - (*LimitError)(nil), // 4: gitaly.LimitError - (*durationpb.Duration)(nil), // 5: google.protobuf.Duration -} -var file_errors_proto_depIdxs = []int32{ - 5, // 0: gitaly.LimitError.retry_after:type_name -> google.protobuf.Duration - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_errors_proto_init() } -func file_errors_proto_init() { - if File_errors_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_errors_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessCheckError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_errors_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MergeConflictError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_errors_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReferenceUpdateError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_errors_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResolveRevisionError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_errors_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LimitError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_errors_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_errors_proto_goTypes, - DependencyIndexes: file_errors_proto_depIdxs, - MessageInfos: file_errors_proto_msgTypes, - }.Build() - File_errors_proto = out.File - file_errors_proto_rawDesc = nil - file_errors_proto_goTypes = nil - file_errors_proto_depIdxs = nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server.pb.go deleted file mode 100644 index a109a94d4b..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server.pb.go +++ /dev/null @@ -1,706 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: server.proto - -package gitalypb - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ServerInfoRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ServerInfoRequest) Reset() { - *x = ServerInfoRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServerInfoRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerInfoRequest) ProtoMessage() {} - -func (x *ServerInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerInfoRequest.ProtoReflect.Descriptor instead. -func (*ServerInfoRequest) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{0} -} - -type ServerInfoResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ServerVersion string `protobuf:"bytes,1,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"` - GitVersion string `protobuf:"bytes,2,opt,name=git_version,json=gitVersion,proto3" json:"git_version,omitempty"` - StorageStatuses []*ServerInfoResponse_StorageStatus `protobuf:"bytes,3,rep,name=storage_statuses,json=storageStatuses,proto3" json:"storage_statuses,omitempty"` -} - -func (x *ServerInfoResponse) Reset() { - *x = ServerInfoResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServerInfoResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerInfoResponse) ProtoMessage() {} - -func (x *ServerInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerInfoResponse.ProtoReflect.Descriptor instead. -func (*ServerInfoResponse) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{1} -} - -func (x *ServerInfoResponse) GetServerVersion() string { - if x != nil { - return x.ServerVersion - } - return "" -} - -func (x *ServerInfoResponse) GetGitVersion() string { - if x != nil { - return x.GitVersion - } - return "" -} - -func (x *ServerInfoResponse) GetStorageStatuses() []*ServerInfoResponse_StorageStatus { - if x != nil { - return x.StorageStatuses - } - return nil -} - -type DiskStatisticsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *DiskStatisticsRequest) Reset() { - *x = DiskStatisticsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiskStatisticsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiskStatisticsRequest) ProtoMessage() {} - -func (x *DiskStatisticsRequest) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DiskStatisticsRequest.ProtoReflect.Descriptor instead. -func (*DiskStatisticsRequest) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{2} -} - -type DiskStatisticsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - StorageStatuses []*DiskStatisticsResponse_StorageStatus `protobuf:"bytes,1,rep,name=storage_statuses,json=storageStatuses,proto3" json:"storage_statuses,omitempty"` -} - -func (x *DiskStatisticsResponse) Reset() { - *x = DiskStatisticsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiskStatisticsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiskStatisticsResponse) ProtoMessage() {} - -func (x *DiskStatisticsResponse) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DiskStatisticsResponse.ProtoReflect.Descriptor instead. -func (*DiskStatisticsResponse) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{3} -} - -func (x *DiskStatisticsResponse) GetStorageStatuses() []*DiskStatisticsResponse_StorageStatus { - if x != nil { - return x.StorageStatuses - } - return nil -} - -type ClockSyncedRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ntp_host is a URL to the external NTP service that should be used for clock sync check. - // Default is ntp.pool.org - NtpHost string `protobuf:"bytes,1,opt,name=ntp_host,json=ntpHost,proto3" json:"ntp_host,omitempty"` - // drift_threshold_millis is an allowed drift from the NTP service in milliseconds. - DriftThresholdMillis int64 `protobuf:"varint,2,opt,name=drift_threshold_millis,json=driftThresholdMillis,proto3" json:"drift_threshold_millis,omitempty"` -} - -func (x *ClockSyncedRequest) Reset() { - *x = ClockSyncedRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClockSyncedRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClockSyncedRequest) ProtoMessage() {} - -func (x *ClockSyncedRequest) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClockSyncedRequest.ProtoReflect.Descriptor instead. -func (*ClockSyncedRequest) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{4} -} - -func (x *ClockSyncedRequest) GetNtpHost() string { - if x != nil { - return x.NtpHost - } - return "" -} - -func (x *ClockSyncedRequest) GetDriftThresholdMillis() int64 { - if x != nil { - return x.DriftThresholdMillis - } - return 0 -} - -type ClockSyncedResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // synced is set to true if system clock has an affordable drift compared to NTP service. - Synced bool `protobuf:"varint,1,opt,name=synced,proto3" json:"synced,omitempty"` -} - -func (x *ClockSyncedResponse) Reset() { - *x = ClockSyncedResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClockSyncedResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClockSyncedResponse) ProtoMessage() {} - -func (x *ClockSyncedResponse) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClockSyncedResponse.ProtoReflect.Descriptor instead. -func (*ClockSyncedResponse) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{5} -} - -func (x *ClockSyncedResponse) GetSynced() bool { - if x != nil { - return x.Synced - } - return false -} - -type ServerInfoResponse_StorageStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - Readable bool `protobuf:"varint,2,opt,name=readable,proto3" json:"readable,omitempty"` - Writeable bool `protobuf:"varint,3,opt,name=writeable,proto3" json:"writeable,omitempty"` - FsType string `protobuf:"bytes,4,opt,name=fs_type,json=fsType,proto3" json:"fs_type,omitempty"` - FilesystemId string `protobuf:"bytes,5,opt,name=filesystem_id,json=filesystemId,proto3" json:"filesystem_id,omitempty"` - ReplicationFactor uint32 `protobuf:"varint,6,opt,name=replication_factor,json=replicationFactor,proto3" json:"replication_factor,omitempty"` -} - -func (x *ServerInfoResponse_StorageStatus) Reset() { - *x = ServerInfoResponse_StorageStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServerInfoResponse_StorageStatus) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerInfoResponse_StorageStatus) ProtoMessage() {} - -func (x *ServerInfoResponse_StorageStatus) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerInfoResponse_StorageStatus.ProtoReflect.Descriptor instead. -func (*ServerInfoResponse_StorageStatus) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{1, 0} -} - -func (x *ServerInfoResponse_StorageStatus) GetStorageName() string { - if x != nil { - return x.StorageName - } - return "" -} - -func (x *ServerInfoResponse_StorageStatus) GetReadable() bool { - if x != nil { - return x.Readable - } - return false -} - -func (x *ServerInfoResponse_StorageStatus) GetWriteable() bool { - if x != nil { - return x.Writeable - } - return false -} - -func (x *ServerInfoResponse_StorageStatus) GetFsType() string { - if x != nil { - return x.FsType - } - return "" -} - -func (x *ServerInfoResponse_StorageStatus) GetFilesystemId() string { - if x != nil { - return x.FilesystemId - } - return "" -} - -func (x *ServerInfoResponse_StorageStatus) GetReplicationFactor() uint32 { - if x != nil { - return x.ReplicationFactor - } - return 0 -} - -type DiskStatisticsResponse_StorageStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // When both available and used fields are equal 0 that means that - // Gitaly was unable to determine storage stats. - StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - Available int64 `protobuf:"varint,2,opt,name=available,proto3" json:"available,omitempty"` - Used int64 `protobuf:"varint,3,opt,name=used,proto3" json:"used,omitempty"` -} - -func (x *DiskStatisticsResponse_StorageStatus) Reset() { - *x = DiskStatisticsResponse_StorageStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_server_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiskStatisticsResponse_StorageStatus) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiskStatisticsResponse_StorageStatus) ProtoMessage() {} - -func (x *DiskStatisticsResponse_StorageStatus) ProtoReflect() protoreflect.Message { - mi := &file_server_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DiskStatisticsResponse_StorageStatus.ProtoReflect.Descriptor instead. -func (*DiskStatisticsResponse_StorageStatus) Descriptor() ([]byte, []int) { - return file_server_proto_rawDescGZIP(), []int{3, 0} -} - -func (x *DiskStatisticsResponse_StorageStatus) GetStorageName() string { - if x != nil { - return x.StorageName - } - return "" -} - -func (x *DiskStatisticsResponse_StorageStatus) GetAvailable() int64 { - if x != nil { - return x.Available - } - return 0 -} - -func (x *DiskStatisticsResponse_StorageStatus) GetUsed() int64 { - if x != nil { - return x.Used - } - return 0 -} - -var File_server_proto protoreflect.FileDescriptor - -var file_server_proto_rawDesc = []byte{ - 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, - 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x69, 0x74, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x69, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x1a, 0xd9, 0x01, 0x0a, 0x0d, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, - 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x73, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x6b, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0xd7, 0x01, 0x0a, 0x16, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, - 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x22, 0x65, 0x0a, 0x12, 0x43, 0x6c, - 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6e, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x64, - 0x72, 0x69, 0x66, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, - 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x64, 0x72, 0x69, - 0x66, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x4d, 0x69, 0x6c, 0x6c, 0x69, - 0x73, 0x22, 0x2d, 0x0a, 0x13, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x63, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, - 0x32, 0xf5, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x6b, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x63, - 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6c, 0x6f, - 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, - 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, - 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_server_proto_rawDescOnce sync.Once - file_server_proto_rawDescData = file_server_proto_rawDesc -) - -func file_server_proto_rawDescGZIP() []byte { - file_server_proto_rawDescOnce.Do(func() { - file_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_server_proto_rawDescData) - }) - return file_server_proto_rawDescData -} - -var file_server_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_server_proto_goTypes = []interface{}{ - (*ServerInfoRequest)(nil), // 0: gitaly.ServerInfoRequest - (*ServerInfoResponse)(nil), // 1: gitaly.ServerInfoResponse - (*DiskStatisticsRequest)(nil), // 2: gitaly.DiskStatisticsRequest - (*DiskStatisticsResponse)(nil), // 3: gitaly.DiskStatisticsResponse - (*ClockSyncedRequest)(nil), // 4: gitaly.ClockSyncedRequest - (*ClockSyncedResponse)(nil), // 5: gitaly.ClockSyncedResponse - (*ServerInfoResponse_StorageStatus)(nil), // 6: gitaly.ServerInfoResponse.StorageStatus - (*DiskStatisticsResponse_StorageStatus)(nil), // 7: gitaly.DiskStatisticsResponse.StorageStatus -} -var file_server_proto_depIdxs = []int32{ - 6, // 0: gitaly.ServerInfoResponse.storage_statuses:type_name -> gitaly.ServerInfoResponse.StorageStatus - 7, // 1: gitaly.DiskStatisticsResponse.storage_statuses:type_name -> gitaly.DiskStatisticsResponse.StorageStatus - 0, // 2: gitaly.ServerService.ServerInfo:input_type -> gitaly.ServerInfoRequest - 2, // 3: gitaly.ServerService.DiskStatistics:input_type -> gitaly.DiskStatisticsRequest - 4, // 4: gitaly.ServerService.ClockSynced:input_type -> gitaly.ClockSyncedRequest - 1, // 5: gitaly.ServerService.ServerInfo:output_type -> gitaly.ServerInfoResponse - 3, // 6: gitaly.ServerService.DiskStatistics:output_type -> gitaly.DiskStatisticsResponse - 5, // 7: gitaly.ServerService.ClockSynced:output_type -> gitaly.ClockSyncedResponse - 5, // [5:8] is the sub-list for method output_type - 2, // [2:5] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_server_proto_init() } -func file_server_proto_init() { - if File_server_proto != nil { - return - } - file_lint_proto_init() - if !protoimpl.UnsafeEnabled { - file_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerInfoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerInfoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiskStatisticsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiskStatisticsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClockSyncedRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClockSyncedResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerInfoResponse_StorageStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiskStatisticsResponse_StorageStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_server_proto_rawDesc, - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_server_proto_goTypes, - DependencyIndexes: file_server_proto_depIdxs, - MessageInfos: file_server_proto_msgTypes, - }.Build() - File_server_proto = out.File - file_server_proto_rawDesc = nil - file_server_proto_goTypes = nil - file_server_proto_depIdxs = nil -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint_test.go deleted file mode 100644 index 5747b38937..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package linter - -import ( - "errors" - "testing" - - "github.com/stretchr/testify/require" - _ "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata" - "google.golang.org/protobuf/reflect/protodesc" - protoreg "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/types/descriptorpb" - "google.golang.org/protobuf/types/pluginpb" -) - -func TestLintFile(t *testing.T) { - for _, tt := range []struct { - protoPath string - errs []error - }{ - { - protoPath: "go/internal/linter/testdata/valid.proto", - errs: nil, - }, - { - protoPath: "go/internal/linter/testdata/invalid.proto", - errs: []error{ - formatError("go/internal/linter/testdata/invalid.proto", "InterceptedWithOperationType", "InvalidMethod", errors.New("operation type defined on an intercepted method")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod0", errors.New("missing op_type extension")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod1", errors.New("op set to UNKNOWN")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod2", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod4", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod5", errors.New("wrong type of field RequestWithWrongTypeRepository.header.repository, expected .gitaly.Repository, got .test.InvalidMethodResponse")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod6", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod7", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod8", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod9", errors.New("unexpected count of target_repository fields 1, expected 0, found target_repository label at: [InvalidMethodRequestWithRepo.destination]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod10", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithStorageAndRepo.storage_name]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod11", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithNestedStorageAndRepo.inner_message.storage_name]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod13", errors.New("unexpected count of storage field 0, expected 1, found storage label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod14", errors.New("unexpected count of storage field 2, expected 1, found storage label at: [RequestWithMultipleNestedStorage.inner_message.storage_name RequestWithMultipleNestedStorage.storage_name]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "InvalidMethod15", errors.New("operation type defined on an intercepted method")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithMissingRepository", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithUnflaggedRepository", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithWrongNestedRepositoryType", errors.New("wrong type of field RequestWithWrongTypeRepository.header.repository, expected .gitaly.Repository, got .test.InvalidMethodResponse")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithInvalidTargetType", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithInvalidNestedRequest", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithStorageAndRepository", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithStorageAndRepo.storage_name]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithNestedStorageAndRepository", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithNestedStorageAndRepo.inner_message.storage_name]")), - formatError("go/internal/linter/testdata/invalid.proto", "InvalidService", "MaintenanceWithStorageScope", errors.New("unknown operation scope level 2")), - }, - }, - } { - t.Run(tt.protoPath, func(t *testing.T) { - fd, err := protoreg.GlobalFiles.FindFileByPath(tt.protoPath) - require.NoError(t, err) - - fdToCheck := protodesc.ToFileDescriptorProto(fd) - req := &pluginpb.CodeGeneratorRequest{ - ProtoFile: []*descriptorpb.FileDescriptorProto{fdToCheck}, - } - - for _, protoPath := range []string{ - // as we have no input stream we can use to create CodeGeneratorRequest - // we must create it by hands with all required dependencies loaded - "google/protobuf/descriptor.proto", - "google/protobuf/timestamp.proto", - "lint.proto", - "shared.proto", - } { - fd, err := protoreg.GlobalFiles.FindFileByPath(protoPath) - require.NoError(t, err) - req.ProtoFile = append(req.ProtoFile, protodesc.ToFileDescriptorProto(fd)) - } - - errs := LintFile(fdToCheck, req) - require.Equal(t, tt.errs, errs) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/hook.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/hook.proto deleted file mode 100644 index 9c3810ded1..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/hook.proto +++ /dev/null @@ -1,126 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; -import "shared.proto"; - -service HookService { - rpc PreReceiveHook(stream PreReceiveHookRequest) returns (stream PreReceiveHookResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc PostReceiveHook(stream PostReceiveHookRequest) returns (stream PostReceiveHookResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc UpdateHook(UpdateHookRequest) returns (stream UpdateHookResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - rpc ReferenceTransactionHook(stream ReferenceTransactionHookRequest) returns (stream ReferenceTransactionHookResponse) { - option (op_type) = { - op: ACCESSOR - }; - } - // PackObjectsHook has been replaced by PackObjectsHookWithSidechannel. Remove in 15.0. - rpc PackObjectsHook(stream PackObjectsHookRequest) returns (stream PackObjectsHookResponse) { - option deprecated = true; - option (op_type) = { - op: ACCESSOR - }; - } - // PackObjectsHookWithSidechannel is an optimized version of PackObjectsHook that uses - // a unix socket side channel. - rpc PackObjectsHookWithSidechannel(PackObjectsHookWithSidechannelRequest) returns (PackObjectsHookWithSidechannelResponse) { - option (op_type) = { - op: ACCESSOR - }; - } -} - -message PreReceiveHookRequest { - Repository repository = 1 [(target_repository)=true]; - repeated string environment_variables = 2; - bytes stdin = 4; - repeated string git_push_options = 5; -} - -message PreReceiveHookResponse{ - bytes stdout = 1; - bytes stderr = 2; - ExitStatus exit_status = 3; -} - -message PostReceiveHookRequest { - Repository repository = 1 [(target_repository)=true]; - repeated string environment_variables = 2; - bytes stdin = 3; - repeated string git_push_options = 4; -} - -message PostReceiveHookResponse{ - bytes stdout = 1; - bytes stderr = 2; - ExitStatus exit_status = 3; -} - -message UpdateHookRequest { - Repository repository = 1 [(target_repository)=true]; - repeated string environment_variables = 2; - bytes ref = 3; - string old_value = 4; - string new_value = 5; -} - -message UpdateHookResponse{ - bytes stdout = 1; - bytes stderr = 2; - ExitStatus exit_status = 3; -} - -message ReferenceTransactionHookRequest { - Repository repository = 1 [(target_repository)=true]; - repeated string environment_variables = 2; - bytes stdin = 3; - enum State { - PREPARED = 0; - COMMITTED = 1; - ABORTED = 2; - } - State state = 4; -} - -message ReferenceTransactionHookResponse { - bytes stdout = 1; - bytes stderr = 2; - ExitStatus exit_status = 3; -} - -message PackObjectsHookRequest { - Repository repository = 1 [(target_repository)=true]; - // args contains the arguments passed to the pack-objects hook, without the leading "git" - repeated string args = 2; - // stdin is meant for consumption by git-pack-objects - bytes stdin = 3; -} - -message PackObjectsHookResponse { - // stdout contains packfile data - bytes stdout = 1; - // stderr contains progress messages (such as "Enumerating objects ...") - bytes stderr = 2; -} - -message PackObjectsHookWithSidechannelRequest { - Repository repository = 1 [(target_repository)=true]; - // args contains the arguments passed to the pack-objects hook, without the leading "git" - repeated string args = 2; -} - -message PackObjectsHookWithSidechannelResponse {} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/namespace.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/namespace.proto deleted file mode 100644 index 298ef9cb44..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/namespace.proto +++ /dev/null @@ -1,63 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; - -service NamespaceService { - rpc AddNamespace(AddNamespaceRequest) returns (AddNamespaceResponse) { - option (op_type) = { - op: MUTATOR - scope_level: STORAGE, - }; - } - rpc RemoveNamespace(RemoveNamespaceRequest) returns (RemoveNamespaceResponse) { - option (op_type) = { - op: MUTATOR - scope_level: STORAGE, - }; - } - rpc RenameNamespace(RenameNamespaceRequest) returns (RenameNamespaceResponse) { - option (op_type) = { - op: MUTATOR - scope_level: STORAGE, - }; - } - rpc NamespaceExists(NamespaceExistsRequest) returns (NamespaceExistsResponse) { - option (op_type) = { - op: ACCESSOR - scope_level: STORAGE, - }; - } -} - -message AddNamespaceRequest { - string storage_name = 1 [(storage)=true]; - string name = 2; -} - -message RemoveNamespaceRequest { - string storage_name = 1 [(storage)=true]; - string name = 2; -} - -message RenameNamespaceRequest { - string storage_name = 1 [(storage)=true]; - string from = 2; - string to = 3; -} - -message NamespaceExistsRequest { - string storage_name = 1 [(storage)=true]; - string name = 2; -} - -message NamespaceExistsResponse { - bool exists = 1; -} - -message AddNamespaceResponse {} -message RemoveNamespaceResponse {} -message RenameNamespaceResponse {} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/objectpool.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/objectpool.proto deleted file mode 100644 index e6be24c393..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/objectpool.proto +++ /dev/null @@ -1,98 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; -import "shared.proto"; - -service ObjectPoolService { - rpc CreateObjectPool(CreateObjectPoolRequest) returns (CreateObjectPoolResponse) { - option (op_type) = { - op: MUTATOR - }; - } - rpc DeleteObjectPool(DeleteObjectPoolRequest) returns (DeleteObjectPoolResponse) { - option (op_type) = { - op: MUTATOR - }; - } - - // Repositories are assumed to be stored on the same disk - rpc LinkRepositoryToObjectPool(LinkRepositoryToObjectPoolRequest) returns (LinkRepositoryToObjectPoolResponse) { - option (op_type) = { - op: MUTATOR - }; - } - - rpc ReduplicateRepository(ReduplicateRepositoryRequest) returns (ReduplicateRepositoryResponse) { - option (op_type) = { - op: MUTATOR - }; - } - rpc DisconnectGitAlternates(DisconnectGitAlternatesRequest) returns (DisconnectGitAlternatesResponse) { - option (op_type) = { - op: MUTATOR - }; - } - rpc FetchIntoObjectPool(FetchIntoObjectPoolRequest) returns (FetchIntoObjectPoolResponse) { - option (op_type) = { - op: MUTATOR - }; - } - rpc GetObjectPool(GetObjectPoolRequest) returns (GetObjectPoolResponse) { - option (op_type) = { - op: ACCESSOR - }; - } -} - -// Creates an object pool from the repository. The client is responsible for -// joining this pool later with this repository. -message CreateObjectPoolRequest { - ObjectPool object_pool = 1 [(target_repository)=true]; - Repository origin = 2 [(additional_repository)=true]; -} -message CreateObjectPoolResponse {} - -// Removes the directory from disk, caller is responsible for leaving the object -// pool before calling this RPC -message DeleteObjectPoolRequest { - ObjectPool object_pool = 1 [(target_repository)=true]; -} -message DeleteObjectPoolResponse {} - -message LinkRepositoryToObjectPoolRequest { - ObjectPool object_pool = 1 [(additional_repository)=true]; - Repository repository = 2 [(target_repository)=true]; -} -message LinkRepositoryToObjectPoolResponse {} - -message ReduplicateRepositoryRequest { - Repository repository = 1 [(target_repository)=true]; -} -message ReduplicateRepositoryResponse {} - -message DisconnectGitAlternatesRequest { - Repository repository = 1 [(target_repository)=true]; -} - -message DisconnectGitAlternatesResponse {} - -message FetchIntoObjectPoolRequest { - Repository origin = 1 [(additional_repository)=true]; - ObjectPool object_pool = 2 [(target_repository)=true]; - bool repack = 3; -} -message FetchIntoObjectPoolResponse {} - -message GetObjectPoolRequest { - Repository repository = 1 [(target_repository)=true]; -} - -message GetObjectPoolResponse { - ObjectPool object_pool = 1; -} - - diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/server.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/server.proto deleted file mode 100644 index 7a61402227..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/server.proto +++ /dev/null @@ -1,61 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; - -service ServerService { - option (intercepted) = true; - - rpc ServerInfo(ServerInfoRequest) returns (ServerInfoResponse); - rpc DiskStatistics(DiskStatisticsRequest) returns (DiskStatisticsResponse); - // ClockSynced checks if machine clock is synced - // (the offset is less that the one passed in the request). - rpc ClockSynced(ClockSyncedRequest) returns (ClockSyncedResponse) {} -} - -message ServerInfoRequest {} - -message ServerInfoResponse { - message StorageStatus { - string storage_name = 1; - bool readable = 2; - bool writeable = 3; - string fs_type = 4; - string filesystem_id = 5; - uint32 replication_factor = 6; - } - - string server_version = 1; - string git_version = 2; - repeated StorageStatus storage_statuses = 3; -} - -message DiskStatisticsRequest {} - -message DiskStatisticsResponse { - message StorageStatus { -// When both available and used fields are equal 0 that means that -// Gitaly was unable to determine storage stats. - string storage_name = 1; - int64 available = 2; - int64 used = 3; - } - - repeated StorageStatus storage_statuses = 1; -} - -message ClockSyncedRequest { - // ntp_host is a URL to the external NTP service that should be used for clock sync check. - // Default is ntp.pool.org - string ntp_host = 1; - // drift_threshold_millis is an allowed drift from the NTP service in milliseconds. - int64 drift_threshold_millis = 2; -} - -message ClockSyncedResponse { - // synced is set to true if system clock has an affordable drift compared to NTP service. - bool synced = 1; -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/shared.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/shared.proto deleted file mode 100644 index 07ca7c5d2a..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/shared.proto +++ /dev/null @@ -1,164 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "google/protobuf/timestamp.proto"; -import "lint.proto"; - -enum ObjectType { - UNKNOWN = 0; - COMMIT = 1; - BLOB = 2; - TREE = 3; - TAG = 4; -} - -enum SignatureType { - NONE = 0; - PGP = 1; - X509 = 2; - SSH = 3; - // maybe add X509+TSA or other combinations at a later step -} - -message Repository { - // DEPRECATED: https://gitlab.com/gitlab-org/gitaly/issues/151 - reserved 1; - reserved "path"; - - string storage_name = 2; - string relative_path = 3; - // Sets the GIT_OBJECT_DIRECTORY envvar on git commands to the value of this field. - // It influences the object storage directory the SHA1 directories are created underneath. - string git_object_directory = 4; - // Sets the GIT_ALTERNATE_OBJECT_DIRECTORIES envvar on git commands to the values of this field. - // It influences the list of Git object directories which can be used to search for Git objects. - repeated string git_alternate_object_directories = 5; - // Used in callbacks to GitLab so that it knows what repository the event is - // associated with. May be left empty on RPC's that do not perform callbacks. - // During project creation, `gl_repository` may not be known. - string gl_repository = 6; - reserved 7; - // The human-readable GitLab project path (e.g. gitlab-org/gitlab-ce). - // When hashed storage is use, this associates a project path with its - // path on disk. The name can change over time (e.g. when a project is - // renamed). This is primarily used for logging/debugging at the - // moment. - string gl_project_path = 8; -} - -// A single Git trailer (https://git-scm.com/docs/git-interpret-trailers) -// key-value pair. -message CommitTrailer { - // The key of the trailer, such as `Signed-off-by`. - bytes key = 1; - // The value of the trailer, such as `Alice `. - bytes value = 2; -} - -// Corresponds to Gitlab::Git::Commit -message GitCommit { - string id = 1; - bytes subject = 2; - bytes body = 3; - CommitAuthor author = 4; - CommitAuthor committer = 5; - repeated string parent_ids = 6; - // If body exceeds a certain threshold, it will be nullified, - // but its size will be set in body_size so we can know if - // a commit had a body in the first place. - int64 body_size = 7; - SignatureType signature_type = 8; - - // The tree ID will always be filled, even if the tree is empty. In that case - // the value will be `4b825dc642cb6eb9a060e54bf8d69288fbee4904`. - // That value is equivalent to `git hash-object -t tree /dev/null` - string tree_id = 9; - // The list of Git trailers (https://git-scm.com/docs/git-interpret-trailers) - // found in this commit's message. The number of trailers and their key/value - // sizes are limited. If a trailer exceeds these size limits, it and any - // trailers that follow it are not included. - repeated CommitTrailer trailers = 10; -} - -message CommitAuthor { - bytes name = 1; - bytes email = 2; - google.protobuf.Timestamp date = 3; - bytes timezone = 4; -} - -message ExitStatus { - int32 value = 1; -} - -// Corresponds to Gitlab::Git::Branch -message Branch { - bytes name = 1; - GitCommit target_commit = 2; -} - -message Tag { - bytes name = 1; - string id = 2; - GitCommit target_commit = 3; - // If message exceeds a certain threshold, it will be nullified, - // but its size will be set in message_size so we can know if - // a tag had a message in the first place. - bytes message = 4; - int64 message_size = 5; - CommitAuthor tagger = 6; - SignatureType signature_type = 7; -} - -message User { - string gl_id = 1; - bytes name = 2; - bytes email = 3; - string gl_username = 4; - // Timezone is the timezone as configured by the user in the web interface. This - // timezone may be used when new commits are created via RPC calls. - string timezone = 5; -} - -message ObjectPool { - Repository repository = 1 [(gitaly.repository)=true]; -} - -message PaginationParameter { - // Instructs pagination to start sending results after the provided page - // token appears. A page token allows for a generic pattern to uniquely - // identify a result or 'page'. Each paginated RPC may interpret a page - // token differently. - string page_token = 1; - // When fully consuming the response the client will receive _at most_ - // `limit` number of resulting objects. Note that the number of response - // messages might be much lower, as some response messages already send - // multiple objects per message. - // When the limit is smaller than 0, it will be normalized to 2147483647 - // on the server side. When limit is not set, it defaults to 0, and no - // results are send in the response. - int32 limit = 2; -} - -message PaginationCursor { - // To the caller, this is an opaque token to indicate what the caller - // should present as a page_token to get subsequent results. - string next_cursor = 1; -} - -// https://git-scm.com/docs/git/#_options -message GlobalOptions { - // Treat pathspecs literally (i.e. no globbing, no pathspec magic) - bool literal_pathspecs = 1; -} - -// SortDirection defines the sort direction. -enum SortDirection { - // ASCENDING sorts by the sort key in ascending order. - ASCENDING = 0; - // DESCENDING sorts by the sort key in descending order. - DESCENDING = 1; -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/transaction.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/transaction.proto deleted file mode 100644 index bccd2ab6b9..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/transaction.proto +++ /dev/null @@ -1,62 +0,0 @@ -syntax = "proto3"; - -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; -import "shared.proto"; - -service RefTransaction { - option (intercepted) = true; - - rpc VoteTransaction (VoteTransactionRequest) returns (VoteTransactionResponse); - - rpc StopTransaction (StopTransactionRequest) returns (StopTransactionResponse); -} - -message VoteTransactionRequest { - enum Phase { - // UNKNOWN_PHASE is the unknown voting phase. This value has been the - // default because phases have been introduced. Eventually, using this - // phase will become unsupported. - UNKNOWN_PHASE = 0; - // PREPARED_PHASE is the prepratory phase. The data that is about to change - // is locked for concurrent modification, but changes have not yet been - // written to disk. - PREPARED_PHASE = 1; - // COMMITTED_PHASE is the committing phase. Data has been committed to disk - // and will be visible in all subsequent requests. - COMMITTED_PHASE = 2; - }; - - Repository repository = 1[(target_repository)=true]; - // ID of the transaction we're processing - uint64 transaction_id = 2; - // Name of the Gitaly node that's voting on a transaction. - string node = 3; - // SHA1 of the references that are to be updated - bytes reference_updates_hash = 4; - // Phase is the voting phase. - Phase phase = 5; -} - -message VoteTransactionResponse { - // The outcome of the given transaction telling the client whether the - // transaction should be committed or rolled back. - enum TransactionState { - COMMIT = 0; - ABORT = 1; - STOP = 2; - } - - TransactionState state = 1; -} - -message StopTransactionRequest { - Repository repository = 1[(target_repository)=true]; - // ID of the transaction we're processing - uint64 transaction_id = 2; -} - -message StopTransactionResponse {} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/repository_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/repository_service.rb deleted file mode 100644 index cd84ee1802..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/repository_service.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'licensee' - -module GitalyServer - class RepositoryService < Gitaly::RepositoryService::Service - include Utils - - def find_license(request, call) - repo = Gitlab::Git::Repository.from_gitaly(request.repository, call) - - short_name = begin - ::Licensee.license(repo.path).try(:key) - rescue Rugged::Error - end - - Gitaly::FindLicenseResponse.new(license_short_name: short_name || "") - end - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/gitaly_remote_repository.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/gitaly_remote_repository.rb deleted file mode 100644 index 9ed5b750c7..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/gitaly_remote_repository.rb +++ /dev/null @@ -1,113 +0,0 @@ -require 'gitlab-labkit' - -module Gitlab - module Git - class GitalyRemoteRepository < RemoteRepository - CLIENT_NAME = 'gitaly-ruby'.freeze - PEM_REXP = /[-]+BEGIN CERTIFICATE[-]+.+?[-]+END CERTIFICATE[-]+/m.freeze - - attr_reader :gitaly_client - - def initialize(gitaly_repository, call) - @gitaly_repository = gitaly_repository - @storage = gitaly_repository.storage_name - @gitaly_client = GitalyServer.client(call) - - @interceptors = [] - @interceptors << Labkit::Tracing::GRPC::ClientInterceptor.instance if Labkit::Tracing.enabled? - end - - def path - raise 'gitaly-ruby cannot access remote repositories by path' - end - - def empty? - !exists? || !has_visible_content? - end - - def branch_exists?(branch_name) - request = Gitaly::RefExistsRequest.new(repository: @gitaly_repository, ref: "refs/heads/#{branch_name}".b) - stub = Gitaly::RefService::Stub.new(address, credentials) - stub.ref_exists(request, request_kwargs).value - end - - def commit_id(revision) - request = Gitaly::FindCommitRequest.new(repository: @gitaly_repository, revision: revision.b) - stub = Gitaly::CommitService::Stub.new(address, credentials) - stub.find_commit(request, request_kwargs)&.commit&.id.presence - end - - def certs - raise 'SSL_CERT_DIR and/or SSL_CERT_FILE environment variable must be set' unless ENV['SSL_CERT_DIR'] || ENV['SSL_CERT_FILE'] - - return @certs if @certs - - files = [] - files += Dir["#{ENV['SSL_CERT_DIR']}/*"] if ENV['SSL_CERT_DIR'] - files += [ENV['SSL_CERT_FILE']] if ENV['SSL_CERT_FILE'] - files.sort! - - @certs = files.flat_map do |cert_file| - File.read(cert_file).scan(PEM_REXP).map do |cert| - begin - OpenSSL::X509::Certificate.new(cert).to_pem - rescue OpenSSL::OpenSSLError => e - Rails.logger.error "Could not load certificate #{cert_file} #{e}" - nil - end - end.compact - end.uniq.join("\n") - end - - def credentials - if URI(gitaly_client.address(storage)).scheme == 'tls' - GRPC::Core::ChannelCredentials.new certs - else - :this_channel_is_insecure - end - end - - private - - def exists? - request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repository) - stub = Gitaly::RepositoryService::Stub.new(address, credentials, interceptors: @interceptors) - stub.repository_exists(request, request_kwargs).exists - end - - def has_visible_content? - request = Gitaly::HasLocalBranchesRequest.new(repository: @gitaly_repository) - stub = Gitaly::RepositoryService::Stub.new(address, credentials, interceptors: @interceptors) - stub.has_local_branches(request, request_kwargs).value - end - - def address - addr = gitaly_client.address(storage) - addr = addr.sub(%r{^tcp://|^tls://}, '') if %w[tcp tls].include? URI(addr).scheme - addr - end - - def shared_secret - gitaly_client.shared_secret(storage).to_s - end - - def request_kwargs - @request_kwargs ||= begin - metadata = { - 'authorization' => "Bearer #{authorization_token}", - 'client_name' => CLIENT_NAME - } - - { metadata: metadata } - end - end - - def authorization_token - issued_at = Time.now.to_i.to_s - hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, shared_secret, issued_at) - - "v2.#{hmac}.#{issued_at}" - end - end - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/remote_repository.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/remote_repository.rb deleted file mode 100644 index 50f07ad945..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/remote_repository.rb +++ /dev/null @@ -1,71 +0,0 @@ -module Gitlab - module Git - # - # When a Gitaly call involves two repositories instead of one we cannot - # assume that both repositories are on the same Gitaly server. In this - # case we need to make a distinction between the repository that the - # call is being made on (a Repository instance), and the "other" - # repository (a RemoteRepository instance). This is the reason why we - # have the RemoteRepository class in Gitlab::Git. - class RemoteRepository - attr_reader :relative_path, :gitaly_repository - - def initialize(repository) - @relative_path = repository.relative_path - @gitaly_repository = repository.gitaly_repository - - @repository = repository - end - - def empty? - !@repository.exists? || @repository.empty? - end - - def commit_id(revision) - @repository.commit(revision)&.sha - end - - def branch_exists?(name) - @repository.branch_exists?(name) - end - - # Compares self to a Gitlab::Git::Repository - def same_repository?(other_repository) - gitaly_repository.storage_name == other_repository.storage && - gitaly_repository.relative_path == other_repository.relative_path - end - - def fetch_env(git_config_options: []) - gitaly_ssh = File.absolute_path(File.join(Gitlab.config.gitaly.bin_dir, 'gitaly-ssh')) - gitaly_address = gitaly_client.address(storage) - shared_secret = gitaly_client.shared_secret(storage) - - request = Gitaly::SSHUploadPackRequest.new(repository: gitaly_repository, git_config_options: git_config_options) - env = { - 'GITALY_ADDRESS' => gitaly_address, - 'GITALY_PAYLOAD' => request.to_json, - 'GITALY_WD' => Dir.pwd, - 'GIT_SSH_COMMAND' => "#{gitaly_ssh} upload-pack" - } - env['GITALY_TOKEN'] = shared_secret if shared_secret.present? - - env - end - - def path - @repository.path - end - - private - - # Must return an object that responds to 'address' and 'storage'. - def gitaly_client - raise NotImplementedError.new("Can't perform remote operations on superclass") - end - - def storage - gitaly_repository.storage_name - end - end - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/errors_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/errors_pb.rb deleted file mode 100644 index b281157683..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/errors_pb.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: errors.proto - -require 'google/protobuf/duration_pb' -require 'google/protobuf' - -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("errors.proto", :syntax => :proto3) do - add_message "gitaly.AccessCheckError" do - optional :error_message, :string, 1 - optional :protocol, :string, 2 - optional :user_id, :string, 3 - optional :changes, :bytes, 4 - end - add_message "gitaly.MergeConflictError" do - repeated :conflicting_files, :bytes, 1 - end - add_message "gitaly.ReferenceUpdateError" do - optional :reference_name, :bytes, 1 - optional :old_oid, :string, 2 - optional :new_oid, :string, 3 - end - add_message "gitaly.ResolveRevisionError" do - optional :revision, :bytes, 1 - end - add_message "gitaly.LimitError" do - optional :error_message, :string, 1 - optional :retry_after, :message, 2, "google.protobuf.Duration" - end - end -end - -module Gitaly - AccessCheckError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.AccessCheckError").msgclass - MergeConflictError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.MergeConflictError").msgclass - ReferenceUpdateError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceUpdateError").msgclass - ResolveRevisionError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ResolveRevisionError").msgclass - LimitError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.LimitError").msgclass -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/transaction_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/transaction_services_pb.rb deleted file mode 100644 index 4e21fc2f67..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/transaction_services_pb.rb +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: transaction.proto for package 'gitaly' - -require 'grpc' -require 'transaction_pb' - -module Gitaly - module RefTransaction - class Service - - include ::GRPC::GenericService - - self.marshal_class_method = :encode - self.unmarshal_class_method = :decode - self.service_name = 'gitaly.RefTransaction' - - rpc :VoteTransaction, ::Gitaly::VoteTransactionRequest, ::Gitaly::VoteTransactionResponse - rpc :StopTransaction, ::Gitaly::StopTransactionRequest, ::Gitaly::StopTransactionResponse - end - - Stub = Service.rpc_stub_class - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_client_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_client_spec.rb deleted file mode 100644 index 15943495e3..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_client_spec.rb +++ /dev/null @@ -1,136 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Git::GitalyRemoteRepository do - include TestRepo - include IntegrationClient - - describe '#new' do - let(:gitaly_repository) { double(storage_name: 'storage') } - let(:call) do - servers = Base64.strict_encode64({ - default: { - address: 'address', - token: 'the-secret-token' - } - }.to_json) - - double(metadata: { 'gitaly-servers' => servers }) - end - - context 'Labkit::Tracing enabled' do - before do - expect(Labkit::Tracing).to receive(:enabled?).and_return(true) - end - - it 'initializes with an interceptor' do - client = described_class.new(gitaly_repository, call) - expect(client.instance_variable_get(:@interceptors).size).to eq 1 - end - end - - context 'Labkit::Tracing disabled' do - before do - expect(Labkit::Tracing).to receive(:enabled?).and_return(false) - end - - it 'initializes with no interceptors' do - client = described_class.new(gitaly_repository, call) - expect(client.instance_variable_get(:@interceptors).size).to eq 0 - end - end - end - - let(:repository) { gitlab_git_from_gitaly(new_mutable_test_repo) } - describe 'certs' do - let(:client) { get_client("tls://localhost:#{GitalyConfig.dynamic_port('tls')}") } - - context 'when neither SSL_CERT_FILE and SSL_CERT_DIR is set' do - it 'Raises an error' do - expect { client.certs }.to raise_error 'SSL_CERT_DIR and/or SSL_CERT_FILE environment variable must be set' - end - end - - context 'when SSL_CERT_FILE is set' do - it 'Should return the correct certificate' do - cert = File.join(File.dirname(__FILE__), "testdata/certs/gitalycert.pem") - allow(ENV).to receive(:[]).with('GITLAB_TRACING').and_call_original - allow(ENV).to receive(:[]).with('SSL_CERT_DIR').and_return(nil) - allow(ENV).to receive(:[]).with('SSL_CERT_FILE').and_return(cert) - certs = client.certs - expect(certs).to eq File.read(cert) - end - end - - context 'when SSL_CERT_DIR is set' do - it 'Should return concatenation of gitalycert and gitalycert2 and gitalycert3 omitting gitalycertdup.pem' do - cert_pool_dir = File.join(File.dirname(__FILE__), "testdata/certs") - allow(ENV).to receive(:[]).with('GITLAB_TRACING').and_call_original - allow(ENV).to receive(:[]).with('SSL_CERT_DIR').and_return(cert_pool_dir) - allow(ENV).to receive(:[]).with('SSL_CERT_FILE').and_return(nil) - certs = client.certs - - # gitalycertdup.pem must exist and must be a duplicate of gitalycert.pem - expect(File.exist?(File.join(cert_pool_dir, "gitalycertdup.pem"))).to be true - expect(File.read(File.join(cert_pool_dir, "gitalycertdup.pem"))) - .to eq File.read(File.join(cert_pool_dir, "gitalycert.pem")) - - # No gitalycertdup.pem because duplicates should be removed - expected_certs = [File.read(File.join(cert_pool_dir, "gitalycert.pem")), - File.read(File.join(cert_pool_dir, "gitalycert2.pem")), - File.read(File.join(cert_pool_dir, "gitalycert3.pem"))].join "\n" - - expect(certs).to eq expected_certs - end - end - - context 'when both SSL_CERT_DIR and SSL_CERT_FILE are set' do - it 'Should return all certs in SSL_CERT_DIR + SSL_CERT_FILE' do - cert_pool_dir = File.join(File.dirname(__FILE__), "testdata/certs") - cert1_file = File.join(File.dirname(__FILE__), "testdata/gitalycert.pem") - allow(ENV).to receive(:[]).with('GITLAB_TRACING').and_call_original - allow(ENV).to receive(:[]).with('SSL_CERT_DIR').and_return(cert_pool_dir) - allow(ENV).to receive(:[]).with('SSL_CERT_FILE').and_return(cert1_file) - expected_certs_paths = [cert1_file, File.join(cert_pool_dir, "gitalycert2.pem"), File.join(cert_pool_dir, "gitalycert3.pem")] - - expected_certs = expected_certs_paths.map do |cert| - File.read cert - end.join("\n") - certs = client.certs - expect(certs).to eq expected_certs - end - end - end - - describe 'Connectivity' do - context 'tcp' do - let(:client) do - get_client("tcp://localhost:#{GitalyConfig.dynamic_port('tcp')}") - end - - it 'Should connect over tcp' do - expect(client).not_to be_empty - end - end - - context 'unix' do - let(:client) { get_client("unix:#{File.join(TMP_DIR, SOCKET_PATH)}") } - - it 'Should connect over unix' do - expect(client).not_to be_empty - end - end - - context 'tls' do - let(:client) { get_client("tls://localhost:#{GitalyConfig.dynamic_port('tls')}") } - - it 'Should connect over tls' do - cert = File.join(File.dirname(__FILE__), "testdata/certs/gitalycert.pem") - allow(ENV).to receive(:[]).with('GITLAB_TRACING').and_call_original - allow(ENV).to receive(:[]).with('SSL_CERT_DIR').and_return(nil) - allow(ENV).to receive(:[]).with('SSL_CERT_FILE').and_return(cert) - - expect(client).not_to be_empty - end - end - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_spec.rb deleted file mode 100644 index 325ec52055..0000000000 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/remote_repository_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Git::RemoteRepository do - include TestRepo - - let(:repository) { gitlab_git_from_gitaly(git_test_repo_read_only) } - let(:non_existing_gitaly_repo) do - Gitaly::Repository.new(storage_name: DEFAULT_STORAGE_NAME, relative_path: 'does-not-exist.git') - end - - subject { described_class.new(repository) } - - describe '#empty?' do - using RSpec::Parameterized::TableSyntax - - where(:repository, :result) do - repository | false - gitlab_git_from_gitaly(non_existing_gitaly_repo) | true - end - - with_them do - it { expect(subject.empty?).to eq(result) } - end - end - - describe '#commit_id' do - it 'returns an OID if the revision exists' do - expect(subject.commit_id('v1.0.0')).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') - end - - it 'is nil when the revision does not exist' do - expect(subject.commit_id('does-not-exist')).to be_nil - end - end - - describe '#branch_exists?' do - using RSpec::Parameterized::TableSyntax - - where(:branch, :result) do - 'master' | true - 'does-not-exist' | false - end - - with_them do - it { expect(subject.branch_exists?(branch)).to eq(result) } - end - end - - describe '#same_repository?' do - using RSpec::Parameterized::TableSyntax - - where(:other_repository, :result) do - repository | true - repository_from_relative_path(repository.relative_path) | true - repository_from_relative_path('wrong/relative-path.git') | false - end - - with_them do - it { expect(subject.same_repository?(other_repository)).to eq(result) } - end - end - - describe '#fetch_env' do - let(:remote_repository) { described_class.new(repository) } - - let(:gitaly_client) { double(:gitaly_client) } - let(:address) { 'fake-address' } - let(:shared_secret) { 'fake-secret' } - - subject { remote_repository.fetch_env } - - before do - allow(remote_repository).to receive(:gitaly_client).and_return(gitaly_client) - - expect(gitaly_client).to receive(:address).with(repository.storage).and_return(address) - expect(gitaly_client).to receive(:shared_secret).with(repository.storage).and_return(shared_secret) - end - - it { expect(subject).to be_a(Hash) } - it { expect(subject['GITALY_ADDRESS']).to eq(address) } - it { expect(subject['GITALY_TOKEN']).to eq(shared_secret) } - it { expect(subject['GITALY_WD']).to eq(Dir.pwd) } - - it 'creates a plausible GIT_SSH_COMMAND' do - git_ssh_command = subject['GIT_SSH_COMMAND'] - - expect(git_ssh_command).to start_with('/') - expect(git_ssh_command).to end_with('/gitaly-ssh upload-pack') - end - - it 'creates a plausible GITALY_PAYLOAD' do - req = Gitaly::SSHUploadPackRequest.decode_json(subject['GITALY_PAYLOAD']) - - expect(remote_repository.gitaly_repository).to eq(req.repository) - end - - context 'when the token is blank' do - let(:shared_secret) { '' } - - it { expect(subject.keys).not_to include('GITALY_TOKEN') } - end - end -end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.codeclimate.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.codeclimate.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.codeclimate.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.codeclimate.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.editorconfig b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.editorconfig similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.editorconfig rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.editorconfig index 9a7c5bb719..c8f2af68cb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.editorconfig +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.editorconfig @@ -24,6 +24,7 @@ max_line_length = 80 [**.proto] indent_style = space indent_size = 2 +max_line_length = 100 [**.rb] indent_size = 2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitattributes b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitattributes similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitattributes rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitattributes diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitignore b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitignore similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitignore rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitignore diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab-ci.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab-ci.yml similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab-ci.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab-ci.yml index 2f47e50ebf..30485d9513 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab-ci.yml +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab-ci.yml @@ -4,23 +4,32 @@ stages: - qa default: - image: registry.gitlab.com/gitlab-org/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-git-2.33-postgresql-11 + image: registry.gitlab.com/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}:git-2.36 tags: - gitlab-org variables: - DOCKER_DRIVER: overlay2 + FF_USE_FASTZIP: "true" + FF_NETWORK_PER_BUILD: "true" SAST_DISABLE_DIND: "true" SAST_DEFAULT_ANALYZERS: "gosec" DEBIAN_VERSION: "bullseye" + UBI_VERSION: "8.6" # We use Gitaly's Git version by default. GIT_VERSION: "default" - GO_VERSION: "1.17" + GO_VERSION: "1.18" RUBY_VERSION: "2.7" POSTGRES_VERSION: "12.6-alpine" PGBOUNCER_VERSION: "1.16.1" BUNDLE_PATH: "${CI_PROJECT_DIR}/.ruby" GOPATH: "${CI_PROJECT_DIR}/.go" + # Run tests with an intercepted home directory so that we detect cases where + # Gitaly picks up the gitconfig even though it ought not to. + GITALY_TESTING_INTERCEPT_HOME: "YesPlease" + # TEST_UID is the user ID we use to run tests in an unprivileged way. 9999 is + # chosen as a semi-random value so as to not interfer with any preexisting + # users. + TEST_UID: 9999 include: - template: Workflows/MergeRequest-Pipelines.gitlab-ci.yml @@ -68,23 +77,46 @@ include: policy: pull .test_template: &test_definition + needs: [] stage: test cache: - *cache_deps_configuration - *cache_gems_configuration - *cache_go_configuration services: - - postgres:${POSTGRES_VERSION} - variables: &postgres_variables + - name: postgres:${POSTGRES_VERSION} + alias: postgres + command: ["postgres", "-c", "max_connections=500"] + variables: &test_variables PGHOST: postgres PGPORT: 5432 PGUSER: postgres POSTGRES_DB: praefect_test POSTGRES_HOST_AUTH_METHOD: trust - TEST_REPORT: /tmp/go-tests-report.xml + TEST_REPORT: _unprivileged/go-tests-report.xml + TEST_COVERAGE_DIR: _unprivileged + TEST_FULL_OUTPUT: /tmp/test-output.log before_script: &test_before_script - go version - - while ! psql -h $PGHOST -U $PGUSER -c 'SELECT 1' > /dev/null; do echo "awaiting Postgres service to be ready..." && sleep 1 ; done && echo "Postgres service is ready!" + # Create a directory for the unprivileged user that we're running tests as. + # This is required so that we can still store test reports successfully. + - install --directory --owner=${TEST_UID} --group=${TEST_UID} _unprivileged + # We need to explicitly build all prerequisites so that we can run tests unprivileged. + - make -j$(nproc) build prepare-tests $(pwd)/_build/tools/gocover-cobertura $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease) + script: + # But the actual tests should run unprivileged. This assures that we pay + # proper attention to permission bits and that we don't modify the source + # directory. + - setpriv --reuid=${TEST_UID} --regid=${TEST_UID} --clear-groups --no-new-privs make ${TEST_TARGET} UNPRIVILEGED_CI_SKIP=YesPlease $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease) + + after_script: + - | + # Checking for panics in ${TEST_FULL_OUTPUT} + if [ "${CI_JOB_STATUS}" = "failed" ] && grep 'Output":"panic' "${TEST_FULL_OUTPUT}" > /dev/null; then + echo -e "\e[0Ksection_start:`date +%s`:panic_stack_traces[collapsed=true]\r\e[0K\e[0;31mPanic stack traces\e[0m" + ruby -e "require 'json'; f = File.read(ENV['TEST_FULL_OUTPUT']); f.lines.each do |l| out = JSON.parse(l); puts out['Output']; end" | awk '/^panic/ || /goroutine/,/^\s*$/' + echo -e "\e[0Ksection_end:`date +%s`:panic_stack_traces\r\e[0K" + fi artifacts: paths: - ruby/tmp/gitaly-rspec-test.log @@ -94,12 +126,14 @@ include: expire_in: 1 week danger-review: + needs: [] stage: build allow_failure: true variables: - BUNDLE_GEMFILE: danger/Gemfile + GITLAB_DANGERFILES_VERSION: "3.1.0" build: + needs: [] stage: build cache: - <<: *cache_deps_configuration @@ -114,11 +148,12 @@ build: - _support/test-boot . ${TEST_BOOT_ARGS} parallel: matrix: - - GO_VERSION: [ "1.16", "1.17" ] + - GO_VERSION: [ "1.17", "1.18" ] TEST_BOOT_ARGS: "--bundled-git" - GIT_VERSION: "v2.33.0" build:binaries: + needs: [] stage: build cache: - *cache_deps_configuration @@ -138,53 +173,50 @@ build:binaries: expire_in: 6 months parallel: matrix: - - GO_VERSION: [ "1.16", "1.17" ] + - GO_VERSION: [ "1.17", "1.18" ] test: <<: *test_definition - script: - # We need to prepare test dependencies as privileged user. - - make -j$(nproc) build prepare-tests $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease) - # But the actual tests should run unprivileged. This assures that we pay - # proper attention to permission bits and that we don't modify the source - # directory. - - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make ${TARGET} SKIP_RSPEC_BUILD=YesPlease $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease) parallel: matrix: # The following jobs all test with our default Git version, which is # using bundled Git binaries. - - GO_VERSION: [ "1.16", "1.17" ] - TARGET: test - - TARGET: [ test-with-proxies, test-with-praefect, race-go ] + - GO_VERSION: [ "1.17", "1.18" ] + TEST_TARGET: test + - TEST_TARGET: [ test-with-proxies, test-with-praefect, race-go ] # We also verify that things work as expected with a non-bundled Git # version matching our minimum required Git version. - - TARGET: test + - TEST_TARGET: test GIT_VERSION: "v2.33.0" # Execute tests with our minimum required Postgres version, as well. If # the minimum version changes, please change this to the new minimum # version. Furthermore, please make sure to update the minimum required # version in `datastore.CheckPostgresVersion()`. - POSTGRES_VERSION: "11.14-alpine" - TARGET: [ test, test-with-praefect ] + TEST_TARGET: [ test, test-with-praefect ] test:coverage: <<: *test_definition - script: - # We need to explicitly build all prerequisites so that we can run tests unprivileged. - - make -j$(nproc) build prepare-tests $(pwd)/_build/tools/gocover-cobertura - - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make cover SKIP_RSPEC_BUILD=YesPlease + coverage: /^total:\t+\(statements\)\t+\d+\.\d+%$/ artifacts: reports: - cobertura: _build/cover/cobertura.xml + coverage_report: + coverage_format: cobertura + path: ${TEST_COVERAGE_DIR}/cobertura.xml + variables: + <<: *test_variables + TEST_TARGET: "cover" test:pgbouncer: <<: *test_definition services: - - postgres:${POSTGRES_VERSION} + - name: postgres:${POSTGRES_VERSION} + alias: postgres + command: ["postgres", "-c", "max_connections=500"] - name: bitnami/pgbouncer:${PGBOUNCER_VERSION} alias: pgbouncer variables: - <<: *postgres_variables + <<: *test_variables # The following variables are used by PgBouncer to connect to Postgres. POSTGRESQL_HOST: "${PGHOST}" # The image doesn't support setting `auth_user`, so we're cheating and use @@ -205,27 +237,18 @@ test:pgbouncer: PGPORT_PGBOUNCER: 6432 # We need to enable per-build networking such that the PgBouncer service # can reach Postgres. - FF_NETWORK_PER_BUILD: "true" - before_script: - - *test_before_script - - while ! psql -h "${PGHOST_PGBOUNCER}" -p "${PGPORT_PGBOUNCER}" -U "${PGUSER}" -c 'SELECT 1' > /dev/null; do echo "awaiting PgBouncer service to be ready..." && sleep 1 ; done && echo "PgBouncer service is ready!" - script: - # We need to explicitly build all prerequisites so that we can run tests unprivileged. - - make -j$(nproc) build prepare-tests - - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make test-with-praefect SKIP_RSPEC_BUILD=YesPlease + TEST_TARGET: "test-with-praefect" test:nightly: <<: *test_definition - script: - - go version - - make -j$(nproc) build prepare-tests - - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make ${TARGET} SKIP_RSPEC_BUILD=YesPlease parallel: matrix: - GIT_VERSION: [ "master", "next" ] - TARGET: [ test, test-with-proxies, test-with-praefect ] + TEST_TARGET: [ test, test-with-proxies, test-with-praefect ] rules: - if: '$CI_PIPELINE_SOURCE == "schedule"' + - when: manual + allow_failure: true test:praefect_smoke: <<: *test_definition @@ -235,13 +258,51 @@ test:praefect_smoke: - ./_build/bin/praefect -config config.praefect.toml sql-ping - ./_build/bin/praefect -config config.praefect.toml sql-migrate +test:sha256: + <<: *test_definition + parallel: + matrix: + - TEST_TARGET: [ test, test-with-praefect ] + GITALY_TESTING_ENABLE_SHA256: "YesPlease" + +test:fips: + <<: *test_definition + tags: + - fips + image: registry.gitlab.com/gitlab-org/gitlab-build-images/ubi-${UBI_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}:git-2.36 + before_script: + - test "$(cat /proc/sys/crypto/fips_enabled)" = "1" || (echo "System is not running in FIPS mode" && exit 1) + - *test_before_script + parallel: + matrix: + - TEST_TARGET: [ test, test-with-praefect ] + FIPS_MODE: "YesPlease" + rules: + # When running in a fork of Gitaly we don't have the runners available, and + # consequentially this job would fail anyway. So we configure the job to be + # a manual one in that case. + - if: $CI_PROJECT_PATH != "gitlab-org/gitaly" + when: manual + allow_failure: true + # Otherwise, we automatically run the job when either merging to the + # default branch or when the merge request has a FIPS label. + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_MERGE_REQUEST_LABELS =~ /FIPS/ + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: manual + allow_failure: true + verify: + needs: [] stage: test cache: - *cache_deps_configuration - *cache_gems_configuration - *cache_go_configuration script: + # Download the dependencies in case there was no cache hit, otherwise + # golang-ci lint will timeout downloading them. + - go mod download - make -j$(nproc) verify artifacts: paths: @@ -251,18 +312,18 @@ verify: when: on_failure dbschema: + needs: [] stage: test cache: - *cache_deps_configuration + - *cache_gems_configuration - *cache_go_configuration services: # The database version we use must match the version of `pg_dump` we have # available in the build image. - postgres:11.13-alpine variables: - <<: *postgres_variables - before_script: - - while ! psql -h $PGHOST -U $PGUSER -c 'SELECT 1' > /dev/null; do echo "awaiting Postgres service to be ready..." && sleep 1 ; done && echo "Postgres service is ready!" + <<: *test_variables script: - make dump-database-schema no-changes artifacts: @@ -271,14 +332,21 @@ dbschema: when: on_failure gosec-sast: - dependencies: [] + needs: [] cache: - *cache_go_configuration variables: GOPATH: "/go" before_script: - - apk add pkgconfig libgit2-dev gcc libc-dev - - mv .go /go + # Our pipeline places GOPATH to $CI_PROJECT_DIR/.go so it can be cached. + # This causes gosec-sast to find the module cache and scan all the sources of + # the dependencies as well. This makes the scan time grow massively. This is + # avoided by this job moving the GOPATH outside of the project directory along + # with the cached modules if they were successfully extracted. + # + # SAST_EXCLUDED_PATHS is not sufficient as it only filters out the results but + # still performs the expensive scan. + - if [ -d .go ]; then mv .go $GOPATH; fi rules: - if: $SAST_DISABLED when: never @@ -287,11 +355,7 @@ gosec-sast: - if: $CI_COMMIT_TAG license_scanning: - dependencies: [] - cache: [] - before_script: - - sudo apt-get update - - sudo apt-get install -y libicu-dev libgit2-dev cmake + needs: [] rules: - if: $LICENSE_SCANNING_DISABLED when: never @@ -302,8 +366,7 @@ license_scanning: LICENSE_FINDER_CLI_OPTS: '--aggregate-paths=. ruby' gemnasium-dependency_scanning: - dependencies: [] - cache: [] + needs: [] rules: - if: $DEPENDENCY_SCANNING_DISABLED when: never @@ -312,10 +375,7 @@ gemnasium-dependency_scanning: - if: $CI_COMMIT_TAG secret_detection: - dependencies: [] - cache: [] - inherit: - default: false + needs: [] rules: - if: $SECRET_DETECTION_DISABLED when: never @@ -324,6 +384,7 @@ secret_detection: - if: $CI_COMMIT_TAG trigger-qa: + needs: [] stage: qa trigger: project: gitlab-org/build/omnibus-gitlab-mirror @@ -342,9 +403,9 @@ trigger-qa: GITALY_SERVER_VERSION: $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA - when: manual allow_failure: true - needs: [] qa:nightly-praefect-migration-test: + needs: [] stage: qa trigger: project: gitlab-org/quality/praefect-migration-testing diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/CODEOWNERS b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/CODEOWNERS new file mode 100644 index 0000000000..b35259bd61 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/CODEOWNERS @@ -0,0 +1,10 @@ +# When adding a group as a code owner, make sure to invite the group to the +# project here: https://gitlab.com/gitlab-org/gitaly/-/project_members +# As described in https://docs.gitlab.com/ee/user/project/code_owners.html + +[Code] +* @gl-gitaly + +^[Documentation] +/doc/ @eread +*.md @eread diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/changelog_config.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/changelog_config.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/changelog_config.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/changelog_config.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Config Change.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Config Change.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Config Change.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Config Change.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Default.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Default.md new file mode 100644 index 0000000000..d818d9af96 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Default.md @@ -0,0 +1,5 @@ + + + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Demo.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Demo.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Demo.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Demo.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Feature Flag Roll Out.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Feature Flag Roll Out.md similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Feature Flag Roll Out.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Feature Flag Roll Out.md index ffa0002de3..6eab09d89b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Feature Flag Roll Out.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Feature Flag Roll Out.md @@ -7,7 +7,7 @@ Enable the `:feature_name` feature flag ... ## Owners - Team: Gitaly -- Most appropriate slack channel to reach out to: `#g_create_gitaly` +- Most appropriate slack channel to reach out to: `#g_gitaly` - Best individual to reach out to: NAME ## Expectations diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Gitaly Client Update.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Gitaly Client Update.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Gitaly Client Update.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Gitaly Client Update.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Security Release.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Security Release.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Security Release.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Security Release.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Support Request.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Support Request.md similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Support Request.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Support Request.md index 907083cc86..522f12908f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/issue_templates/Support Request.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Support Request.md @@ -10,10 +10,16 @@ As we collaborate on resolution of this issue, the Gitaly team will attempt to u _The goal is to keep these requests public. However, if customer information is required to the support request, please be sure to mark this issue as confidential._ +This request template is part of [Gitaly Team's intake process](https://about.gitlab.com/handbook/engineering/development/dev/gitaly/#how-to-contact-the-team). + ## Customer Information **Salesforce Link:** + +**Zendesk Ticket:** + **Installation Size:** + **Architecture Information:** **Slack Channel:** @@ -28,6 +34,8 @@ _The goal is to keep these requests public. However, if customer information is ### Problem Description @@ -48,5 +56,5 @@ For a good rule of thumb, please refer to the bug prioritization framework locat - [ ] Severity realistically set - [ ] Clearly articulated what is needed from the Gitaly team to support your request by filling out the _What specifically do you need from the Gitaly team_ -/label ~"Gitaly Customer Issue" ~"group::gitaly" ~"devops::create" -/cc @mjwood +/label ~"Gitaly Customer Issue" ~"group::gitaly" ~"devops::systems" ~"section::enablement" ~"workflow::problem validation" +/cc @mjwood @andrashorvath diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Team Member Onboarding.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Team Member Onboarding.md new file mode 100644 index 0000000000..c3ebebbebe --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/issue_templates/Team Member Onboarding.md @@ -0,0 +1,38 @@ +# Gitaly Team specific onboarding + +Welcome to [Gitaly Team](https://about.gitlab.com/handbook/engineering/development/enablement/systems/gitaly/)!! + +The following items are the team-specific extension of your onboarding issue. +Please complete all but the "Reading material" section in your first few working days. + +- Join Slack channels: + - [ ] [#gitaly-lounge](https://gitlab.slack.com/archives/gitaly-lounge) (internal team affairs, generic informal chat) + - [ ] [#g_gitaly](https://gitlab.slack.com/archives/g_gitaly) (important communication also outside the team) + - [ ] [#git-core](https://gitlab.slack.com/archives/git-core) (conversations re git itself) + - [ ] [#s_enablement](https://gitlab.slack.com/archives/s_enablement) (section-wide communication) + - [ ] [#gitaly-alerts](https://gitlab.slack.com/archives/gitaly-alerts) (Alerts for gitaly releases and failures) +- Ask your manager or your mentor in order to: + - [ ] get Maintainer access to the [@gl-gitaly](https://gitlab.com/groups/gl-gitaly/-/group_members) group + - [ ] be added to the weekly team meeting and [meeting notes](https://docs.google.com/document/d/1k1hY0ZdeFUnSqF6GUToFaJEtVIN_SjWeaRdx1V0i25E/edit) + - [ ] be added to [Geekbot](https://app.geekbot.com/dashboard) for daily Slack standup updates +- Open issues / Access Requests to: + - [ ] join the @gitalyteam Slack group ([example](https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/15868)) + - [ ] get access to [Stackdriver](https://about.gitlab.com/handbook/engineering/monitoring/#go-services) + - [ ] join the `gcp-host-profiles-sg@gitlab.com` GCP group for access to [periodic profiling data](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1433#note_901717231) + - [ ] request access to [Zendesk](https://about.gitlab.com/handbook/support/internal-support/#requesting-a-zendesk-light-agent-account) + - [ ] create [RubyGems.org](https://rubygems.org/sign_up) account and request access to `gitaly` gem +- If transferring from another team within GitLab: + - [ ] update your [Team page entry](https://about.gitlab.com/handbook/git-page-update/#12-add-yourself-to-the-team-page) + - [ ] update your Slack profile ("What I do") + - [ ] update your Zoom title +- Reading material + - [ ] check out the [README](https://gitlab.com/gitlab-org/gitaly/-/blob/master/README.md) at https://gitlab.com/gitlab-org/gitaly, without getting lost in too much detail + - [ ] watch video [presentations](https://gitlab.com/gitlab-org/gitaly/-/blob/master/README.md#presentations) linked in README + - [ ] checkout the Gitaly doc [README](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/README.md) + - [ ] get familiar with how we [schedule work](https://gitlab.com/gitlab-org/gitaly/-/issues/4095) and possibly bookmark the [Gitaly ongoing work issue board](https://gitlab.com/groups/gitlab-org/-/boards/1140874?label_name%5B%5D=group%3A%3Agitaly&milestone_title=Upcoming) + - [ ] familiarize yourself with the [Merge request workflow](https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html) specific to working _on_ GitLab (the whole page) + - [ ] check out the [team page](https://about.gitlab.com/handbook/engineering/development/enablement/systems/gitaly/) + +/confidential +/assign me +/cc @andrashorvath diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/merge_request_templates/RFC.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/merge_request_templates/RFC.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/merge_request_templates/RFC.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/merge_request_templates/RFC.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/merge_request_templates/Security Release.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/merge_request_templates/Security Release.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.gitlab/merge_request_templates/Security Release.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.gitlab/merge_request_templates/Security Release.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.golangci.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.golangci.yml similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.golangci.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.golangci.yml index 4ef4e7da72..2c667e980c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.golangci.yml +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.golangci.yml @@ -1,7 +1,7 @@ # options for analysis running run: # timeout for analysis, e.g. 30s, 5m, default is 1m - timeout: 5m + timeout: 10m modules-download-mode: readonly # list of useful linters could be found at https://github.com/golangci/awesome-go-linters @@ -34,6 +34,7 @@ linters: - staticcheck - structcheck - stylecheck + - thelper - unconvert - unused - varcheck @@ -58,10 +59,34 @@ linters-settings: # they're tested as expected. - ^context.Background$ - ^context.TODO$ + # Tests should not set the bare environment functions, but instead use + # `t.Setenv()` or `testhelper.Unsetenv()`. These functions have sanity + # checks to verify we don't use `t.Parallel()` when setting envvars. + - ^os.Setenv$ + - ^os.Unsetenv$ + revive: + rules: + - name: context-as-argument + arguments: + # The context should always be first, except in our testing packages. + allowTypesBefore: "*testing.T,*testing.B,testing.TB" stylecheck: # ST1000 checks for missing package comments. We don't use these for most # packages, so let's disable this check. checks: [ "all", "-ST1000" ] + thelper: + test: + # The following linter would check whether we always call `t.Helper()` in + # functions that are not the top-level testcase. While this is nice in + # theory, in practice it would also impact e.g. usecases like + # `testhelper.NewFeatureSets(...).Run(t, testWithFeatures)`. This isn't + # really what we want, so we just leave these as disabled for the time + # being. + begin: false + benchmark: + begin: false + tb: + begin: false issues: exclude-use-default: false @@ -70,10 +95,6 @@ issues: - forbidigo # This fine thing excludes all paths which don't end with "_test.go". path: "^([^_]|_([^t]|t([^e]|e([^s]|s([^t]|t([^\\.]|\\.([^g]|g[^o])))))))*$" - - linters: - - revive - text: "context.Context should be the first parameter of a function" - path: "_test.go" - linters: - errcheck text: "Error return value of `[^`]+.(Close|Serve)` is not checked" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.mailmap b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.mailmap similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.mailmap rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.mailmap diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.ruby-version b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.ruby-version similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.ruby-version rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.ruby-version diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.tool-versions b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.tool-versions similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.tool-versions rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.tool-versions index 7929518f88..687c9652e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/.tool-versions +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/.tool-versions @@ -1,3 +1,3 @@ # Versions of Gitaly dependencies managed by asdf. -golang 1.17.7 1.16.14 +golang 1.18.3 1.17.9 ruby 2.7.5 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CHANGELOG.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CHANGELOG.md similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CHANGELOG.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CHANGELOG.md index f3431806fa..e168cf9d1c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CHANGELOG.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CHANGELOG.md @@ -1,5 +1,344 @@ # Gitaly changelog +## 15.4.2 (2022-10-04) + +No changes. + +## 15.4.1 (2022-09-29) + +No changes. + +## 15.4.0 (2022-09-21) + +### Added (1 change) + +- [praefect: Add 'track-repositories' subcommand](gitlab-org/gitaly@69420b517a18582cfefeab4297c0ac2456b96de8) ([merge request](gitlab-org/gitaly!4845)) + +### Fixed (2 changes) + +- [featureflag: Add more constraint to flag name](gitlab-org/gitaly@b619bfb798e6ad9924f82dbe337a1ac6133a1fd6) by @blanet ([merge request](gitlab-org/gitaly!4793)) +- [Fix Repository SearchFilesByName not handle non-ASCII file names well](gitlab-org/gitaly@8ba76ca0cd834574e9db2d611a8152457f8e82d0) ([merge request](gitlab-org/gitaly!4827)) + +### Changed (4 changes) + +- [repository: Use git-cat-file to calculate repository size](gitlab-org/gitaly@62fa713f85a6fdc13fb6d330aadfc10b9f2df460) ([merge request](gitlab-org/gitaly!4797)) +- [Update rack and rouge gems to match GitLab Rails](gitlab-org/gitaly@94bdfbe63229ce05d0bf2c5e6bd867e415de6af9) ([merge request](gitlab-org/gitaly!4817)) +- [Update ffi gem to v1.15.5](gitlab-org/gitaly@03b47d49bc11adcc8398947a632e3e41266a2cc8) ([merge request](gitlab-org/gitaly!4816)) +- [Update pg_query gem to v2.1.3](gitlab-org/gitaly@3365f28c76212f1664f5fc1e6934abd1d065c83c) ([merge request](gitlab-org/gitaly!4815)) + +### Other (2 changes) + +- [Public Grafana dashboards does not exist any more](gitlab-org/gitaly@ef80fcf20a02fa6fd4010d50d8a7cfa030b5b39c) ([merge request](gitlab-org/gitaly!4831)) +- [Add support for MulanPSL-2.0 in license detection](gitlab-org/gitaly@5a64218610feb05b833647b4e703386b2d1564f0) ([merge request](gitlab-org/gitaly!4825)) + +## 15.3.3 (2022-09-01) + +No changes. + +## 15.3.2 (2022-08-30) + +No changes. + +## 15.3.1 (2022-08-22) + +No changes. + +## 15.3.0 (2022-08-19) + +### Added (2 changes) + +- [praefect: Add -db-only flag to remove repository](gitlab-org/gitaly@2d958aba0c67cc9887e667ee9b60f0bf165b355a) ([merge request](gitlab-org/gitaly!4715)) +- [proto: Introduce structured UserCreateTagError](gitlab-org/gitaly@d3c675691d366b9c751f0f17d1eb61c87b509ab6) ([merge request](gitlab-org/gitaly!4741)) + +### Fixed (16 changes) + +- [objectpool: Default-enable pruning of refs to fix reference conflicts](gitlab-org/gitaly@02082a58a64fae83ae59aba60aa8c44e882e66e4) ([merge request](gitlab-org/gitaly!4807)) +- [git: Fix warning on startup about Git binary fallback](gitlab-org/gitaly@96bdc9439798f202647360242cb5109cece5e2d8) ([merge request](gitlab-org/gitaly!4805)) +- [linguist: Ensure empty files are omitted in totals](gitlab-org/gitaly@0b310f3cb26889f74f8b3024efc683279b2c6ef6) ([merge request](gitlab-org/gitaly!4791)) +- [repository: Fix passing zero OID to WriteRef](gitlab-org/gitaly@2db323c12071fc8f1ff16f42ecadac09db0b95fd) ([merge request](gitlab-org/gitaly!4794)) +- [localrepo: Speed up fetches by disabling computation of forced updates](gitlab-org/gitaly@c466baa1c30afd14838f8cba97c6bca958ecc3f1) ([merge request](gitlab-org/gitaly!4783)) +- [objectpool: Speed up fetches by disabling computation of forced updates](gitlab-org/gitaly@8b14bc6b52f0ca20bf25a9c22abea76917a31cea) ([merge request](gitlab-org/gitaly!4783)) +- [server: Give clients grace-period for keepalives](gitlab-org/gitaly@6a02746cd6edc7d3e87e8c340ad271e8859b4956) ([merge request](gitlab-org/gitaly!4772)) +- [ref: Fix `Internal` errors in `FindTag()` when tag doesn't exist](gitlab-org/gitaly@453ac57fc19b14da7f579df8d5c3a36adaa2ef3a) ([merge request](gitlab-org/gitaly!4771)) +- [ssh: Fix silent errors when SSHReceivePack fails](gitlab-org/gitaly@83a8bf540aecf84c8aed6275b2219a00bedf1dfd) ([merge request](gitlab-org/gitaly!4766)) +- [ssh: Handle timeout waiting on packfile negotiation with proper errors](gitlab-org/gitaly@5caeaa1d3e5694a1f9179b5cf09aa663f4f75b42) ([merge request](gitlab-org/gitaly!4761)) +- [objectpool: Fix conflicting references when fetching into pools](gitlab-org/gitaly@018958fb1cb4a8550d15bbd096b55fdee9f2a3b4) ([merge request](gitlab-org/gitaly!4745)) +- [operations: Introduce structured errors for UserCreateTag](gitlab-org/gitaly@0fedeb41fda77a8024f923060b646648dbb753bb) ([merge request](gitlab-org/gitaly!4743)) +- [operations: Validate tag name more thoroughly in UserCreateTag](gitlab-org/gitaly@928c1f5793058730bc1e5eefdd08ae3a067205ea) ([merge request](gitlab-org/gitaly!4740)) +- [ssh: Improve errors for fetches canceled by the user](gitlab-org/gitaly@a2fee3dd53319f08a5971d9474c48cf1a58e031a) ([merge request](gitlab-org/gitaly!4731)) +- [git: Don't advertise internal references via git-upload-pack(1)](gitlab-org/gitaly@4a789524c7a786a2c8fb0019c3ac20a66c1f9431) ([merge request](gitlab-org/gitaly!4727)) +- [updateref: Ignore failures of custom post-receive hooks](gitlab-org/gitaly@13a18236e716994437345474f1879afca64e3b3f) ([merge request](gitlab-org/gitaly!4714)) + +### Changed (9 changes) + +- [Use semantic sort for tags](gitlab-org/gitaly@7750e95b0c1642eba9e325cf2dffbdd25b37c928) ([merge request](gitlab-org/gitaly!4336)) +- [Default enable Praefect generated replica paths](gitlab-org/gitaly@60f197836831e160ca82d1eecd36110c1e7f4b13) ([merge request](gitlab-org/gitaly!4809)) +- [git: Upgrade default Git distribution to v2.37.1.gl1](gitlab-org/gitaly@4e8e6fc81206f73218b976d44156b9bd00f60a1a) ([merge request](gitlab-org/gitaly!4787)) +- [git: Default-enable use of Git v2.37.1.gl1](gitlab-org/gitaly@aa2dda0777880de1744efbd58fa1a95b4c2fbfa4) ([merge request](gitlab-org/gitaly!4782)) +- [Update nokogiri gem to v1.13.8](gitlab-org/gitaly@2c74a182c4b8ce4d4094b3bfca859204ac82bd63) ([merge request](gitlab-org/gitaly!4776)) +- [refs: Return structured errors for DeleteRefs](gitlab-org/gitaly@ae728915534c37a9e44fad0d78ef936c6abea765) ([merge request](gitlab-org/gitaly!4554)) +- [Update google-protobuf Ruby gem to v3.21.3](gitlab-org/gitaly@c8cf249ff66ac6011ab25298119210e56745ff8c) ([merge request](gitlab-org/gitaly!4762)) +- [Bump all Rails-related gems to v6.1.6.1](gitlab-org/gitaly@a3535f2bf3963e4a9aaf4feed645c05abed45432) ([merge request](gitlab-org/gitaly!4759)) +- [objectpool: Remove feature flag guarding heuristical repo maintenance](gitlab-org/gitaly@fe6d9ada1acab1bac4c298047cbf9299b4c833b4) ([merge request](gitlab-org/gitaly!4757)) + +### Removed (1 change) + +- [Remove 'exact_pagination_token_match' feature flag](gitlab-org/gitaly@5624136ef16c77cf1b795e5ea658e09991243ae4) ([merge request](gitlab-org/gitaly!4724)) + +### Security (2 changes) + +- [Exclude github.com/gin-gonic/gin vulnerable to CVE-2020-28483](gitlab-org/gitaly@790de3895243fac0c550c8f60e230fb9eb58febb) ([merge request](gitlab-org/gitaly!4784)) +- [git: Fix missing consistency checks for clones](gitlab-org/gitaly@b5d0d04155ad7b464ab5c63440b55e9ca514ae6e) + +## 15.2.4 (2022-08-30) + +No changes. + +## 15.2.3 (2022-08-22) + +No changes. + +## 15.2.2 (2022-08-01) + +No changes. + +## 15.2.1 (2022-07-28) + +### Security (1 change) + +- [Import via git protocol allows to bypass checks on repository](gitlab-org/security/gitaly@d7af133ce2c05dcfc93ebf15a47154a0cd40e9bd) ([merge request](gitlab-org/security/gitaly!56)) + +## 15.2.0 (2022-07-21) + +### Added (4 changes) + +- [cgroups: Only enable metrics if option is turned on](gitlab-org/gitaly@fde4a4702a17509f12e63732f7778da19972278f) ([merge request](gitlab-org/gitaly!4619)) +- [Add an option to skip flat paths for tree entries](gitlab-org/gitaly@a6b5618baa4c722890812606876501f5eb65f20c) ([merge request](gitlab-org/gitaly!4693)) +- [git: Add a gitversion label](gitlab-org/gitaly@a5e97fc55aebf67ce14a5da64103b8763abb6f23) ([merge request](gitlab-org/gitaly!4460)) +- [Add proto for FullPath RPC](gitlab-org/gitaly@19f47f2757ab7afdbb22e0ae7a0a60e96cc773e3) ([merge request](gitlab-org/gitaly!4642)) + +### Fixed (25 changes) + +- [config: Don't treat EPERM as error when signalling](gitlab-org/gitaly@b32f0ad8f66f42057dabfac127e3d1ca75cda7e7) ([merge request](gitlab-org/gitaly!4716)) +- [repository: Fix commit-graphs referencing pruned commits after PruneUnreachableObjects](gitlab-org/gitaly@e972e73d08c5ed6bd6491a523204d2812c659ea4) ([merge request](gitlab-org/gitaly!4695)) +- [repository: Fix commit-graphs referencing pruned commits after GC](gitlab-org/gitaly@0920b15a01e1fb7ac54fd36ae29802b2855d9e4b) ([merge request](gitlab-org/gitaly!4695)) +- [housekeeping: Fix commit-graphs referencing pruned commits](gitlab-org/gitaly@83802e116052ba032ddb76770bf29ff346b547ea) ([merge request](gitlab-org/gitaly!4695)) +- [git: Fix missing reverse indices for some Git commands](gitlab-org/gitaly@a99108e67146e10d84dd0370db8f643501f12ef1) ([merge request](gitlab-org/gitaly!4712)) +- [Pin auxiliary binaries the main Gitaly binary invokes](gitlab-org/gitaly@19636a5caa57a0a580abab958cb06a086bf1b794) ([merge request](gitlab-org/gitaly!4670)) +- [objectpool: Switch to use OptimizeRepository for pool repos](gitlab-org/gitaly@410295810f9b3e7d94d0ce07b1a3ad1682023746) ([merge request](gitlab-org/gitaly!4708)) +- [housekeeping: Fix delta islands for pool repositories](gitlab-org/gitaly@81a6acbd3fb8ab30f0e4a1276722b55e780ba23c) ([merge request](gitlab-org/gitaly!4708)) +- [housekeeping: Fix off-by-one in packfile count required to repack](gitlab-org/gitaly@84e99923567045f71b90b804f07f81ea4fef977d) ([merge request](gitlab-org/gitaly!4708)) +- [maintenance: Remove per-repository timeouts in nightly maintenance](gitlab-org/gitaly@608d1a1124ca4f5290910e3c1d1a59784f07f3f3) ([merge request](gitlab-org/gitaly!4711)) +- [Prune leftover runtime directories on startup](gitlab-org/gitaly@d760915a3736498f5c422e9e43aafd7a3f5c5035) ([merge request](gitlab-org/gitaly!4700)) +- [datastore: Extend timeout to retrieve Postgres server's version](gitlab-org/gitaly@83d0af99ad184df110f0d5bd2865a353b226983b) ([merge request](gitlab-org/gitaly!4710)) +- [git: Fix commit-graph corruption caused by corrected committer dates](gitlab-org/gitaly@a8f996a321e73597a0c726576bc9b8c1d03d9a07) ([merge request](gitlab-org/gitaly!4677)) +- [coordinator: Fix feature flags being set twice](gitlab-org/gitaly@a8c7c3e210bf5f0a2f7ef2418248429e2187cba0) ([merge request](gitlab-org/gitaly!4675)) +- [command: Export environment variable to force-enable all feature flags](gitlab-org/gitaly@3e466e74e72b5b02c5da0b57bb771995f199efae) ([merge request](gitlab-org/gitaly!4672)) +- [operations: Honor feature flag for structured errors in UserCherryPick](gitlab-org/gitaly@6d32a81bc028feccddabdb5a6c369b72afa1ccaf) ([merge request](gitlab-org/gitaly!4669)) +- [repository: Fix clone credentials leaking via command line arguments](gitlab-org/gitaly@0ef2a43087a702169fb0ab98776b4260a51ad455) ([merge request](gitlab-org/gitaly!4668)) +- [ssh: Fix racy cleanup of read monitor's pipe](gitlab-org/gitaly@584b529003efe914d497720620e387b17be146aa) ([merge request](gitlab-org/gitaly!4615)) +- [command: Fix race with setting Cgroup path and context cancellation](gitlab-org/gitaly@2068a98fd460bf6a6079806bb4466b1f2c757be2) ([merge request](gitlab-org/gitaly!4615)) +- [command: Fix race with setting command names and context cancellation](gitlab-org/gitaly@c25f5094e1a0916b133358f078f1496985c28f00) ([merge request](gitlab-org/gitaly!4615)) +- [operations: Always enable structured errors in UserDeleteBranch](gitlab-org/gitaly@76483dccec0600278845dc825516ff3896595f19) ([merge request](gitlab-org/gitaly!4660)) +- [localrepo: Speed up calculating size for repo with excluded alternates](gitlab-org/gitaly@c9c426cf6297984a2639f4036f34fc725fa3a8b2) ([merge request](gitlab-org/gitaly!4657)) +- [git: Always disable use of alternate refs for git-fetch(1)](gitlab-org/gitaly@2383696d128d2c448ba5aca6a7fb3a688af11756) ([merge request](gitlab-org/gitaly!4657)) +- [Ensure there is a receive hooks payload before using it](gitlab-org/gitaly@227a594d2128d80f4239fea952e33eb372740782) ([merge request](gitlab-org/gitaly!4655)) +- [praefect: Don't overwrite '-older-than' flag](gitlab-org/gitaly@cb0fb4c0ff91825e8a35c1dbf6a5795535b0d7bf) ([merge request](gitlab-org/gitaly!4644)) + +### Changed (6 changes) + +- [Makefile: Update Git to v2.37.1](gitlab-org/gitaly@be8b2457721e1ec154ecb6e037e797b37578ea62) ([merge request](gitlab-org/gitaly!4706)) +- [cgroups: Adjust metric names](gitlab-org/gitaly@c0955807f263552ff28ef09519f249498aa3b7cd) ([merge request](gitlab-org/gitaly!4619)) +- [operations: Convert UserCherryPick to return structured errors](gitlab-org/gitaly@b253d7c82adab0e4df280be61c5a5ea892f2cb71) ([merge request](gitlab-org/gitaly!4585)) +- [Use FIPS-compliant encryption for gitaly-ruby in FIPS mode](gitlab-org/gitaly@3c37bfdc1bb29ac00ad8879d5b48624a3c480fb6) ([merge request](gitlab-org/gitaly!4645)) +- [git2go: Add conflicting files to cherry pick error](gitlab-org/gitaly@372fdeec4c06000b248648bf780d665a98aa9514) ([merge request](gitlab-org/gitaly!4585)) +- [git2go: Pass feature flags into gitaly-git2go binary](gitlab-org/gitaly@47c23de002767c131095cfc0ed5f5eac99af1c63) ([merge request](gitlab-org/gitaly!4601)) + +### Performance (1 change) + +- [linguist: Implement Stats in pure Go](gitlab-org/gitaly@efd9a598f50e03f05620b56f2e010600128f3b1c) ([merge request](gitlab-org/gitaly!4580)) + +## 15.1.6 (2022-08-30) + +No changes. + +## 15.1.5 (2022-08-22) + +No changes. + +## 15.1.4 (2022-07-28) + +### Security (1 change) + +- [Import via git protocol allows to bypass checks on repository](gitlab-org/security/gitaly@f8909dcbab9ea2ddabad06577a1c2ae50ac5f8f3) ([merge request](gitlab-org/security/gitaly!54)) + +## 15.1.3 (2022-07-19) + +No changes. + +## 15.1.2 (2022-07-05) + +No changes. + +## 15.1.1 (2022-06-30) + +No changes. + +## 15.1.0 (2022-06-21) + +### Added (4 changes) + +- [operations: Return structured errors on conflict in UserMergeBranch](gitlab-org/gitaly@ba8202022606baa73e8ddde68d11a386a1ae4b64) ([merge request](gitlab-org/gitaly!4623)) +- [praefect: Add list-storages subcommand](gitlab-org/gitaly@1350878ea184e06ab7d22f3cdd9e2b106ea3c8de) ([merge request](gitlab-org/gitaly!4609)) +- [gitaly/config: Add option to ignore gitconfig files](gitlab-org/gitaly@7224e71bc7684578950b193f8130a4ce123f63ab) ([merge request](gitlab-org/gitaly!4588)) +- [Make Git build with SHA256 routines in FIPS mode](gitlab-org/gitaly@4d3a9577487ddc9cb588b4725c8b8804897a93c3) ([merge request](gitlab-org/gitaly!4570)) + +### Fixed (10 changes) + +- [operations: Use structured errors in UserDeleteBranch](gitlab-org/gitaly@30d4fd427fc63daef560f1608b3833b827ab54ac) ([merge request](gitlab-org/gitaly!4605)) +- [datastore: Fix migration that prunes maintenance-style replication jobs](gitlab-org/gitaly@8e94bb2baee1634525a4648342a9d20efb4ca608) ([merge request](gitlab-org/gitaly!4608)) +- [catfile: Fix deadlock between reading a new object and accessing it](gitlab-org/gitaly@e263ba26e72b18015fc09bd97b759b074e660abf) ([merge request](gitlab-org/gitaly!4590)) +- [catfile: Fix dirtiness check when current object has been fully read](gitlab-org/gitaly@4b83e5996056b4a6260d57b7a19180aa4f220c2c) ([merge request](gitlab-org/gitaly!4590)) +- [streamcache: Unlock waiters after cache keys have been pruned](gitlab-org/gitaly@59864b3bc908d82789fbd289f1de04672cfe5a82) ([merge request](gitlab-org/gitaly!4589)) +- [gitpipe: Fix closing queue too early](gitlab-org/gitaly@3672650574465fbd42677b5f68d35f1beb555dc0) ([merge request](gitlab-org/gitaly!4581)) +- [gitpipe: Fix deadlock on context cancellation with unflushed requests](gitlab-org/gitaly@bee7ceb4ed70fc4b4001e2981725c95943d539d8) ([merge request](gitlab-org/gitaly!4581)) +- [Makefile: Fix install target using doubly-prefixed Gitaly paths](gitlab-org/gitaly@316f0078fa88aa2f1991f197efb425c065d9c6df) ([merge request](gitlab-org/gitaly!4553)) +- [cgroups: Handle nil repo](gitlab-org/gitaly@00e44ba6dd47ba7e089468698fb0dfa643d51edb) ([merge request](gitlab-org/gitaly!4572)) +- [supervisor: Fix leaking logrus Goroutine on spawn failure](gitlab-org/gitaly@faac47edca44039bcfcc4becb3be5b21b8dc5f95) ([merge request](gitlab-org/gitaly!4567)) + +### Changed (5 changes) + +- [Update nokogiri to v1.13.6](gitlab-org/gitaly@52538cbfafc73c071f94b0189c5bd1d890d95fad) ([merge request](gitlab-org/gitaly!4626)) +- [metadatahandler: Add grpc_method to prometheus metric](gitlab-org/gitaly@8c55670cf91f8f34ea682a1a816e227dab63fa35) ([merge request](gitlab-org/gitaly!4625)) +- [Enable feature flag exact_pagination_token_match by default](gitlab-org/gitaly@b40f2581082a81cebbdcc96fee35f21b6805466e) ([merge request](gitlab-org/gitaly!4606)) +- [gitaly-lfs-smudge: Update git-lfs module and dependencies](gitlab-org/gitaly@336df8ac52306225d89eb06ad9a64c83ead67749) ([merge request](gitlab-org/gitaly!4600)) +- [linguist: Implement wrapper to ignore gitconfig in Rugged](gitlab-org/gitaly@41fe00cab752de8701a0bc4f86866a30b9157d45) ([merge request](gitlab-org/gitaly!4577)) + +### Security (1 change) + +- [Makefile: Run bundle in frozen mode](gitlab-org/gitaly@037e033f846274093ed857aec17c2a5b7a310a96) ([merge request](gitlab-org/gitaly!4613)) + +### Performance (1 change) + +- [repository: Use long-running filter process for converting LFS pointers](gitlab-org/gitaly@0603c758d6e3580adbd3d0d69e326d05baa340b9) ([merge request](gitlab-org/gitaly!4595)) + +## 15.0.5 (2022-07-28) + +### Security (1 change) + +- [Import via git protocol allows to bypass checks on repository](gitlab-org/security/gitaly@a110173b56e3bc8c7cb5db2e1e84f6cfb226c39e) ([merge request](gitlab-org/security/gitaly!55)) + +## 15.0.4 (2022-06-30) + +No changes. + +## 15.0.3 (2022-06-16) + +### Fixed (5 changes) + +- [catfile: Fix deadlock between reading a new object and accessing it](gitlab-org/gitaly@cde65f668a6a6dbec9868f29082f2ad898ae4231) ([merge request](gitlab-org/gitaly!4638)) +- [catfile: Fix dirtiness check when current object has been fully read](gitlab-org/gitaly@da64bceee41f73a2f3cb3531fe41af458dd1a00f) ([merge request](gitlab-org/gitaly!4638)) +- [gitpipe: Fix closing queue too early](gitlab-org/gitaly@e695fc43615119edf620fbcda0224a68427dea26) ([merge request](gitlab-org/gitaly!4638)) +- [gitpipe: Fix deadlock on context cancellation with unflushed requests](gitlab-org/gitaly@6803dcb284c8598a3613abd951b9f5adf47da460) ([merge request](gitlab-org/gitaly!4638)) +- [cgroups: Handle nil repo](gitlab-org/gitaly@3c68f28df307b2d417ec361fba947f2d5f03a380) ([merge request](gitlab-org/gitaly!4635)) + +## 15.0.2 (2022-06-06) + +No changes. + +## 15.0.1 (2022-06-01) + +No changes. + +## 15.0.0 (2022-05-20) + +### Added (13 changes) + +- [proto: Introduce new `CustomHookError` for `UserMergeBranchError`](gitlab-org/gitaly@4302c0cc9df4bb2736103eea1a69cbc299bd3cda) ([merge request](gitlab-org/gitaly!4549)) +- [Log routing decisions in Praefect](gitlab-org/gitaly@b7d13f2fbd80866076bd17e094a3f51d0aab212e) ([merge request](gitlab-org/gitaly!4540)) +- [localrepo: Allow Size to pass exclude flag](gitlab-org/gitaly@3e04a937bb112bb7b7e85667f6eed65b894a3dca) ([merge request](gitlab-org/gitaly!4532)) +- [Add configuration to enable deletions in background verifier](gitlab-org/gitaly@889d25f3ac44ed491d29d25c42ba0975f8cc071e) ([merge request](gitlab-org/gitaly!4527)) +- [operations: Use merge for squashing](gitlab-org/gitaly@e694381a237da441dd8c5c955def41c48eade760) by @trakos ([merge request](gitlab-org/gitaly!4514)) +- [git: Add execution environment for bundled Git v2.36.0.gl1](gitlab-org/gitaly@a852018be2f88e5ce934533d56e5953666f18349) ([merge request](gitlab-org/gitaly!4516)) +- [Makefile: Install bundled Git v2.36.0.gl1](gitlab-org/gitaly@d07ed513fd4723ed9c1af1cd749ccc478e38aab9) ([merge request](gitlab-org/gitaly!4516)) +- [command: Add metric for spawning tokens](gitlab-org/gitaly@1034bb6bf25466dfe13457f0e5e4f6bb09596487) ([merge request](gitlab-org/gitaly!4487)) +- [safe: Add new LockingDirectory](gitlab-org/gitaly@1a7197e3b2171626a95fbab2b28ecbe43ea79aea) ([merge request](gitlab-org/gitaly!4481)) +- [Implement 'praefect verify' subcommand](gitlab-org/gitaly@b902b6bfbe107e26a8d721414d2fbb76cd648797) ([merge request](gitlab-org/gitaly!4463)) +- [Add proto definitions for MarkUnverified RPC](gitlab-org/gitaly@b850c3990c3eb2e5f42024ca3409b1dfc078ffb7) ([merge request](gitlab-org/gitaly!4463)) +- [Add support for FIPS encryption](gitlab-org/gitaly@fdcb9f0499c8fe2468cbce02b2aa5180dddf3168) ([merge request](gitlab-org/gitaly!4482)) +- [proto: Add LimitError as a structured error](gitlab-org/gitaly@4e2d52201ab72dbc2e18f4cb931a8c1303fb9d47) ([merge request](gitlab-org/gitaly!4476)) + +### Fixed (14 changes) + +- [ruby: Fix diverging Git configuration in Go and Ruby](gitlab-org/gitaly@99c1774919705cee43849a6c6dd6ee8c91b3c7a5) ([merge request](gitlab-org/gitaly!4557)) +- [Generate unique replica paths for repositories](gitlab-org/gitaly@aec4a9343a82c80b919bb081a86fa60d6115a6c7) ([merge request](gitlab-org/gitaly!4101)) +- [Intercept RenameRepository calls in Praefect](gitlab-org/gitaly@3e92c2cf29a757444e11b39f61e58a8820751e2a) ([merge request](gitlab-org/gitaly!4101)) +- [testcfg: Fix building Go binaries with Go 1.18](gitlab-org/gitaly@4e747d4bb4ccc6d23094da9894ebd6d8980e25a3) ([merge request](gitlab-org/gitaly!4561)) +- [gitpipe: Propagate context cancellation in object data pipeline](gitlab-org/gitaly@8773480fd0eb9740c96f32e992697600477a5b63) ([merge request](gitlab-org/gitaly!4524)) +- [gitpipe: Propagate context cancellation in object info pipeline](gitlab-org/gitaly@60b977838c56c120a4cb844392cd304e09510250) ([merge request](gitlab-org/gitaly!4524)) +- [gitpipe: Propagate context cancellation in revisions pipeline](gitlab-org/gitaly@50ad532fcd1e7cdde65ea68b23ea58ad864da537) ([merge request](gitlab-org/gitaly!4524)) +- [gitpipe: Fix sending of events to be race-free with context cancellation](gitlab-org/gitaly@cd56f37bb3d09324805898c4ccb0d66cd89dd24b) ([merge request](gitlab-org/gitaly!4524)) +- [commit: Do not ignore revisions of the initial request](gitlab-org/gitaly@6dc1d2b46da953e893c3da5505a876cef0a51f34) ([merge request](gitlab-org/gitaly!4510)) +- [commit: Fix verification of arguments in `CheckObjectsExist()`](gitlab-org/gitaly@5fc7fa58c6da132fc79f7b0b0f6e893efb986a57) ([merge request](gitlab-org/gitaly!4510)) +- [limithandler: Return error from limit handler](gitlab-org/gitaly@de291225acc1244454075466cb0986e5bf7072fa) ([merge request](gitlab-org/gitaly!4492)) +- [catfile: Fix losing all context information on decorrelation](gitlab-org/gitaly@77b8ced5bd60eebd0614e5ab408d048ab1116d43) ([merge request](gitlab-org/gitaly!4500)) +- [git: Fix corruption of refs on hard-resets](gitlab-org/gitaly@c89c8002131dabee677cce9c0551801a8e272570) ([merge request](gitlab-org/gitaly!4498)) +- [git: Fix fsyncing config incompatibility with Git v2.36.0](gitlab-org/gitaly@e1f0e5a5ffc31387cb1137c41db538f22e0153de) ([merge request](gitlab-org/gitaly!4498)) + +### Changed (18 changes) + +- [Use Praefect's RemoveRepository from remove-repository subcommand](gitlab-org/gitaly@5553cc8f515bbcb0e7414710387f330074f1e27d) ([merge request](gitlab-org/gitaly!4101)) +- [cgroups: Repository isolated cgroups](gitlab-org/gitaly@07dc211c8d457e82cdc682bea35a4b3e7c2181e3) ([merge request](gitlab-org/gitaly!4520)) +- [repository: Exclude alternate object directories in repository size](gitlab-org/gitaly@06b14498122b0a5bab966384375e497566d25574) ([merge request](gitlab-org/gitaly!4558)) +- [ListCommits: Extend ListCommits rpc to support filter by commit msg patterns](gitlab-org/gitaly@269bbd8c76739c4785fa686cb570404a0dc51421) by @akumar1503 ([merge request](gitlab-org/gitaly!4421)) +- [git: Sync internal namespaces with distros' settings](gitlab-org/gitaly@9645623a23b51be7d1525e765d532bef198380df) ([merge request](gitlab-org/gitaly!4562)) +- [repository: Log repo size calculations](gitlab-org/gitaly@92fc011f905a5e80f719d5310b9831243eb31630) ([merge request](gitlab-org/gitaly!4556)) +- [operations: Return detailed errors for hook failures in UserMergeBranch](gitlab-org/gitaly@718370303ca9e0c0a05c34ff58794b2943ea1053) ([merge request](gitlab-org/gitaly!4549)) +- [Use LabKit for FIPS mode check](gitlab-org/gitaly@453bb0e733524e6a55af4cd41fc5c3f1c559074e) ([merge request](gitlab-org/gitaly!4535)) +- [limithandler: Do not wrap errors from limithandler](gitlab-org/gitaly@e01b8fa0334367eccba423a4f8815b9d6e733dc7) ([merge request](gitlab-org/gitaly!4537)) +- [Makefile: Upgrade bundled Git to v2.36.1](gitlab-org/gitaly@4fed4c661cfae6afe2e284932778c89b9977e21b) ([merge request](gitlab-org/gitaly!4538)) +- [Update grpc-go and protobuf](gitlab-org/gitaly@95049fa8b6ceea4aa47ba18910fbbf833c34a389) ([merge request](gitlab-org/gitaly!4536)) +- [repository: Exclude merge-requests, keep-around, pipelines from size](gitlab-org/gitaly@d66c7e2e4f44f0afc621dd591dfb44e1fbac138d) ([merge request](gitlab-org/gitaly!4532)) +- [limithandler: Return structured errors](gitlab-org/gitaly@18c5b92ebb461d2f13712a057795699c183f0f71) ([merge request](gitlab-org/gitaly!4507)) +- [config: Introduce new Cgroups config](gitlab-org/gitaly@be0ee060975bddbabdd27cad3e4e0c6881d5c468) ([merge request](gitlab-org/gitaly!4483)) +- [smarthttp: Add finalizing vote in PostReceivePack](gitlab-org/gitaly@459e7d1dfa36cb443c41144f0b0535ba01556d23) ([merge request](gitlab-org/gitaly!4488)) +- [repository: RestoreCustomHooks to do transaction voting](gitlab-org/gitaly@e66d0d5107a5e3a56259e3bdfc2617d24a920a94) ([merge request](gitlab-org/gitaly!4481)) +- [Remove Maintenance routing feature flag](gitlab-org/gitaly@6f96233eb33adefc756f4be6906a6370ec84a8bd) ([merge request](gitlab-org/gitaly!4486)) +- [Ignore verification columns for read-only cache updates](gitlab-org/gitaly@5c9feb4e8e3175f1f80aae2f452e9e676133d14f) ([merge request](gitlab-org/gitaly!4468)) + +### Removed (4 changes) + +- [proto: Remove deprecated `PackObjectsHook()` RPC](gitlab-org/gitaly@c39a684bbc14bbd91e38d76e5692559bd60a10eb) ([merge request](gitlab-org/gitaly!4508)) +- [config: Remove internal socket path configuration](gitlab-org/gitaly@8a3373c8b07b06fe38ade96350c9bde836b25849) ([merge request](gitlab-org/gitaly!4504)) +- [operations: Remove feature flag for transactional voting in UserSquash](gitlab-org/gitaly@58825d1f725f0c04677aeca6ba65521f2e52217f) ([merge request](gitlab-org/gitaly!4496)) +- [Makefile: Drop bundled Git v2.33.1.gl3](gitlab-org/gitaly@9c700ea473d781eea50eab685d643d95e9c4ffee) ([merge request](gitlab-org/gitaly!4495)) + +### Other (1 change) + +- [go.mod: Remove exclude directive](gitlab-org/gitaly@c40c629a01fae35e3f34b05bf1e28a94aaac2692) ([merge request](gitlab-org/gitaly!4525)) + +## 14.10.5 (2022-06-30) + +No changes. + +## 14.10.4 (2022-06-01) + +No changes. + +## 14.10.3 (2022-05-20) + +### Other (1 change) + +- [go.mod: Remove exclude directive](gitlab-org/gitaly@fab75a04e3be466b5f2023cdb5d3480746241b04) ([merge request](gitlab-org/gitaly!4530)) + +## 14.10.2 (2022-05-04) + +No changes. + +## 14.10.1 (2022-04-29) + +No changes. + ## 14.10.0 (2022-04-21) ### Added (9 changes) @@ -65,6 +404,14 @@ - [Add migrations for background verification schema](gitlab-org/gitaly@465af6714c19c7a7d0b38fd02b626b08d1b6f343) ([merge request](gitlab-org/gitaly!4459)) - [sidechannel: use default yamux max window size](gitlab-org/gitaly@f99ae8abf6f317892065e99463c179364c462383) ([merge request](gitlab-org/gitaly!4439)) +## 14.9.5 (2022-06-01) + +No changes. + +## 14.9.4 (2022-04-29) + +No changes. + ## 14.9.3 (2022-04-12) No changes. @@ -135,6 +482,10 @@ No changes. - [Makefile: Add more patches to speed up git-fetch(1) to v2.35.1.gl1](gitlab-org/gitaly@4c5b7a2a4fa9960381a214b057062ed3693b41ba) ([merge request](gitlab-org/gitaly!4408)) - [git: Convert internal fetches to use sidechannel](gitlab-org/gitaly@8e5cb64195e732fd95f98d49971b6e9910b86ce2) ([merge request](gitlab-org/gitaly!4358)) +## 14.8.6 (2022-04-29) + +No changes. + ## 14.8.5 (2022-03-31) ### Fixed (1 change) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CONTRIBUTING.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CONTRIBUTING.md similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CONTRIBUTING.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CONTRIBUTING.md index b87bb0ee91..a616c9d334 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/CONTRIBUTING.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/CONTRIBUTING.md @@ -224,14 +224,8 @@ Signed-off-by: Alice ## Gitaly Maintainers -- @8bitlife -- @avar -- @chriscool -- @jcaigitlab -- @pks-t -- @proglottis -- @samihiltunen -- @toon +This project is maintained by the [members](https://gitlab.com/groups/gl-gitaly/-/group_members) +of @gl-gitaly. ## Development Process diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Dangerfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Dangerfile similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Dangerfile rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Dangerfile index 616556b1aa..39c6730e2b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Dangerfile +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Dangerfile @@ -14,5 +14,6 @@ Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| danger.import_dangerfile(path: "danger/rules/#{rule}") end - gitlab_dangerfiles.import_defaults + gitlab_dangerfiles.import_plugins + gitlab_dangerfiles.import_dangerfiles(except: %w[changes_size]) end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/LICENSE b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/LICENSE similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/LICENSE rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/LICENSE diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Makefile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Makefile similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Makefile rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Makefile index 8d9846c648..157721c1b7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/Makefile +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/Makefile @@ -26,7 +26,6 @@ ARCH := $(shell uname -m) # Directories SOURCE_DIR := $(abspath $(dir $(lastword ${MAKEFILE_LIST}))) BUILD_DIR := ${SOURCE_DIR}/_build -COVERAGE_DIR := ${BUILD_DIR}/cover DEPENDENCY_DIR := ${BUILD_DIR}/deps TOOLS_DIR := ${BUILD_DIR}/tools GITALY_RUBY_DIR := ${SOURCE_DIR}/ruby @@ -41,57 +40,82 @@ exec_prefix ?= ${prefix} bindir ?= ${exec_prefix}/bin INSTALL_DEST_DIR := ${DESTDIR}${bindir} ## The prefix where Git will be installed to. -GIT_PREFIX ?= ${GIT_DEFAULT_PREFIX} -FIPS_MODE ?= 0 +GIT_PREFIX ?= ${PREFIX} # Tools -GIT := $(shell command -v git) -GOIMPORTS := ${TOOLS_DIR}/goimports -GOFUMPT := ${TOOLS_DIR}/gofumpt -GOLANGCI_LINT := ${TOOLS_DIR}/golangci-lint -GO_LICENSES := ${TOOLS_DIR}/go-licenses -PROTOC := ${TOOLS_DIR}/protoc -PROTOC_GEN_GO := ${TOOLS_DIR}/protoc-gen-go -PROTOC_GEN_GO_GRPC:= ${TOOLS_DIR}/protoc-gen-go-grpc -PROTOC_GEN_GITALY := ${TOOLS_DIR}/protoc-gen-gitaly -GOTESTSUM := ${TOOLS_DIR}/gotestsum -GOCOVER_COBERTURA := ${TOOLS_DIR}/gocover-cobertura +GIT := $(shell command -v git) +GOIMPORTS := ${TOOLS_DIR}/goimports +GOFUMPT := ${TOOLS_DIR}/gofumpt +GOLANGCI_LINT := ${TOOLS_DIR}/golangci-lint +PROTOLINT := ${TOOLS_DIR}/protolint +GO_LICENSES := ${TOOLS_DIR}/go-licenses +PROTOC := ${TOOLS_DIR}/protoc +PROTOC_GEN_GO := ${TOOLS_DIR}/protoc-gen-go +PROTOC_GEN_GO_GRPC := ${TOOLS_DIR}/protoc-gen-go-grpc +PROTOC_GEN_GITALY_LINT := ${TOOLS_DIR}/protoc-gen-gitaly-lint +PROTOC_GEN_GITALY_PROTOLIST := ${TOOLS_DIR}/protoc-gen-gitaly-protolist +GOTESTSUM := ${TOOLS_DIR}/gotestsum +GOCOVER_COBERTURA := ${TOOLS_DIR}/gocover-cobertura +DELVE := ${TOOLS_DIR}/dlv # Tool options GOLANGCI_LINT_OPTIONS ?= GOLANGCI_LINT_CONFIG ?= ${SOURCE_DIR}/.golangci.yml # Build information -GITALY_PACKAGE := gitlab.com/gitlab-org/gitaly/v14 +GITALY_PACKAGE := gitlab.com/gitlab-org/gitaly/v15 BUILD_TIME := $(shell date +"%Y%m%d.%H%M%S") GITALY_VERSION := $(shell ${GIT} describe --match v* 2>/dev/null | sed 's/^v//' || cat ${SOURCE_DIR}/VERSION 2>/dev/null || echo unknown) GO_LDFLAGS := -X ${GITALY_PACKAGE}/internal/version.version=${GITALY_VERSION} -X ${GITALY_PACKAGE}/internal/version.buildtime=${BUILD_TIME} -X ${GITALY_PACKAGE}/internal/version.moduleVersion=${MODULE_VERSION} SERVER_BUILD_TAGS := tracer_static,tracer_static_jaeger,tracer_static_stackdriver,continuous_profiler_stackdriver GIT2GO_BUILD_TAGS := static,system_libgit2 -ifeq (${FIPS_MODE}, 1) - SERVER_BUILD_TAGS := ${SERVER_BUILD_TAGS},boringcrypto - GIT2GO_BUILD_TAGS := ${GIT2GO_BUILD_TAGS},boringcrypto +# Temporary GNU build ID used as a placeholder value so that we can replace it +# with our own one after binaries have been built. This is the ASCII encoding +# of the string "TEMP_GITALY_BUILD_ID". +TEMPORARY_BUILD_ID := 54454D505F474954414C595F4255494C445F4944 + +## FIPS_MODE controls whether to build Gitaly and dependencies in FIPS mode. +## Set this to a non-empty value to enable it. +FIPS_MODE ?= + +ifdef FIPS_MODE + SERVER_BUILD_TAGS := ${SERVER_BUILD_TAGS},fips + GIT2GO_BUILD_TAGS := ${GIT2GO_BUILD_TAGS},fips + + # Build Git with the OpenSSL backend for SHA256 in case FIPS-mode is + # requested. Note that we explicitly don't do the same for SHA1: we + # instead use SHA1DC to protect users against the SHAttered attack. + GIT_FIPS_BUILD_OPTIONS := OPENSSL_SHA256=YesPlease + + export GITALY_TESTING_ENABLE_FIPS := YesPlease +endif + +ifdef GITALY_TESTING_ENABLE_SHA256 + SERVER_BUILD_TAGS := ${SERVER_BUILD_TAGS},gitaly_test_sha256 + GIT2GO_BUILD_TAGS := ${GIT2GO_BUILD_TAGS},gitaly_test_sha256 endif # Dependency versions -GOLANGCI_LINT_VERSION ?= 1.44.2 +GOLANGCI_LINT_VERSION ?= v1.48.0 +PROTOLINT_VERSION ?= v0.38.1 GOCOVER_COBERTURA_VERSION ?= aaee18c8195c3f2d90e5ef80ca918d265463842a -GOFUMPT_VERSION ?= 0.3.1 -GOIMPORTS_VERSION ?= 2538eef75904eff384a2551359968e40c207d9d2 -GOTESTSUM_VERSION ?= v1.7.0 -GO_LICENSES_VERSION ?= v1.0.0 +GOFUMPT_VERSION ?= v0.3.1 +GOIMPORTS_VERSION ?= v0.1.10 +GOTESTSUM_VERSION ?= v1.8.1 +GO_LICENSES_VERSION ?= v1.2.1 # https://pkg.go.dev/github.com/protocolbuffers/protobuf -PROTOC_VERSION ?= v3.17.3 +PROTOC_VERSION ?= v21.1 # https://pkg.go.dev/google.golang.org/protobuf -PROTOC_GEN_GO_VERSION ?= 1.26.0 +PROTOC_GEN_GO_VERSION ?= v1.28.0 # https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc -PROTOC_GEN_GO_GRPC_VERSION?= 1.1.0 +PROTOC_GEN_GO_GRPC_VERSION?= v1.2.0 # Git2Go and libgit2 may need to be updated in sync. Please refer to # https://github.com/libgit2/git2go/#which-go-version-to-use for a # compatibility matrix. GIT2GO_VERSION ?= v33 -LIBGIT2_VERSION ?= v1.3.0 +LIBGIT2_VERSION ?= v1.3.2 +DELVE_VERSION ?= v1.8.3 # protoc target PROTOC_REPO_URL ?= https://github.com/protocolbuffers/protobuf @@ -103,15 +127,12 @@ ifeq ($(origin PROTOC_BUILD_OPTIONS),undefined) ## Build options for protoc. PROTOC_BUILD_OPTIONS ?= PROTOC_BUILD_OPTIONS += -DBUILD_SHARED_LIBS=NO - PROTOC_BUILD_OPTIONS += -DBUILD_TESTS=OFF PROTOC_BUILD_OPTIONS += -DCMAKE_INSTALL_PREFIX=${PROTOC_INSTALL_DIR} + PROTOC_BUILD_OPTIONS += -Dprotobuf_BUILD_TESTS=OFF endif # Git target GIT_REPO_URL ?= https://gitlab.com/gitlab-org/gitlab-git.git -# The default prefix specifies where Git will be installed to if no GIT_PREFIX -# was given. This directory will be cleaned up before we install into it. -GIT_DEFAULT_PREFIX := ${DEPENDENCY_DIR}/git/install GIT_QUIET := ifeq (${Q},@) GIT_QUIET = --quiet @@ -121,10 +142,15 @@ GIT_EXECUTABLES += git GIT_EXECUTABLES += git-remote-http GIT_EXECUTABLES += git-http-backend +## The version of Git to build and test Gitaly with when not used +## WITH_BUNDLED_GIT=YesPlease. Can be set to an arbitrary Git revision with +## tags, branches, and commit ids. +GIT_VERSION ?= + # The default version is used in case the caller does not set the variable or # if it is either set to the empty string or "default". ifeq (${GIT_VERSION:default=},) - override GIT_VERSION := v2.35.1 + override GIT_VERSION := v2.37.1 # This extra version has two intentions: first, it allows us to detect # capabilities of the command at runtime. Second, it helps admins to @@ -137,7 +163,7 @@ ifeq (${GIT_VERSION:default=},) # Before adding custom patches, please read doc/PROCESS.md#Patching-git # first to make sure your patches meet our acceptance criteria. Patches # must be put into `_support/git-patches`. - GIT_PATCHES := $(sort $(wildcard ${SOURCE_DIR}/_support/git-patches/v2.35.1.gl1/*)) + GIT_PATCHES := $(sort $(wildcard ${SOURCE_DIR}/_support/git-patches/v2.37.1.gl1/*)) else # Support both vX.Y.Z and X.Y.Z version patterns, since callers across GitLab # use both. @@ -157,7 +183,6 @@ ifeq ($(origin GIT_BUILD_OPTIONS),undefined) GIT_BUILD_OPTIONS += NO_TCLTK=YesPlease GIT_BUILD_OPTIONS += NO_GETTEXT=YesPlease GIT_BUILD_OPTIONS += NO_PYTHON=YesPlease - GIT_BUILD_OPTIONS += NO_INSTALL_HARDLINKS=YesPlease PCRE_PC=libpcre2-8 ifeq ($(shell pkg-config --exists ${PCRE_PC} && echo exists),exists) GIT_BUILD_OPTIONS += LIBPCREDIR=$(shell pkg-config ${PCRE_PC} --variable prefix) @@ -168,6 +193,10 @@ ifdef GIT_APPEND_BUILD_OPTIONS GIT_BUILD_OPTIONS += ${GIT_APPEND_BUILD_OPTIONS} endif +ifdef GIT_FIPS_BUILD_OPTIONS + GIT_BUILD_OPTIONS += ${GIT_FIPS_BUILD_OPTIONS} +endif + # libgit2 target LIBGIT2_REPO_URL ?= https://gitlab.com/libgit2/libgit2 LIBGIT2_SOURCE_DIR ?= ${DEPENDENCY_DIR}/libgit2/source @@ -201,24 +230,32 @@ endif # These variables control test options and artifacts ## List of Go packages which shall be tested. ## Go packages to test when using the test-go target. -TEST_PACKAGES ?= ${SOURCE_DIR}/... +TEST_PACKAGES ?= ${SOURCE_DIR}/... ## Test options passed to `go test`. -TEST_OPTIONS ?= -count=1 +TEST_OPTIONS ?= -count=1 ## Specify the output format used to print tests ["standard-verbose", "standard-quiet", "short"] -TEST_FORMAT ?= short -TEST_REPORT ?= ${BUILD_DIR}/reports/go-tests-report.xml +TEST_FORMAT ?= short +TEST_REPORT ?= ${BUILD_DIR}/reports/go-tests-report.xml +# Full output of `go test -json` +TEST_FULL_OUTPUT ?= /dev/null +## Specify the output directory for test coverage reports. +TEST_COVERAGE_DIR ?= ${BUILD_DIR}/cover ## Directory where all runtime test data is being created. -TEST_TMP_DIR ?= -TEST_REPO_DIR := ${BUILD_DIR}/testrepos -TEST_REPO := ${TEST_REPO_DIR}/gitlab-test.git -TEST_REPO_MIRROR := ${TEST_REPO_DIR}/gitlab-test-mirror.git -TEST_REPO_GIT := ${TEST_REPO_DIR}/gitlab-git-test.git -BENCHMARK_REPO := ${TEST_REPO_DIR}/benchmark.git +TEST_TMP_DIR ?= +TEST_REPO_DIR := ${BUILD_DIR}/testrepos +TEST_REPO := ${TEST_REPO_DIR}/gitlab-test.git +TEST_REPO_MIRROR := ${TEST_REPO_DIR}/gitlab-test-mirror.git +TEST_REPO_GIT := ${TEST_REPO_DIR}/gitlab-git-test.git +BENCHMARK_REPO := ${TEST_REPO_DIR}/benchmark.git -# All executables provided by Gitaly -GITALY_EXECUTABLES = $(notdir $(shell find ${SOURCE_DIR}/cmd -mindepth 1 -maxdepth 1 -type d -print)) +# All executables provided by Gitaly. +GITALY_EXECUTABLES = $(addprefix ${BUILD_DIR}/bin/,$(notdir $(shell find ${SOURCE_DIR}/cmd -mindepth 1 -maxdepth 1 -type d -print))) +# All executables packed inside the Gitaly binary. +GITALY_PACKED_EXECUTABLES = $(filter %gitaly-hooks %gitaly-git2go %gitaly-ssh %gitaly-lfs-smudge, ${GITALY_EXECUTABLES}) +# All executables that should be installed. +GITALY_INSTALLED_EXECUTABLES = $(filter-out ${GITALY_PACKED_EXECUTABLES}, ${GITALY_EXECUTABLES}) # Find all Go source files. -find_go_sources = $(shell find ${SOURCE_DIR} -type d \( -name ruby -o -name vendor -o -name testdata -o -name '_*' -o -path '*/proto/go/gitalypb' \) -prune -o -type f -name '*.go' -not -name '*.pb.go' -print | sort -u) +find_go_sources = $(shell find ${SOURCE_DIR} -type d \( -name ruby -o -name vendor -o -name testdata -o -name '_*' -o -path '*/proto/go/gitalypb' \) -prune -o -type f -name '*.go' -not -name '*.pb.go' -print | sort -u) # run_go_tests will execute Go tests with all required parameters. Its # behaviour can be modified via the following variables: @@ -227,10 +264,22 @@ find_go_sources = $(shell find ${SOURCE_DIR} -type d \( -name ruby -o -nam # TEST_PACKAGES: packages which shall be tested run_go_tests = PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' \ TEST_TMP_DIR='${TEST_TMP_DIR}' \ - ${GOTESTSUM} --format ${TEST_FORMAT} --junitfile ${TEST_REPORT} -- -ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}' ${TEST_OPTIONS} ${TEST_PACKAGES} + ${GOTESTSUM} --format ${TEST_FORMAT} --junitfile ${TEST_REPORT} --jsonfile ${TEST_FULL_OUTPUT} -- -ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS},gitaly_test_signing' ${TEST_OPTIONS} ${TEST_PACKAGES} + +## Test options passed to `dlv test`. +DEBUG_OPTIONS ?= $(patsubst -%,-test.%,${TEST_OPTIONS}) + +# debug_go_tests will execute Go tests from a single package in the delve debugger. +# Its behaviour can be modified via the following variable: +# +# DEBUG_OPTIONS: any additional options, will default to TEST_OPTIONS if not set. +debug_go_tests = PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' \ + TEST_TMP_DIR='${TEST_TMP_DIR}' \ + ${DELVE} test --build-flags="-ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}'" ${TEST_PACKAGES} -- ${DEBUG_OPTIONS} unexport GOROOT -export GOBIN = ${BUILD_DIR}/bin +## GOCACHE_MAX_SIZE_KB is the maximum size of Go's build cache in kilobytes before it is cleaned up. +GOCACHE_MAX_SIZE_KB ?= 5000000 export GOCACHE ?= ${BUILD_DIR}/cache export GOPROXY ?= https://proxy.golang.org export PATH := ${BUILD_DIR}/bin:${PATH} @@ -238,6 +287,9 @@ export PKG_CONFIG_PATH := ${LIBGIT2_INSTALL_DIR}/lib/pkgconfig # Allow the linker flag -D_THREAD_SAFE as libgit2 is compiled with it on FreeBSD export CGO_LDFLAGS_ALLOW = -D_THREAD_SAFE +# Disallow changes to the Gemfile +export BUNDLE_FROZEN = true + # By default, intermediate targets get deleted automatically after a successful # build. We do not want that though: there's some precious intermediate targets # like our `*.version` targets which are required in order to determine whether @@ -249,6 +301,9 @@ export CGO_LDFLAGS_ALLOW = -D_THREAD_SAFE ## Default target which builds Gitaly. all: build +.PHONY: .FORCE +.FORCE: + ## Print help about available targets and variables. help: @echo "usage: make [...] [=...]" @@ -262,7 +317,8 @@ help: { desc = "" }' $(MAKEFILE_LIST) | sort | column -s: -t ${Q}echo "" - ${Q}echo "These are common variables which can be overridden in config.mak:" + ${Q}echo "These are common variables which can be overridden in config.mak" + ${Q}echo "or by passing them to make directly as environment variables:" ${Q}echo "" @ # Match all variables which have preceding `## ` comments and which are assigned via `?=`. @@ -272,42 +328,28 @@ help: .PHONY: build ## Build Go binaries and install required Ruby Gems. -build: ${SOURCE_DIR}/.ruby-bundle ${GITALY_EXECUTABLES} - -gitaly: GO_BUILD_TAGS = ${SERVER_BUILD_TAGS} -praefect: GO_BUILD_TAGS = ${SERVER_BUILD_TAGS} -gitaly-git2go-v14: GO_BUILD_TAGS = ${GIT2GO_BUILD_TAGS} -gitaly-git2go-v14: libgit2 - -.PHONY: ${GITALY_EXECUTABLES} -${GITALY_EXECUTABLES}: - ${Q}go install -ldflags '${GO_LDFLAGS}' -tags "${GO_BUILD_TAGS}" $(addprefix ${GITALY_PACKAGE}/cmd/, $@) - @ # To compute a unique and deterministic value for GNU build-id, we build the Go binary a second time. - @ # From the first build, we extract its unique and deterministic Go build-id, and use that to derive - @ # comparably unique and deterministic GNU build-id to inject into the final binary. - @ # If we cannot extract a Go build-id, we punt and fallback to using a random 32-byte hex string. - @ # This fallback is unique but non-deterministic, making it sufficient to avoid generating the - @ # GNU build-id from the empty string and causing guaranteed collisions. - ${Q}GO_BUILD_ID=$$( go tool buildid $(addprefix ${BUILD_DIR}/bin/, $@) || openssl rand -hex 32 ) && \ - GNU_BUILD_ID=$$( echo $$GO_BUILD_ID | sha1sum | cut -d' ' -f1 ) && \ - go install -ldflags '${GO_LDFLAGS}'" -B 0x$$GNU_BUILD_ID" -tags "${GO_BUILD_TAGS}" $(addprefix ${GITALY_PACKAGE}/cmd/, $@) +build: ${SOURCE_DIR}/.ruby-bundle ${GITALY_INSTALLED_EXECUTABLES} .PHONY: install ## Install Gitaly binaries. The target directory can be modified by setting PREFIX and DESTDIR. install: build ${Q}mkdir -p ${INSTALL_DEST_DIR} - install $(addprefix ${BUILD_DIR}/bin/,${GITALY_EXECUTABLES}) "${INSTALL_DEST_DIR}" + install ${GITALY_INSTALLED_EXECUTABLES} "${INSTALL_DEST_DIR}" .PHONY: build-bundled-git ## Build bundled Git binaries. build-bundled-git: build-bundled-git-v2.35.1.gl1 +build-bundled-git: build-bundled-git-v2.37.1.gl1 build-bundled-git-v2.35.1.gl1: $(patsubst %,${BUILD_DIR}/bin/gitaly-%-v2.35.1.gl1,${GIT_EXECUTABLES}) +build-bundled-git-v2.37.1.gl1: $(patsubst %,${BUILD_DIR}/bin/gitaly-%-v2.37.1.gl1,${GIT_EXECUTABLES}) .PHONY: install-bundled-git ## Install bundled Git binaries. The target directory can be modified by ## setting PREFIX and DESTDIR. install-bundled-git: install-bundled-git-v2.35.1.gl1 +install-bundled-git: install-bundled-git-v2.37.1.gl1 install-bundled-git-v2.35.1.gl1: $(patsubst %,${INSTALL_DEST_DIR}/gitaly-%-v2.35.1.gl1,${GIT_EXECUTABLES}) +install-bundled-git-v2.37.1.gl1: $(patsubst %,${INSTALL_DEST_DIR}/gitaly-%-v2.37.1.gl1,${GIT_EXECUTABLES}) ifdef WITH_BUNDLED_GIT build: build-bundled-git @@ -316,15 +358,21 @@ install: install-bundled-git export GITALY_TESTING_BUNDLED_GIT_PATH ?= ${BUILD_DIR}/bin else -prepare-tests: git +prepare-tests: ${DEPENDENCY_DIR}/git-distribution/git -export GITALY_TESTING_GIT_BINARY ?= ${GIT_PREFIX}/bin/git +export GITALY_TESTING_GIT_BINARY ?= ${DEPENDENCY_DIR}/git-distribution/bin-wrappers/git endif .PHONY: prepare-tests prepare-tests: libgit2 prepare-test-repos ${SOURCE_DIR}/.ruby-bundle ${GOTESTSUM} +ifndef UNPRIVILEGED_CI_SKIP +prepare-tests: ${GITALY_PACKED_EXECUTABLES} +endif ${Q}mkdir -p "$(dir ${TEST_REPORT})" +.PHONY: prepare-debug +prepare-debug: ${DELVE} + .PHONY: prepare-test-repos prepare-test-repos: ${TEST_REPO_MIRROR} ${TEST_REPO} ${TEST_REPO_GIT} @@ -340,6 +388,11 @@ test-ruby: rspec test-go: prepare-tests ${Q}$(call run_go_tests) +.PHONY: debug-go-tests +## Run Go tests in delve debugger. +debug-test-go: prepare-tests prepare-debug + ${Q}$(call debug_go_tests) + .PHONY: test ## Run Go benchmarks. bench: TEST_OPTIONS := ${TEST_OPTIONS} -bench=. -run=^$ @@ -367,10 +420,10 @@ rspec: prepare-tests ${Q}cd ${GITALY_RUBY_DIR} && PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' bundle exec rspec # This is a workaround for our unprivileged CI builds. We manually execute the -# build target as privileged user, but then run the rspec target unprivileged. +# build target as privileged user, but then run other targets unprivileged. # We thus cannot rebuild binaries there given that we have no permissions to # write into the build directory. -ifndef SKIP_RSPEC_BUILD +ifndef UNPRIVILEGED_CI_SKIP rspec: build endif @@ -386,7 +439,7 @@ check-mod-tidy: .PHONY: lint ## Run Go linter. -lint: ${GOLANGCI_LINT} libgit2 +lint: ${GOLANGCI_LINT} libgit2 ${GITALY_PACKED_EXECUTABLES} ${Q}${GOLANGCI_LINT} run --build-tags "${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}" --out-format tab --config ${GOLANGCI_LINT_CONFIG} ${GOLANGCI_LINT_OPTIONS} .PHONY: format @@ -404,10 +457,15 @@ notice-up-to-date: ${BUILD_DIR}/NOTICE notice: ${SOURCE_DIR}/NOTICE .PHONY: clean -## Clean up build artifacts. +## Clean up the Go and Ruby build artifacts. clean: rm -rf ${BUILD_DIR} ${SOURCE_DIR}/ruby/.bundle/ ${SOURCE_DIR}/ruby/vendor/bundle/ +.PHONY: clean-build +## Clean up the build artifacts except for Ruby dependencies. +clean-build: + rm -rf ${BUILD_DIR} + .PHONY: clean-ruby-vendor-go clean-ruby-vendor-go: mkdir -p ${SOURCE_DIR}/ruby/vendor && find ${SOURCE_DIR}/ruby/vendor -type f -name '*.go' -delete @@ -419,42 +477,42 @@ rubocop: ${SOURCE_DIR}/.ruby-bundle .PHONY: cover ## Generate coverage report via Go tests. -cover: TEST_OPTIONS := ${TEST_OPTIONS} -coverprofile "${COVERAGE_DIR}/all.merged" +cover: TEST_OPTIONS := ${TEST_OPTIONS} -coverprofile "${TEST_COVERAGE_DIR}/all.merged" cover: prepare-tests libgit2 ${GOCOVER_COBERTURA} - ${Q}rm -rf "${COVERAGE_DIR}" - ${Q}mkdir -p "${COVERAGE_DIR}" + ${Q}rm -rf "${TEST_COVERAGE_DIR}" + ${Q}mkdir -p "${TEST_COVERAGE_DIR}" ${Q}$(call run_go_tests) - ${Q}go tool cover -html "${COVERAGE_DIR}/all.merged" -o "${COVERAGE_DIR}/all.html" + ${Q}go tool cover -html "${TEST_COVERAGE_DIR}/all.merged" -o "${TEST_COVERAGE_DIR}/all.html" @ # sed is used below to convert file paths to repository root relative paths. See https://gitlab.com/gitlab-org/gitlab/-/issues/217664 - ${Q}${GOCOVER_COBERTURA} <"${COVERAGE_DIR}/all.merged" | sed 's;filename=\"$(shell go list -m)/;filename=\";g' >"${COVERAGE_DIR}/cobertura.xml" + ${Q}${GOCOVER_COBERTURA} <"${TEST_COVERAGE_DIR}/all.merged" | sed 's;filename=\"$(shell go list -m)/;filename=\";g' >"${TEST_COVERAGE_DIR}/cobertura.xml" ${Q}echo "" ${Q}echo "=====> Total test coverage: <=====" ${Q}echo "" - ${Q}go tool cover -func "${COVERAGE_DIR}/all.merged" + ${Q}go tool cover -func "${TEST_COVERAGE_DIR}/all.merged" .PHONY: proto ## Regenerate protobuf definitions. -proto: SHARED_PROTOC_OPTS = --plugin=${PROTOC_GEN_GO} --plugin=${PROTOC_GEN_GO_GRPC} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative -proto: ${PROTOC} ${PROTOC_GEN_GO} ${PROTOC_GEN_GO_GRPC} ${SOURCE_DIR}/.ruby-bundle +proto: SHARED_PROTOC_OPTS = --plugin=${PROTOC_GEN_GO} --plugin=${PROTOC_GEN_GO_GRPC} --plugin=${PROTOC_GEN_GITALY_PROTOLIST} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative +proto: ${PROTOC} ${PROTOC_GEN_GO} ${PROTOC_GEN_GO_GRPC} ${PROTOC_GEN_GITALY_PROTOLIST} ${SOURCE_DIR}/.ruby-bundle ${Q}mkdir -p ${SOURCE_DIR}/proto/go/gitalypb ${Q}rm -f ${SOURCE_DIR}/proto/go/gitalypb/*.pb.go - ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/proto/go/gitalypb --go-grpc_out=${SOURCE_DIR}/proto/go/gitalypb ${SOURCE_DIR}/proto/*.proto + ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/proto/go/gitalypb --gitaly-protolist_out=proto_dir=${SOURCE_DIR}/proto,gitalypb_dir=${SOURCE_DIR}/proto/go/gitalypb:${SOURCE_DIR} --go-grpc_out=${SOURCE_DIR}/proto/go/gitalypb ${SOURCE_DIR}/proto/*.proto ${SOURCE_DIR}/_support/generate-proto-ruby @ # this part is related to the generation of sources from testing proto files - ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/internal --go_out=${SOURCE_DIR}/internal --go-grpc_out=${SOURCE_DIR}/internal ${SOURCE_DIR}/internal/praefect/grpc-proxy/testdata/test.proto ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${SOURCE_DIR}/internal -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/internal --go-grpc_out=${SOURCE_DIR}/internal \ ${SOURCE_DIR}/internal/praefect/mock/mock.proto \ ${SOURCE_DIR}/internal/middleware/cache/testdata/stream.proto \ ${SOURCE_DIR}/internal/helper/chunk/testdata/test.proto \ ${SOURCE_DIR}/internal/middleware/limithandler/testdata/test.proto - ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/proto --go-grpc_out=${SOURCE_DIR}/proto ${SOURCE_DIR}/proto/go/internal/linter/testdata/*.proto + ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${SOURCE_DIR}/tools -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/tools --go-grpc_out=${SOURCE_DIR}/tools ${SOURCE_DIR}/tools/protoc-gen-gitaly-lint/testdata/*.proto .PHONY: check-proto check-proto: proto no-proto-changes lint-proto .PHONY: lint-proto -lint-proto: ${PROTOC} ${PROTOC_GEN_GITALY} - ${Q}${PROTOC} --plugin=${PROTOC_GEN_GITALY} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --gitaly_out=proto_dir=${SOURCE_DIR}/proto,gitalypb_dir=${SOURCE_DIR}/proto/go/gitalypb:${SOURCE_DIR} ${SOURCE_DIR}/proto/*.proto +lint-proto: ${PROTOC} ${PROTOLINT} ${PROTOC_GEN_GITALY_LINT} + ${Q}${PROTOC} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --plugin=${PROTOC_GEN_GITALY_LINT} --gitaly-lint_out=${SOURCE_DIR} ${SOURCE_DIR}/proto/*.proto + ${Q}${PROTOLINT} lint -config_dir_path=${SOURCE_DIR}/proto ${SOURCE_DIR}/proto .PHONY: no-changes no-changes: @@ -471,12 +529,17 @@ dump-database-schema: build .PHONY: upgrade-module upgrade-module: - ${Q}go run ${SOURCE_DIR}/_support/module-updater/main.go -dir . -from=${FROM_MODULE} -to=${TO_MODULE} + ${Q}go run ${SOURCE_DIR}/tools/module-updater/main.go -dir . -from=${FROM_MODULE} -to=${TO_MODULE} ${Q}${MAKE} proto .PHONY: git -## Build Git. -git: ${GIT_PREFIX}/bin/git +# This target is deprecated and will eventually be removed. +git: install-git + +.PHONY: install-git +## Install Git. +install-git: ${DEPENDENCY_DIR}/git-distribution/Makefile + ${Q}env -u PROFILE -u MAKEFLAGS -u GIT_VERSION ${MAKE} -C "${DEPENDENCY_DIR}/git-distribution" -j$(shell nproc) prefix=${GIT_PREFIX} ${GIT_BUILD_OPTIONS} install .PHONY: libgit2 ## Build libgit2. @@ -492,10 +555,10 @@ ${SOURCE_DIR}/.ruby-bundle: ${GITALY_RUBY_DIR}/Gemfile.lock ${GITALY_RUBY_DIR}/G ${SOURCE_DIR}/NOTICE: ${BUILD_DIR}/NOTICE ${Q}mv $< $@ -${BUILD_DIR}/NOTICE: ${GO_LICENSES} clean-ruby-vendor-go +${BUILD_DIR}/NOTICE: ${GO_LICENSES} clean-ruby-vendor-go ${GITALY_PACKED_EXECUTABLES} ${Q}rm -rf ${BUILD_DIR}/licenses ${Q}GOOS=linux GOFLAGS="-tags=${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}" ${GO_LICENSES} save ${SOURCE_DIR}/... --save_path=${BUILD_DIR}/licenses - ${Q}go run ${SOURCE_DIR}/_support/noticegen/noticegen.go -source ${BUILD_DIR}/licenses -template ${SOURCE_DIR}/_support/noticegen/notice.template > ${BUILD_DIR}/NOTICE + ${Q}go run ${SOURCE_DIR}/tools/noticegen/noticegen.go -source ${BUILD_DIR}/licenses -template ${SOURCE_DIR}/tools/noticegen/notice.template > ${BUILD_DIR}/NOTICE ${BUILD_DIR}: ${Q}mkdir -p ${BUILD_DIR} @@ -506,6 +569,64 @@ ${TOOLS_DIR}: | ${BUILD_DIR} ${DEPENDENCY_DIR}: | ${BUILD_DIR} ${Q}mkdir -p ${DEPENDENCY_DIR} +# This target builds a full Git distribution. +${DEPENDENCY_DIR}/git-distribution/git: ${DEPENDENCY_DIR}/git-distribution/Makefile + ${Q}env -u PROFILE -u MAKEFLAGS -u GIT_VERSION ${MAKE} -C "$( + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/godbus/dbus/v5 Copyright (c) 2013, Georg Reinke (), Google @@ -4057,6 +8915,18 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/golang-jwt/jwt/v4 +Copyright (c) 2012 Dave Grijalva +Copyright (c) 2021 golang-jwt maintainers + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/google/go-cmp/cmp Copyright (c) 2017 The Go Authors. All rights reserved. @@ -4980,6 +9850,8 @@ script: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/hashicorp/go-uuid +Copyright © 2015-2022 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions @@ -5367,22 +10239,40 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "io" ) // GenerateRandomBytes is used to generate random bytes of given size. func GenerateRandomBytes(size int) ([]byte, error) { + return GenerateRandomBytesWithReader(size, rand.Reader) +} + +// GenerateRandomBytesWithReader is used to generate random bytes of given size read from a given reader. +func GenerateRandomBytesWithReader(size int, reader io.Reader) ([]byte, error) { + if reader == nil { + return nil, fmt.Errorf("provided reader is nil") + } buf := make([]byte, size) - if _, err := rand.Read(buf); err != nil { + if _, err := io.ReadFull(reader, buf); err != nil { return nil, fmt.Errorf("failed to read random bytes: %v", err) } return buf, nil } + const uuidLen = 16 // GenerateUUID is used to generate a random UUID func GenerateUUID() (string, error) { - buf, err := GenerateRandomBytes(uuidLen) + return GenerateUUIDWithReader(rand.Reader) +} + +// GenerateUUIDWithReader is used to generate a random UUID with a given Reader +func GenerateUUIDWithReader(reader io.Reader) (string, error) { + if reader == nil { + return "", fmt.Errorf("provided reader is nil") + } + buf, err := GenerateRandomBytesWithReader(uuidLen, reader) if err != nil { return "", err } @@ -5433,6 +10323,7 @@ package uuid import ( "crypto/rand" + "io" "reflect" "regexp" "testing" @@ -5460,6 +10351,36 @@ func TestGenerateUUID(t *testing.T) { } } +func TestGenerateUUIDWithReader(t *testing.T) { + var nilReader io.Reader + str, err := GenerateUUIDWithReader(nilReader) + if err == nil { + t.Fatalf("should get an error with a nilReader") + } + if str != "" { + t.Fatalf("should get an empty string") + } + + prev, err := GenerateUUIDWithReader(rand.Reader) + if err != nil { + t.Fatal(err) + } + + id, err := GenerateUUIDWithReader(rand.Reader) + if err != nil { + t.Fatal(err) + } + if prev == id { + t.Fatalf("Should get a new ID!") + } + + matched, err := regexp.MatchString( + "[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}", id) + if !matched || err != nil { + t.Fatalf("expected match %s %v %s", id, matched, err) + } +} + func TestParseUUID(t *testing.T) { buf := make([]byte, 16) if _, err := rand.Read(buf); err != nil { @@ -5487,6 +10408,12 @@ func BenchmarkGenerateUUID(b *testing.B) { } } +func BenchmarkGenerateUUIDWithReader(b *testing.B) { + for n := 0; n < b.N; n++ { + _, _ = GenerateUUIDWithReader(rand.Reader) + } +} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .gitignore - github.com/hashicorp/golang-lru # Compiled Object files, Static and Dynamic libs (Shared Objects) @@ -8799,6 +13726,25 @@ import ( "fmt" ) +// NetError implements net.Error +type NetError struct { + err error + timeout bool + temporary bool +} + +func (e *NetError) Error() string { + return e.err.Error() +} + +func (e *NetError) Timeout() bool { + return e.timeout +} + +func (e *NetError) Temporary() bool { + return e.temporary +} + var ( // ErrInvalidVersion means we received a frame with an // invalid version @@ -8824,7 +13770,13 @@ var ( ErrRecvWindowExceeded = fmt.Errorf("recv window exceeded") // ErrTimeout is used when we reach an IO deadline - ErrTimeout = fmt.Errorf("i/o deadline reached") + ErrTimeout = &NetError{ + err: fmt.Errorf("i/o deadline reached"), + + // Error should meet net.Error interface for timeouts for compatability + // with standard library expectations, such as http servers. + timeout: true, + } // ErrStreamClosed is returned when using a closed stream ErrStreamClosed = fmt.Errorf("stream closed") @@ -9066,6 +14018,13 @@ type Config struct { // window size that we allow for a stream. MaxStreamWindowSize uint32 + // StreamOpenTimeout is the maximum amount of time that a stream will + // be allowed to remain in pending state while waiting for an ack from the peer. + // Once the timeout is reached the session will be gracefully closed. + // A zero value disables the StreamOpenTimeout allowing unbounded + // blocking on OpenStream calls. + StreamOpenTimeout time.Duration + // StreamCloseTimeout is the maximum time that a stream will allowed to // be in a half-closed state when `Close` is called before forcibly // closing the connection. Forcibly closed connections will empty the @@ -9091,6 +14050,7 @@ func DefaultConfig() *Config { ConnectionWriteTimeout: 10 * time.Second, MaxStreamWindowSize: initialStreamWindow, StreamCloseTimeout: 5 * time.Minute, + StreamOpenTimeout: 75 * time.Second, LogOutput: os.Stderr, } } @@ -9146,6 +14106,7 @@ package yamux import ( "bufio" + "bytes" "fmt" "io" "io/ioutil" @@ -9207,24 +14168,27 @@ type Session struct { // sendCh is used to mark a stream as ready to send, // or to send a header out directly. - sendCh chan sendReady + sendCh chan *sendReady // recvDoneCh is closed when recv() exits to avoid a race // between stream registration and stream shutdown recvDoneCh chan struct{} + sendDoneCh chan struct{} // shutdown is used to safely close a session - shutdown bool - shutdownErr error - shutdownCh chan struct{} - shutdownLock sync.Mutex + shutdown bool + shutdownErr error + shutdownCh chan struct{} + shutdownLock sync.Mutex + shutdownErrLock sync.Mutex } // sendReady is used to either mark a stream as ready // or to directly send a header type sendReady struct { Hdr []byte - Body io.Reader + mu sync.Mutex // Protects Body from unsafe reads. + Body []byte Err chan error } @@ -9245,8 +14209,9 @@ func newSession(config *Config, conn io.ReadWriteCloser, client bool) *Session { inflight: make(map[uint32]struct{}), synCh: make(chan struct{}, config.AcceptBacklog), acceptCh: make(chan *Stream, config.AcceptBacklog), - sendCh: make(chan sendReady, 64), + sendCh: make(chan *sendReady, 64), recvDoneCh: make(chan struct{}), + sendDoneCh: make(chan struct{}), shutdownCh: make(chan struct{}), } if client { @@ -9328,6 +14293,10 @@ GET_ID: s.inflight[id] = struct{}{} s.streamLock.Unlock() + if s.config.StreamOpenTimeout > 0 { + go s.setOpenTimeout(stream) + } + // Send the window update to create if err := stream.sendWindowUpdate(); err != nil { select { @@ -9340,6 +14309,27 @@ GET_ID: return stream, nil } +// setOpenTimeout implements a timeout for streams that are opened but not established. +// If the StreamOpenTimeout is exceeded we assume the peer is unable to ACK, +// and close the session. +// The number of running timers is bounded by the capacity of the synCh. +func (s *Session) setOpenTimeout(stream *Stream) { + timer := time.NewTimer(s.config.StreamOpenTimeout) + defer timer.Stop() + + select { + case <-stream.establishCh: + return + case <-s.shutdownCh: + return + case <-timer.C: + // Timeout reached while waiting for ACK. + // Close the session to force connection re-establishment. + s.logger.Printf("[ERR] yamux: aborted stream open (destination=%s): %v", s.RemoteAddr().String(), ErrTimeout.err) + s.Close() + } +} + // Accept is used to block until the next available stream // is ready to be accepted. func (s *Session) Accept() (net.Conn, error) { @@ -9374,10 +14364,15 @@ func (s *Session) Close() error { return nil } s.shutdown = true + + s.shutdownErrLock.Lock() if s.shutdownErr == nil { s.shutdownErr = ErrSessionShutdown } + s.shutdownErrLock.Unlock() + close(s.shutdownCh) + s.conn.Close() <-s.recvDoneCh @@ -9386,17 +14381,18 @@ func (s *Session) Close() error { for _, stream := range s.streams { stream.forceClose() } + <-s.sendDoneCh return nil } // exitErr is used to handle an error that is causing the // session to terminate. func (s *Session) exitErr(err error) { - s.shutdownLock.Lock() + s.shutdownErrLock.Lock() if s.shutdownErr == nil { s.shutdownErr = err } - s.shutdownLock.Unlock() + s.shutdownErrLock.Unlock() s.Close() } @@ -9471,7 +14467,7 @@ func (s *Session) keepalive() { } // waitForSendErr waits to send a header, checking for a potential shutdown -func (s *Session) waitForSend(hdr header, body io.Reader) error { +func (s *Session) waitForSend(hdr header, body []byte) error { errCh := make(chan error, 1) return s.waitForSendErr(hdr, body, errCh) } @@ -9479,7 +14475,7 @@ func (s *Session) waitForSend(hdr header, body io.Reader) error { // waitForSendErr waits to send a header with optional data, checking for a // potential shutdown. Since there's the expectation that sends can happen // in a timely manner, we enforce the connection write timeout here. -func (s *Session) waitForSendErr(hdr header, body io.Reader, errCh chan error) error { +func (s *Session) waitForSendErr(hdr header, body []byte, errCh chan error) error { t := timerPool.Get() timer := t.(*time.Timer) timer.Reset(s.config.ConnectionWriteTimeout) @@ -9492,7 +14488,7 @@ func (s *Session) waitForSendErr(hdr header, body io.Reader, errCh chan error) e timerPool.Put(t) }() - ready := sendReady{Hdr: hdr, Body: body, Err: errCh} + ready := &sendReady{Hdr: hdr, Body: body, Err: errCh} select { case s.sendCh <- ready: case <-s.shutdownCh: @@ -9501,12 +14497,34 @@ func (s *Session) waitForSendErr(hdr header, body io.Reader, errCh chan error) e return ErrConnectionWriteTimeout } + bodyCopy := func() { + if body == nil { + return // A nil body is ignored. + } + + // In the event of session shutdown or connection write timeout, + // we need to prevent `send` from reading the body buffer after + // returning from this function since the caller may re-use the + // underlying array. + ready.mu.Lock() + defer ready.mu.Unlock() + + if ready.Body == nil { + return // Body was already copied in `send`. + } + newBody := make([]byte, len(body)) + copy(newBody, body) + ready.Body = newBody + } + select { case err := <-errCh: return err case <-s.shutdownCh: + bodyCopy() return ErrSessionShutdown case <-timer.C: + bodyCopy() return ErrConnectionWriteTimeout } } @@ -9528,7 +14546,7 @@ func (s *Session) sendNoWait(hdr header) error { }() select { - case s.sendCh <- sendReady{Hdr: hdr}: + case s.sendCh <- &sendReady{Hdr: hdr}: return nil case <-s.shutdownCh: return ErrSessionShutdown @@ -9539,39 +14557,59 @@ func (s *Session) sendNoWait(hdr header) error { // send is a long running goroutine that sends data func (s *Session) send() { + if err := s.sendLoop(); err != nil { + s.exitErr(err) + } +} + +func (s *Session) sendLoop() error { + defer close(s.sendDoneCh) + var bodyBuf bytes.Buffer for { + bodyBuf.Reset() + select { case ready := <-s.sendCh: // Send a header if ready if ready.Hdr != nil { - sent := 0 - for sent < len(ready.Hdr) { - n, err := s.conn.Write(ready.Hdr[sent:]) - if err != nil { - s.logger.Printf("[ERR] yamux: Failed to write header: %v", err) - asyncSendErr(ready.Err, err) - s.exitErr(err) - return - } - sent += n + _, err := s.conn.Write(ready.Hdr) + if err != nil { + s.logger.Printf("[ERR] yamux: Failed to write header: %v", err) + asyncSendErr(ready.Err, err) + return err } } - // Send data from a body if given + ready.mu.Lock() if ready.Body != nil { - _, err := io.Copy(s.conn, ready.Body) + // Copy the body into the buffer to avoid + // holding a mutex lock during the write. + _, err := bodyBuf.Write(ready.Body) + if err != nil { + ready.Body = nil + ready.mu.Unlock() + s.logger.Printf("[ERR] yamux: Failed to copy body into buffer: %v", err) + asyncSendErr(ready.Err, err) + return err + } + ready.Body = nil + } + ready.mu.Unlock() + + if bodyBuf.Len() > 0 { + // Send data from a body if given + _, err := s.conn.Write(bodyBuf.Bytes()) if err != nil { s.logger.Printf("[ERR] yamux: Failed to write body: %v", err) asyncSendErr(ready.Err, err) - s.exitErr(err) - return + return err } } // No error, successful send asyncSendErr(ready.Err, nil) case <-s.shutdownCh: - return + return nil } } } @@ -9758,8 +14796,9 @@ func (s *Session) incomingStream(id uint32) error { // Backlog exceeded! RST the stream s.logger.Printf("[WARN] yamux: backlog exceeded, forcing connection reset") delete(s.streams, id) - stream.sendHdr.encode(typeWindowUpdate, flagRST, id, 0) - return s.sendNoWait(stream.sendHdr) + hdr := header(make([]byte, headerSize)) + hdr.encode(typeWindowUpdate, flagRST, id, 0) + return s.sendNoWait(hdr) } } @@ -9806,6 +14845,7 @@ import ( "io" "io/ioutil" "log" + "net" "reflect" "runtime" "strings" @@ -10073,6 +15113,39 @@ func TestAccept(t *testing.T) { } } +func TestOpenStreamTimeout(t *testing.T) { + const timeout = 25 * time.Millisecond + + cfg := testConf() + cfg.StreamOpenTimeout = timeout + + client, server := testClientServerConfig(cfg) + defer client.Close() + defer server.Close() + + clientLogs := captureLogs(client) + + // Open a single stream without a server to acknowledge it. + s, err := client.OpenStream() + if err != nil { + t.Fatal(err) + } + + // Sleep for longer than the stream open timeout. + // Since no ACKs are received, the stream and session should be closed. + time.Sleep(timeout * 5) + + if !clientLogs.match([]string{"[ERR] yamux: aborted stream open (destination=yamux:remote): i/o deadline reached"}) { + t.Fatalf("server log incorect: %v", clientLogs.logs()) + } + if s.state != streamClosed { + t.Fatalf("stream should have been closed") + } + if !client.IsClosed() { + t.Fatalf("session should have been closed") + } +} + func TestClose_closeTimeout(t *testing.T) { conf := testConf() conf.StreamCloseTimeout = 10 * time.Millisecond @@ -10229,16 +15302,16 @@ func TestSendData_Small(t *testing.T) { }() select { case <-doneCh: + if client.NumStreams() != 0 { + t.Fatalf("bad") + } + if server.NumStreams() != 0 { + t.Fatalf("bad") + } + return case <-time.After(time.Second): panic("timeout") } - - if client.NumStreams() != 0 { - t.Fatalf("bad") - } - if server.NumStreams() != 0 { - t.Fatalf("bad") - } } func TestSendData_Large(t *testing.T) { @@ -10309,7 +15382,6 @@ func TestSendData_Large(t *testing.T) { t.Fatalf("err: %v", err) } }() - doneCh := make(chan struct{}) go func() { wg.Wait() @@ -10317,6 +15389,7 @@ func TestSendData_Large(t *testing.T) { }() select { case <-doneCh: + return case <-time.After(5 * time.Second): panic("timeout") } @@ -10541,6 +15614,62 @@ func TestHalfClose(t *testing.T) { } } +func TestHalfCloseSessionShutdown(t *testing.T) { + client, server := testClientServer() + defer client.Close() + defer server.Close() + + // dataSize must be large enough to ensure the server will send a window + // update + dataSize := int64(server.config.MaxStreamWindowSize) + + data := make([]byte, dataSize) + for idx := range data { + data[idx] = byte(idx % 256) + } + + stream, err := client.Open() + if err != nil { + t.Fatalf("err: %v", err) + } + if _, err = stream.Write(data); err != nil { + t.Fatalf("err: %v", err) + } + + stream2, err := server.Accept() + if err != nil { + t.Fatalf("err: %v", err) + } + + if err := stream.Close(); err != nil { + t.Fatalf("err: %v", err) + } + + // Shut down the session of the sending side. This should not cause reads + // to fail on the receiving side. + if err := client.Close(); err != nil { + t.Fatalf("err: %v", err) + } + + buf := make([]byte, dataSize) + n, err := stream2.Read(buf) + if err != nil { + t.Fatalf("err: %v", err) + } + if int64(n) != dataSize { + t.Fatalf("bad: %v", n) + } + + // EOF after close + n, err = stream2.Read(buf) + if err != io.EOF { + t.Fatalf("err: %v", err) + } + if n != 0 { + t.Fatalf("bad: %v", n) + } +} + func TestReadDeadline(t *testing.T) { client, server := testClientServer() defer client.Close() @@ -10563,9 +15692,27 @@ func TestReadDeadline(t *testing.T) { } buf := make([]byte, 4) - if _, err := stream.Read(buf); err != ErrTimeout { + _, err = stream.Read(buf) + if err != ErrTimeout { t.Fatalf("err: %v", err) } + + // See https://github.com/hashicorp/yamux/issues/90 + // The standard library's http server package will read from connections in + // the background to detect if they are alive. + // + // It sets a read deadline on connections and detect if the returned error + // is a network timeout error which implements net.Error. + // + // The HTTP server will cancel all server requests if it isn't timeout error + // from the connection. + // + // We assert that we return an error meeting the interface to avoid + // accidently breaking yamux session compatability with the standard + // library's http server implementation. + if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() { + t.Fatalf("reading timeout error is expected to implement net.Error and return true when calling Timeout()") + } } func TestReadDeadline_BlockedRead(t *testing.T) { @@ -10795,6 +15942,8 @@ func TestKeepAlive_Timeout(t *testing.T) { t.Fatalf("timeout waiting for timeout") } + clientConn.writeBlocker.Unlock() + if !server.IsClosed() { t.Fatalf("server should have closed") } @@ -10991,6 +16140,7 @@ func TestSession_WindowUpdateWriteDuringRead(t *testing.T) { conn := client.conn.(*pipeConn) conn.writeBlocker.Lock() + defer conn.writeBlocker.Unlock() _, err = stream.Read(make([]byte, flood)) if err != ErrConnectionWriteTimeout { @@ -11086,6 +16236,7 @@ func TestSession_sendNoWait_Timeout(t *testing.T) { conn := client.conn.(*pipeConn) conn.writeBlocker.Lock() + defer conn.writeBlocker.Unlock() hdr := header(make([]byte, headerSize)) hdr.encode(typePing, flagACK, 0, 0) @@ -11206,6 +16357,7 @@ func TestSession_ConnectionWriteTimeout(t *testing.T) { conn := client.conn.(*pipeConn) conn.writeBlocker.Lock() + defer conn.writeBlocker.Unlock() // Since the write goroutine is blocked then this will return a // timeout since it can't get feedback about whether the write @@ -11371,6 +16523,7 @@ package yamux import ( "bytes" + "errors" "io" "sync" "sync/atomic" @@ -11419,6 +16572,9 @@ type Stream struct { readDeadline atomic.Value // time.Time writeDeadline atomic.Value // time.Time + // establishCh is notified if the stream is established or being closed. + establishCh chan struct{} + // closeTimer is set with stateLock held to honor the StreamCloseTimeout // setting on Session. closeTimer *time.Timer @@ -11439,6 +16595,7 @@ func newStream(session *Session, id uint32, state streamState) *Stream { sendWindow: initialStreamWindow, recvNotifyCh: make(chan struct{}, 1), sendNotifyCh: make(chan struct{}, 1), + establishCh: make(chan struct{}, 1), } s.readDeadline.Store(time.Time{}) s.writeDeadline.Store(time.Time{}) @@ -11492,6 +16649,9 @@ START: // Send a window update potentially err = s.sendWindowUpdate() + if err == ErrSessionShutdown { + err = nil + } return n, err WAIT: @@ -11534,7 +16694,7 @@ func (s *Stream) Write(b []byte) (n int, err error) { func (s *Stream) write(b []byte) (n int, err error) { var flags uint16 var max uint32 - var body io.Reader + var body []byte START: s.stateLock.Lock() switch s.state { @@ -11560,11 +16720,15 @@ START: // Send up to our send window max = min(window, uint32(len(b))) - body = bytes.NewReader(b[:max]) + body = b[:max] // Send the header s.sendHdr.encode(typeData, flags, s.id, max) if err = s.session.waitForSendErr(s.sendHdr, body, s.sendErr); err != nil { + if errors.Is(err, ErrSessionShutdown) || errors.Is(err, ErrConnectionWriteTimeout) { + // Message left in ready queue, header re-use is unsafe. + s.sendHdr = header(make([]byte, headerSize)) + } return 0, err } @@ -11638,6 +16802,10 @@ func (s *Stream) sendWindowUpdate() error { // Send the header s.controlHdr.encode(typeWindowUpdate, flags, s.id, delta) if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil { + if errors.Is(err, ErrSessionShutdown) || errors.Is(err, ErrConnectionWriteTimeout) { + // Message left in ready queue, header re-use is unsafe. + s.controlHdr = header(make([]byte, headerSize)) + } return err } return nil @@ -11652,6 +16820,10 @@ func (s *Stream) sendClose() error { flags |= flagFIN s.controlHdr.encode(typeWindowUpdate, flags, s.id, 0) if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil { + if errors.Is(err, ErrSessionShutdown) || errors.Is(err, ErrConnectionWriteTimeout) { + // Message left in ready queue, header re-use is unsafe. + s.controlHdr = header(make([]byte, headerSize)) + } return err } return nil @@ -11727,8 +16899,9 @@ func (s *Stream) closeTimeout() { // Send a RST so the remote side closes too. s.sendLock.Lock() defer s.sendLock.Unlock() - s.sendHdr.encode(typeWindowUpdate, flagRST, s.id, 0) - s.session.sendNoWait(s.sendHdr) + hdr := header(make([]byte, headerSize)) + hdr.encode(typeWindowUpdate, flagRST, s.id, 0) + s.session.sendNoWait(hdr) } // forceClose is used for when the session is exiting @@ -11762,6 +16935,7 @@ func (s *Stream) processFlags(flags uint16) error { if s.state == streamSYNSent { s.state = streamEstablished } + asyncNotify(s.establishCh) s.session.establishStream(s.id) } if flags&flagFIN == flagFIN { @@ -11794,6 +16968,7 @@ func (s *Stream) processFlags(flags uint16) error { func (s *Stream) notifyWaiting() { asyncNotify(s.recvNotifyCh) asyncNotify(s.sendNotifyCh) + asyncNotify(s.establishCh) } // incrSendWindow updates the size of our send window @@ -11828,6 +17003,7 @@ func (s *Stream) readData(hdr header, flags uint16, conn io.Reader) error { if length > s.recvWindow { s.session.logger.Printf("[ERR] yamux: receive window exceeded (stream: %d, remain: %d, recv: %d)", s.id, s.recvWindow, length) + s.recvLock.Unlock() return ErrRecvWindowExceeded } @@ -11836,14 +17012,15 @@ func (s *Stream) readData(hdr header, flags uint16, conn io.Reader) error { // This way we can read in the whole packet without further allocations. s.recvBuf = bytes.NewBuffer(make([]byte, 0, length)) } - if _, err := io.Copy(s.recvBuf, conn); err != nil { + copiedLength, err := io.Copy(s.recvBuf, conn) + if err != nil { s.session.logger.Printf("[ERR] yamux: Failed to read stream data: %v", err) s.recvLock.Unlock() return err } // Decrement the receive window - s.recvWindow -= length + s.recvWindow -= uint32(copiedLength) s.recvLock.Unlock() // Unblock any readers @@ -12329,6 +17506,414 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/jcmturner/aescts/v2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/jcmturner/dnsutils/v2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/jcmturner/gofork Copyright (c) 2009 The Go Authors. All rights reserved. @@ -12359,6 +17944,618 @@ 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. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/jcmturner/goidentity/v6 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/jcmturner/gokrb5/v8 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/jcmturner/rpc/v2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/jdkato/prose MIT License @@ -12473,6 +18670,30 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LICENSE - github.com/leonelquinteros/gotext +The MIT License (MIT) + +Copyright (c) 2016 Leonel Quinteros + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/libgit2/git2go/v33 The MIT License @@ -13461,10 +19682,10 @@ LICENSE - github.com/opentracing/opentracing-go limitations under the License. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - github.com/pelletier/go-toml +LICENSE - github.com/pelletier/go-toml/v2 The MIT License (MIT) -Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton +Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -14482,7 +20703,7 @@ SoundCloud Ltd. (http://soundcloud.com/). LICENSE - github.com/rubenv/sql-migrate MIT License -Copyright (C) 2014-2019 by Ruben Vermeersch +Copyright (C) 2014-2021 by Ruben Vermeersch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -15363,358 +21584,6 @@ LICENSE - github.com/xanzy/ssh-agent limitations under the License. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -license_test.go - gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository -package repository - -import ( - "context" - "os" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" -) - -func testSuccessfulFindLicenseRequest(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { - testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { - for _, tc := range []struct { - desc string - nonExistentRepository bool - files map[string]string - expectedLicense string - errorContains string - }{ - { - desc: "repository does not exist", - nonExistentRepository: true, - errorContains: "rpc error: code = NotFound desc = GetRepoPath: not a git repository", - }, - { - desc: "empty if no license file in repo", - files: map[string]string{ - "README.md": "readme content", - }, - expectedLicense: "", - }, - { - desc: "high confidence mit result and less confident mit-0 result", - files: map[string]string{ - "LICENSE": `MIT License - -Copyright (c) [year] [fullname] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.`, - }, - expectedLicense: "mit", - }, - { - desc: "unknown license", - files: map[string]string{ - "LICENSE.md": "this doesn't match any known license", - }, - expectedLicense: "other", - }, - } { - t.Run(tc.desc, func(t *testing.T) { - repo, repoPath := gittest.CreateRepository(ctx, t, cfg) - - var treeEntries []gittest.TreeEntry - for file, content := range tc.files { - treeEntries = append(treeEntries, gittest.TreeEntry{ - Mode: "100644", - Path: file, - Content: content, - }) - } - - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithTreeEntries(treeEntries...), gittest.WithParents()) - - if tc.nonExistentRepository { - require.NoError(t, os.RemoveAll(repoPath)) - } - - resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) - if tc.errorContains != "" { - require.Error(t, err) - require.Contains(t, err.Error(), tc.errorContains) - return - } - - require.NoError(t, err) - testhelper.ProtoEqual(t, &gitalypb.FindLicenseResponse{ - LicenseShortName: tc.expectedLicense, - }, resp) - }) - } - }) -} - -func testFindLicenseRequestEmptyRepo(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { - testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { - repo, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) - require.NoError(t, os.RemoveAll(repoPath)) - - _, err := client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{Repository: repo}) - require.NoError(t, err) - - resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) - require.NoError(t, err) - - require.Empty(t, resp.GetLicenseShortName()) - }) -} - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler -Copyright (c) 2016 Masahiro Sano - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE.txt - gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gitlab.com/gitlab-org/gitlab-shell/client -Copyright (c) 2011-2018 GitLab B.V. - -With regard to the GitLab Software: - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - gitlab.com/gitlab-org/labkit The MIT License (MIT) @@ -16959,6 +22828,22 @@ LICENSE - google.golang.org/grpc See the License for the specific language governing permissions and limitations under the License. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NOTICE.txt - google.golang.org/grpc +Copyright 2014 gRPC authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - google.golang.org/protobuf Copyright (c) 2018 The Go Authors. All rights reserved. @@ -16989,847 +22874,6 @@ 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gopkg.in/gorp.v1 -(The MIT License) - -Copyright (c) 2012 James Cooper - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gopkg.in/jcmturner/aescts.v1 - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gopkg.in/jcmturner/dnsutils.v1 - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gopkg.in/jcmturner/gokrb5.v5 - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - gopkg.in/jcmturner/rpc.v0/ndr - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE.md - gopkg.in/neurosnap/sentences.v1 The MIT License (MIT) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/README.md similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/README.md index 3c304af70c..8ef7bd5027 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/README.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/README.md @@ -2,8 +2,8 @@ **Quick Links**: [**Roadmap**][roadmap] | - [Want to Contribute?](https://gitlab.com/gitlab-org/gitaly/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=Accepting%20merge%20requests) | - [GitLab Gitaly Issues](https://gitlab.com/groups/gitlab-org/-/issues?scope=all&state=opened&utf8=%E2%9C%93&label_name%5B%5D=Gitaly) | + [Want to Contribute?](https://gitlab.com/gitlab-org/gitaly/issues?scope=all&state=opened&label_name[]=Accepting%20merge%20requests) | + [GitLab Gitaly Issues](https://gitlab.com/groups/gitlab-org/-/issues?scope=all&state=opened&label_name%5B%5D=Gitaly) | [GitLab Gitaly Merge Requests](https://gitlab.com/groups/gitlab-org/-/merge_requests?label_name%5B%5D=Gitaly) | -------------------------------------------- @@ -43,18 +43,22 @@ GitLab.com, read about our [observability story](doc/observability.md)! ##### Overall -[![image](https://gitlab.com/gitlab-org/gitaly/uploads/c3aa987884d5e78c3567a3a7469ea6c2/overview.png)](https://dashboards.gitlab.com/d/gitaly-main/gitaly-overview) +![image](https://gitlab.com/gitlab-org/gitaly/uploads/c3aa987884d5e78c3567a3a7469ea6c2/overview.png) + +[Dashboard](https://dashboards.gitlab.net/d/gitaly-main/gitaly-overview) (The link can be accessed by GitLab team members.) ##### By Feature -[![image](https://gitlab.com/gitlab-org/gitaly/uploads/3e8a5616863fa17c5bf08cb67c1bb385/feature.png)](https://dashboards.gitlab.com/d/000000198/gitaly-features-overview) +![image](https://gitlab.com/gitlab-org/gitaly/uploads/3e8a5616863fa17c5bf08cb67c1bb385/feature.png) + +[Dashboard](https://dashboards.gitlab.net/d/000000198/gitaly-features-overview?orgId=1) (The link can be accessed by GitLab team members.) ## Installation Most users won't install Gitaly on its own. It is already included in [your GitLab installation](https://about.gitlab.com/install/). -Gitaly requires Go 1.16 or Go 1.17 and Ruby 2.7. Run `make` to download and +Gitaly requires Go 1.17 or Go 1.18 and Ruby 2.7. Run `make` to download and compile Ruby dependencies, and to compile the Gitaly Go executable. Gitaly uses `git`. Versions `2.33.0` and newer are supported. @@ -166,6 +170,9 @@ Gitaly supports Continuous Profiling through [LabKit][] using [Stackdriver Profi For more information on how to set it up, see the [LabKit monitoring docs](https://gitlab.com/gitlab-org/labkit/-/blob/master/monitoring/doc.go). ## Presentations +- [Praefect code walkthrough](https://youtu.be/w2R4ptDLPH4) + + A walkthrough of the Praefect codebase. - [How to configure backpressure in Gitaly](https://youtu.be/wX9CtFdLYxE) @@ -222,7 +229,7 @@ For more information on how to set it up, see the [LabKit monitoring docs](https - [Part 7: How Gitaly uses Prometheus monitoring, 2019-07-09](https://youtu.be/R6F674Nj3wI) What is [Prometheus](https://prometheus.io/). Reconstructing a - [Grafana](https://dashboards.gitlab.com) dashboard panel + [Grafana](https://dashboards.gitlab.net) dashboard panel with [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics/). Adding a new counter to Gitaly. Querying Prometheus in Gitaly @@ -236,5 +243,5 @@ For more information on how to set it up, see the [LabKit monitoring docs](https - [Gitaly Basics, 2017-05-01](https://docs.google.com/presentation/d/1cLslUbXVkniOaeJ-r3s5AYF0kQep8VeNfvs0XSGrpA0/edit#slide=id.g1c73db867d_0_0) - [Git Paris meetup, 2017-02-22](https://docs.google.com/presentation/d/19OZUalFMIDM8WujXrrIyCuVb_oVeaUzpb-UdGThOvAo/edit?usp=sharing) a high-level overview of what our plans are and where we are. -[roadmap]: https://gitlab.com/groups/gitlab-org/-/roadmap?scope=all&utf8=%E2%9C%93&label_name[]=group%3A%3Agitaly +[roadmap]: https://gitlab.com/groups/gitlab-org/-/roadmap?scope=all&label_name[]=group%3A%3Agitaly [LabKit]: https://gitlab.com/gitlab-org/labkit/ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/REVIEWING.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/REVIEWING.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/REVIEWING.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/REVIEWING.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/STYLE.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/STYLE.md similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/STYLE.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/STYLE.md index fbf61a061c..667973ee55 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/STYLE.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/STYLE.md @@ -243,6 +243,21 @@ tests are supposed to set up required state as part of the tests themselves. All `TestMain()` functions must call `testhelper.Run()` though, which performs the setup of global state required for tests. +### Test data + +Tests should not rely on static Git data but instead generate test data at +runtime if possible. This is done so that we can easily adapt to changes in +Git's repository or object format, e.g. in the transition from the SHA1 to the +SHA256 object hash. Using seed repositories is thus discouraged. + +As an alternative, tests can rely on the following helper functions to generate +their test data: + +- `gittest.WriteCommit()` +- `gittest.WriteTree()` +- `gittest.WriteBlob()` +- `gittest.WriteTag()` + ## Black box and white box testing The dominant style of testing in Gitaly is "white box" testing, meaning diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/VERSION b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/VERSION new file mode 100644 index 0000000000..baec1bc73e --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/VERSION @@ -0,0 +1 @@ +15.4.2 \ No newline at end of file diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/bad-proxies b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/bad-proxies similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/bad-proxies rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/bad-proxies diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/config.praefect.toml.ci-sql-test.erb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/config.praefect.toml.ci-sql-test.erb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/config.praefect.toml.ci-sql-test.erb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/config.praefect.toml.ci-sql-test.erb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/generate-praefect-schema b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/generate-praefect-schema similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/generate-praefect-schema rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/generate-praefect-schema diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/generate-proto-ruby b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/generate-proto-ruby similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/generate-proto-ruby rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/generate-proto-ruby diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0019-fetch-pack-use-commit-graph-when-computing-cutoff.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0019-fetch-pack-use-commit-graph-when-computing-cutoff.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0019-fetch-pack-use-commit-graph-when-computing-cutoff.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0019-fetch-pack-use-commit-graph-when-computing-cutoff.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0020-fetch-skip-computing-output-width-when-not-printing-.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0020-fetch-skip-computing-output-width-when-not-printing-.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0020-fetch-skip-computing-output-width-when-not-printing-.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0020-fetch-skip-computing-output-width-when-not-printing-.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0021-refs-extract-packed_refs_delete_refs-to-allow-contro.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0021-refs-extract-packed_refs_delete_refs-to-allow-contro.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0021-refs-extract-packed_refs_delete_refs-to-allow-contro.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0021-refs-extract-packed_refs_delete_refs-to-allow-contro.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0022-refs-allow-passing-flags-when-beginning-transactions.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0022-refs-allow-passing-flags-when-beginning-transactions.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0022-refs-allow-passing-flags-when-beginning-transactions.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0022-refs-allow-passing-flags-when-beginning-transactions.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0023-refs-allow-skipping-the-reference-transaction-hook.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0023-refs-allow-skipping-the-reference-transaction-hook.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0023-refs-allow-skipping-the-reference-transaction-hook.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0023-refs-allow-skipping-the-reference-transaction-hook.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0024-refs-demonstrate-excessive-execution-of-the-referenc.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0024-refs-demonstrate-excessive-execution-of-the-referenc.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0024-refs-demonstrate-excessive-execution-of-the-referenc.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0024-refs-demonstrate-excessive-execution-of-the-referenc.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0025-refs-do-not-execute-reference-transaction-hook-on-pa.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0025-refs-do-not-execute-reference-transaction-hook-on-pa.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0025-refs-do-not-execute-reference-transaction-hook-on-pa.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0025-refs-do-not-execute-reference-transaction-hook-on-pa.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0026-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0026-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0026-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0026-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0027-fetch-prune-exit-with-error-if-pruning-fails.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0027-fetch-prune-exit-with-error-if-pruning-fails.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0027-fetch-prune-exit-with-error-if-pruning-fails.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0027-fetch-prune-exit-with-error-if-pruning-fails.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0028-fetch-increase-test-coverage-of-fetches.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0028-fetch-increase-test-coverage-of-fetches.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0028-fetch-increase-test-coverage-of-fetches.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0028-fetch-increase-test-coverage-of-fetches.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0029-fetch-backfill-tags-before-setting-upstream.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0029-fetch-backfill-tags-before-setting-upstream.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0029-fetch-backfill-tags-before-setting-upstream.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0029-fetch-backfill-tags-before-setting-upstream.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0030-fetch-control-lifecycle-of-FETCH_HEAD-in-a-single-pl.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0030-fetch-control-lifecycle-of-FETCH_HEAD-in-a-single-pl.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0030-fetch-control-lifecycle-of-FETCH_HEAD-in-a-single-pl.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0030-fetch-control-lifecycle-of-FETCH_HEAD-in-a-single-pl.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0031-fetch-report-errors-when-backfilling-tags-fails.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0031-fetch-report-errors-when-backfilling-tags-fails.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0031-fetch-report-errors-when-backfilling-tags-fails.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0031-fetch-report-errors-when-backfilling-tags-fails.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0032-refs-add-interface-to-iterate-over-queued-transactio.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0032-refs-add-interface-to-iterate-over-queued-transactio.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0032-refs-add-interface-to-iterate-over-queued-transactio.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0032-refs-add-interface-to-iterate-over-queued-transactio.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0033-fetch-make-atomic-flag-cover-backfilling-of-tags.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0033-fetch-make-atomic-flag-cover-backfilling-of-tags.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0033-fetch-make-atomic-flag-cover-backfilling-of-tags.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0033-fetch-make-atomic-flag-cover-backfilling-of-tags.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0034-fetch-make-atomic-flag-cover-pruning-of-refs.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0034-fetch-make-atomic-flag-cover-pruning-of-refs.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0034-fetch-make-atomic-flag-cover-pruning-of-refs.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0034-fetch-make-atomic-flag-cover-pruning-of-refs.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0035-upload-pack-look-up-want-lines-via-commit-graph.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0035-upload-pack-look-up-want-lines-via-commit-graph.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0035-upload-pack-look-up-want-lines-via-commit-graph.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0035-upload-pack-look-up-want-lines-via-commit-graph.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0036-fetch-avoid-lookup-of-commits-when-not-appending-to-.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0036-fetch-avoid-lookup-of-commits-when-not-appending-to-.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0036-fetch-avoid-lookup-of-commits-when-not-appending-to-.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0036-fetch-avoid-lookup-of-commits-when-not-appending-to-.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0037-refs-add-ability-for-backends-to-special-case-readin.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0037-refs-add-ability-for-backends-to-special-case-readin.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0037-refs-add-ability-for-backends-to-special-case-readin.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0037-refs-add-ability-for-backends-to-special-case-readin.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0038-remote-read-symbolic-refs-via-refs_read_symbolic_ref.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0038-remote-read-symbolic-refs-via-refs_read_symbolic_ref.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0038-remote-read-symbolic-refs-via-refs_read_symbolic_ref.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0038-remote-read-symbolic-refs-via-refs_read_symbolic_ref.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0039-refs-files-backend-optimize-reading-of-symbolic-refs.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0039-refs-files-backend-optimize-reading-of-symbolic-refs.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/git-patches/v2.35.1.gl1/0039-refs-files-backend-optimize-reading-of-symbolic-refs.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.35.1.gl1/0039-refs-files-backend-optimize-reading-of-symbolic-refs.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0001-refs-extract-packed_refs_delete_refs-to-allow-contro.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0001-refs-extract-packed_refs_delete_refs-to-allow-contro.patch new file mode 100644 index 0000000000..47dd3e41ce --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0001-refs-extract-packed_refs_delete_refs-to-allow-contro.patch @@ -0,0 +1,156 @@ +From c74f385fb46855ac0db222b6845ddb95e6a36264 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:31 +0100 +Subject: [PATCH 21/34] refs: extract packed_refs_delete_refs() to allow + control of transaction + +When deleting loose refs, then we also have to delete the refs in the +packed backend. This is done by calling `refs_delete_refs()`, which +then uses the packed-backend's logic to delete refs. This doesn't allow +us to exercise any control over the reference transaction which is being +created in the packed backend, which is required in a subsequent commit. + +Extract a new function `packed_refs_delete_refs()`, which hosts most of +the logic to delete refs except for creating the transaction itself. +Like this, we can easily create the transaction in the files backend +and thus exert more control over it. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit 69840cc0f7b4f3352903bd2b8f3de7077916c26b) +--- + refs/files-backend.c | 13 ++++++++++--- + refs/packed-backend.c | 26 ++++++++++++++++++++------ + refs/packed-backend.h | 7 +++++++ + 3 files changed, 37 insertions(+), 9 deletions(-) + +diff --git a/refs/files-backend.c b/refs/files-backend.c +index 43a3b882d7..18baea4c6a 100644 +--- a/refs/files-backend.c ++++ b/refs/files-backend.c +@@ -1244,6 +1244,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + { + struct files_ref_store *refs = + files_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); ++ struct ref_transaction *transaction = NULL; + struct strbuf err = STRBUF_INIT; + int i, result = 0; + +@@ -1253,10 +1254,14 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + if (packed_refs_lock(refs->packed_ref_store, 0, &err)) + goto error; + +- if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) { +- packed_refs_unlock(refs->packed_ref_store); ++ transaction = ref_store_transaction_begin(refs->packed_ref_store, &err); ++ if (!transaction) ++ goto error; ++ ++ result = packed_refs_delete_refs(refs->packed_ref_store, ++ transaction, msg, refnames, flags); ++ if (result) + goto error; +- } + + packed_refs_unlock(refs->packed_ref_store); + +@@ -1267,6 +1272,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + result |= error(_("could not remove reference %s"), refname); + } + ++ ref_transaction_free(transaction); + strbuf_release(&err); + return result; + +@@ -1283,6 +1289,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + else + error(_("could not delete references: %s"), err.buf); + ++ ref_transaction_free(transaction); + strbuf_release(&err); + return -1; + } +diff --git a/refs/packed-backend.c b/refs/packed-backend.c +index d91a2018f6..960b43ff76 100644 +--- a/refs/packed-backend.c ++++ b/refs/packed-backend.c +@@ -1521,15 +1521,10 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store, + static int packed_delete_refs(struct ref_store *ref_store, const char *msg, + struct string_list *refnames, unsigned int flags) + { +- struct packed_ref_store *refs = +- packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); + struct strbuf err = STRBUF_INIT; + struct ref_transaction *transaction; +- struct string_list_item *item; + int ret; + +- (void)refs; /* We need the check above, but don't use the variable */ +- + if (!refnames->nr) + return 0; + +@@ -1543,6 +1538,26 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg, + if (!transaction) + return -1; + ++ ret = packed_refs_delete_refs(ref_store, transaction, ++ msg, refnames, flags); ++ ++ ref_transaction_free(transaction); ++ return ret; ++} ++ ++int packed_refs_delete_refs(struct ref_store *ref_store, ++ struct ref_transaction *transaction, ++ const char *msg, ++ struct string_list *refnames, ++ unsigned int flags) ++{ ++ struct strbuf err = STRBUF_INIT; ++ struct string_list_item *item; ++ int ret; ++ ++ /* Assert that the ref store refers to a packed backend. */ ++ packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); ++ + for_each_string_list_item(item, refnames) { + if (ref_transaction_delete(transaction, item->string, NULL, + flags, msg, &err)) { +@@ -1562,7 +1577,6 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg, + error(_("could not delete references: %s"), err.buf); + } + +- ref_transaction_free(transaction); + strbuf_release(&err); + return ret; + } +diff --git a/refs/packed-backend.h b/refs/packed-backend.h +index 9dd8a344c3..52e0490753 100644 +--- a/refs/packed-backend.h ++++ b/refs/packed-backend.h +@@ -3,6 +3,7 @@ + + struct repository; + struct ref_transaction; ++struct string_list; + + /* + * Support for storing references in a `packed-refs` file. +@@ -27,6 +28,12 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) + void packed_refs_unlock(struct ref_store *ref_store); + int packed_refs_is_locked(struct ref_store *ref_store); + ++int packed_refs_delete_refs(struct ref_store *ref_store, ++ struct ref_transaction *transaction, ++ const char *msg, ++ struct string_list *refnames, ++ unsigned int flags); ++ + /* + * Return true if `transaction` really needs to be carried out against + * the specified packed_ref_store, or false if it can be skipped +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0002-refs-allow-passing-flags-when-beginning-transactions.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0002-refs-allow-passing-flags-when-beginning-transactions.patch new file mode 100644 index 0000000000..8038daca2f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0002-refs-allow-passing-flags-when-beginning-transactions.patch @@ -0,0 +1,183 @@ +From 60d0682e02db5c197c09bc4cd5a643dc2269cca2 Mon Sep 17 00:00:00 2001 +Message-Id: <60d0682e02db5c197c09bc4cd5a643dc2269cca2.1646206541.git.ps@pks.im> +In-Reply-To: +References: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:35 +0100 +Subject: [PATCH 22/34] refs: allow passing flags when beginning transactions + +We do not currently have any flags when creating reference transactions, +but we'll add one to disable execution of the reference transaction hook +in some cases. + +Allow passing flags to `ref_store_transaction_begin()` to prepare for +this change. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit fbe73f61cbc29f6c4a85478cf792c37dbe5aa26c) +--- + refs.c | 8 +++++--- + refs.h | 3 ++- + refs/files-backend.c | 10 +++++----- + refs/packed-backend.c | 2 +- + refs/refs-internal.h | 1 + + sequencer.c | 2 +- + 6 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/refs.c b/refs.c +index addb26293b..f498d232e5 100644 +--- a/refs.c ++++ b/refs.c +@@ -800,7 +800,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg, + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; + +- transaction = ref_store_transaction_begin(refs, &err); ++ transaction = ref_store_transaction_begin(refs, 0, &err); + if (!transaction || + ref_transaction_delete(transaction, refname, old_oid, + flags, msg, &err) || +@@ -1005,6 +1005,7 @@ int read_ref_at(struct ref_store *refs, const char *refname, + } + + struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, ++ unsigned int flags, + struct strbuf *err) + { + struct ref_transaction *tr; +@@ -1012,12 +1013,13 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, + + CALLOC_ARRAY(tr, 1); + tr->ref_store = refs; ++ tr->flags = flags; + return tr; + } + + struct ref_transaction *ref_transaction_begin(struct strbuf *err) + { +- return ref_store_transaction_begin(get_main_ref_store(the_repository), err); ++ return ref_store_transaction_begin(get_main_ref_store(the_repository), 0, err); + } + + void ref_transaction_free(struct ref_transaction *transaction) +@@ -1156,7 +1158,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg, + struct strbuf err = STRBUF_INIT; + int ret = 0; + +- t = ref_store_transaction_begin(refs, &err); ++ t = ref_store_transaction_begin(refs, 0, &err); + if (!t || + ref_transaction_update(t, refname, new_oid, old_oid, flags, msg, + &err) || +diff --git a/refs.h b/refs.h +index 8f91a7f9ff..3a141d7066 100644 +--- a/refs.h ++++ b/refs.h +@@ -231,7 +231,7 @@ char *repo_default_branch_name(struct repository *r, int quiet); + * struct strbuf err = STRBUF_INIT; + * int ret = 0; + * +- * transaction = ref_store_transaction_begin(refs, &err); ++ * transaction = ref_store_transaction_begin(refs, 0, &err); + * if (!transaction || + * ref_transaction_update(...) || + * ref_transaction_create(...) || +@@ -573,6 +573,7 @@ enum action_on_err { + * be freed by calling ref_transaction_free(). + */ + struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, ++ unsigned int flags, + struct strbuf *err); + struct ref_transaction *ref_transaction_begin(struct strbuf *err); + +diff --git a/refs/files-backend.c b/refs/files-backend.c +index 18baea4c6a..758d12a0fa 100644 +--- a/refs/files-backend.c ++++ b/refs/files-backend.c +@@ -1116,7 +1116,7 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) + if (check_refname_format(r->name, 0)) + return; + +- transaction = ref_store_transaction_begin(&refs->base, &err); ++ transaction = ref_store_transaction_begin(&refs->base, 0, &err); + if (!transaction) + goto cleanup; + ref_transaction_add_update( +@@ -1187,7 +1187,7 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) + struct strbuf err = STRBUF_INIT; + struct ref_transaction *transaction; + +- transaction = ref_store_transaction_begin(refs->packed_ref_store, &err); ++ transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, &err); + if (!transaction) + return -1; + +@@ -1254,7 +1254,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + if (packed_refs_lock(refs->packed_ref_store, 0, &err)) + goto error; + +- transaction = ref_store_transaction_begin(refs->packed_ref_store, &err); ++ transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, &err); + if (!transaction) + goto error; + +@@ -2769,7 +2769,7 @@ static int files_transaction_prepare(struct ref_store *ref_store, + */ + if (!packed_transaction) { + packed_transaction = ref_store_transaction_begin( +- refs->packed_ref_store, err); ++ refs->packed_ref_store, 0, err); + if (!packed_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; +@@ -3040,7 +3040,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store, + &affected_refnames)) + BUG("initial ref transaction called with existing refs"); + +- packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, err); ++ packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, err); + if (!packed_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; +diff --git a/refs/packed-backend.c b/refs/packed-backend.c +index 960b43ff76..27dd8c3922 100644 +--- a/refs/packed-backend.c ++++ b/refs/packed-backend.c +@@ -1534,7 +1534,7 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg, + * updates into a single transaction. + */ + +- transaction = ref_store_transaction_begin(ref_store, &err); ++ transaction = ref_store_transaction_begin(ref_store, 0, &err); + if (!transaction) + return -1; + +diff --git a/refs/refs-internal.h b/refs/refs-internal.h +index 7ff6fba4f0..6e15db3ca4 100644 +--- a/refs/refs-internal.h ++++ b/refs/refs-internal.h +@@ -213,6 +213,7 @@ struct ref_transaction { + size_t nr; + enum ref_transaction_state state; + void *backend_data; ++ unsigned int flags; + }; + + /* +diff --git a/sequencer.c b/sequencer.c +index 5213d16e97..5a2b609557 100644 +--- a/sequencer.c ++++ b/sequencer.c +@@ -3588,7 +3588,7 @@ static int do_label(struct repository *r, const char *name, int len) + strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name); + strbuf_addf(&msg, "rebase (label) '%.*s'", len, name); + +- transaction = ref_store_transaction_begin(refs, &err); ++ transaction = ref_store_transaction_begin(refs, 0, &err); + if (!transaction) { + error("%s", err.buf); + ret = -1; +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0003-refs-allow-skipping-the-reference-transaction-hook.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0003-refs-allow-skipping-the-reference-transaction-hook.patch new file mode 100644 index 0000000000..cd194f8aa6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0003-refs-allow-skipping-the-reference-transaction-hook.patch @@ -0,0 +1,60 @@ +From 4eccd16b45516df5ab02288d0c50c16e03cc44e4 Mon Sep 17 00:00:00 2001 +Message-Id: <4eccd16b45516df5ab02288d0c50c16e03cc44e4.1646206541.git.ps@pks.im> +In-Reply-To: +References: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:39 +0100 +Subject: [PATCH 23/34] refs: allow skipping the reference-transaction hook + +The reference-transaction hook is executing whenever we prepare, commit +or abort a reference transaction. While this is mostly intentional, in +case of the files backend we're leaking the implementation detail that +the store is in fact a composite store with one loose and one packed +backend to the caller. So while we want to execute the hook for all +logical updates, executing it for such implementation details is +unexpected. + +Prepare for a fix by adding a new flag which allows to skip execution of +the hook. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit 958fbc74e3d0fcc88b2065190e23db556a963644) +--- + refs.c | 3 +++ + refs.h | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/refs.c b/refs.c +index f498d232e5..435b90b1ec 100644 +--- a/refs.c ++++ b/refs.c +@@ -2084,6 +2084,9 @@ static int run_transaction_hook(struct ref_transaction *transaction, + const char *hook; + int ret = 0, i; + ++ if (transaction->flags & REF_TRANSACTION_SKIP_HOOK) ++ return 0; ++ + hook = find_hook("reference-transaction"); + if (!hook) + return ret; +diff --git a/refs.h b/refs.h +index 3a141d7066..a015354fd6 100644 +--- a/refs.h ++++ b/refs.h +@@ -568,6 +568,11 @@ enum action_on_err { + UPDATE_REFS_QUIET_ON_ERR + }; + ++/* ++ * Skip executing the reference-transaction hook. ++ */ ++#define REF_TRANSACTION_SKIP_HOOK (1 << 0) ++ + /* + * Begin a reference transaction. The reference transaction must + * be freed by calling ref_transaction_free(). +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0004-refs-demonstrate-excessive-execution-of-the-referenc.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0004-refs-demonstrate-excessive-execution-of-the-referenc.patch new file mode 100644 index 0000000000..aa6d96a3e8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0004-refs-demonstrate-excessive-execution-of-the-referenc.patch @@ -0,0 +1,97 @@ +From 079f96ed16bb70f99fbe810b1646b1709bb82871 Mon Sep 17 00:00:00 2001 +Message-Id: <079f96ed16bb70f99fbe810b1646b1709bb82871.1646206541.git.ps@pks.im> +In-Reply-To: +References: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:44 +0100 +Subject: [PATCH 24/34] refs: demonstrate excessive execution of the + reference-transaction hook + +Add tests which demonstate that we're executing the +reference-transaction hook too often in some cases, which thus leaks +implementation details about the reference store's implementation +itself. Behaviour will be fixed in follow-up commits. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit 2ce825436268d6409bee8ebb5f5500b7ff172b1e) +--- + t/t1416-ref-transaction-hooks.sh | 64 ++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh +index 6c941027a8..0567fbdf0b 100755 +--- a/t/t1416-ref-transaction-hooks.sh ++++ b/t/t1416-ref-transaction-hooks.sh +@@ -136,4 +136,68 @@ test_expect_success 'interleaving hook calls succeed' ' + test_cmp expect target-repo.git/actual + ' + ++test_expect_success 'hook does not get called on packing refs' ' ++ # Pack references first such that we are in a known state. ++ git pack-refs --all && ++ ++ write_script .git/hooks/reference-transaction <<-\EOF && ++ echo "$@" >>actual ++ cat >>actual ++ EOF ++ rm -f actual && ++ ++ git update-ref refs/heads/unpacked-ref $POST_OID && ++ git pack-refs --all && ++ ++ # We only expect a single hook invocation, which is the call to ++ # git-update-ref(1). But currently, packing refs will also trigger the ++ # hook. ++ cat >expect <<-EOF && ++ prepared ++ $ZERO_OID $POST_OID refs/heads/unpacked-ref ++ committed ++ $ZERO_OID $POST_OID refs/heads/unpacked-ref ++ prepared ++ $ZERO_OID $POST_OID refs/heads/unpacked-ref ++ committed ++ $ZERO_OID $POST_OID refs/heads/unpacked-ref ++ prepared ++ $POST_OID $ZERO_OID refs/heads/unpacked-ref ++ committed ++ $POST_OID $ZERO_OID refs/heads/unpacked-ref ++ EOF ++ ++ test_cmp expect actual ++' ++ ++test_expect_success 'deleting packed ref calls hook once' ' ++ # Create a reference and pack it. ++ git update-ref refs/heads/to-be-deleted $POST_OID && ++ git pack-refs --all && ++ ++ write_script .git/hooks/reference-transaction <<-\EOF && ++ echo "$@" >>actual ++ cat >>actual ++ EOF ++ rm -f actual && ++ ++ git update-ref -d refs/heads/to-be-deleted $POST_OID && ++ ++ # We only expect a single hook invocation, which is the logical ++ # deletion. But currently, we see two interleaving transactions, once ++ # for deleting the loose refs and once for deleting the packed ref. ++ cat >expect <<-EOF && ++ prepared ++ $ZERO_OID $ZERO_OID refs/heads/to-be-deleted ++ prepared ++ $POST_OID $ZERO_OID refs/heads/to-be-deleted ++ committed ++ $ZERO_OID $ZERO_OID refs/heads/to-be-deleted ++ committed ++ $POST_OID $ZERO_OID refs/heads/to-be-deleted ++ EOF ++ ++ test_cmp expect actual ++' ++ + test_done +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0005-refs-do-not-execute-reference-transaction-hook-on-pa.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0005-refs-do-not-execute-reference-transaction-hook-on-pa.patch new file mode 100644 index 0000000000..f2e7c06ed3 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0005-refs-do-not-execute-reference-transaction-hook-on-pa.patch @@ -0,0 +1,81 @@ +From ef35ab926309bf406d3871679c576c718708a93b Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:48 +0100 +Subject: [PATCH 25/34] refs: do not execute reference-transaction hook on + packing refs + +The reference-transaction hook is supposed to track logical changes to +references, but it currently also gets executed when packing refs in a +repository. This is unexpected and ultimately not all that useful: +packing refs is not supposed to result in any user-visible change to the +refs' state, and it ultimately is an implementation detail of how refs +stores work. + +Fix this excessive execution of the hook when packing refs. + +Reported-by: Waleed Khan +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit ffad9941383465553bf26d88050f3243726f30df) +--- + refs/files-backend.c | 6 ++++-- + t/t1416-ref-transaction-hooks.sh | 11 +---------- + 2 files changed, 5 insertions(+), 12 deletions(-) + +diff --git a/refs/files-backend.c b/refs/files-backend.c +index 758d12a0fa..19f43e8d29 100644 +--- a/refs/files-backend.c ++++ b/refs/files-backend.c +@@ -1116,7 +1116,8 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) + if (check_refname_format(r->name, 0)) + return; + +- transaction = ref_store_transaction_begin(&refs->base, 0, &err); ++ transaction = ref_store_transaction_begin(&refs->base, ++ REF_TRANSACTION_SKIP_HOOK, &err); + if (!transaction) + goto cleanup; + ref_transaction_add_update( +@@ -1187,7 +1188,8 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) + struct strbuf err = STRBUF_INIT; + struct ref_transaction *transaction; + +- transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, &err); ++ transaction = ref_store_transaction_begin(refs->packed_ref_store, ++ REF_TRANSACTION_SKIP_HOOK, &err); + if (!transaction) + return -1; + +diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh +index 0567fbdf0b..f9d3d5213f 100755 +--- a/t/t1416-ref-transaction-hooks.sh ++++ b/t/t1416-ref-transaction-hooks.sh +@@ -150,21 +150,12 @@ test_expect_success 'hook does not get called on packing refs' ' + git pack-refs --all && + + # We only expect a single hook invocation, which is the call to +- # git-update-ref(1). But currently, packing refs will also trigger the +- # hook. ++ # git-update-ref(1). + cat >expect <<-EOF && + prepared + $ZERO_OID $POST_OID refs/heads/unpacked-ref + committed + $ZERO_OID $POST_OID refs/heads/unpacked-ref +- prepared +- $ZERO_OID $POST_OID refs/heads/unpacked-ref +- committed +- $ZERO_OID $POST_OID refs/heads/unpacked-ref +- prepared +- $POST_OID $ZERO_OID refs/heads/unpacked-ref +- committed +- $POST_OID $ZERO_OID refs/heads/unpacked-ref + EOF + + test_cmp expect actual +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0006-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0006-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch new file mode 100644 index 0000000000..3b21bf4896 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/git-patches/v2.37.1.gl1/0006-refs-skip-hooks-when-deleting-uncovered-packed-refs.patch @@ -0,0 +1,99 @@ +From d56f2a0e1eed4d0a39b99638117e0c8259e5078d Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Patrick Steinhardt +Date: Mon, 17 Jan 2022 09:12:53 +0100 +Subject: [PATCH 26/34] refs: skip hooks when deleting uncovered packed refs + +When deleting refs from the loose-files refs backend, then we need to be +careful to also delete the same ref from the packed refs backend, if it +exists. If we don't, then deleting the loose ref would "uncover" the +packed ref. We thus always have to queue up deletions of refs for both +the loose and the packed refs backend. This is done in two separate +transactions, where the end result is that the reference-transaction +hook is executed twice for the deleted refs. + +This behaviour is quite misleading: it's exposing implementation details +of how the files backend works to the user, in contrast to the logical +updates that we'd really want to expose via the hook. Worse yet, whether +the hook gets executed once or twice depends on how well-packed the +repository is: if the ref only exists as a loose ref, then we execute it +once, otherwise if it is also packed then we execute it twice. + +Fix this behaviour and don't execute the reference-transaction hook at +all when refs in the packed-refs backend if it's driven by the files +backend. This works as expected even in case the refs to be deleted only +exist in the packed-refs backend because the loose-backend always queues +refs in its own transaction even if they don't exist such that they can +be locked for concurrent creation. And it also does the right thing in +case neither of the backends has the ref because that would cause the +transaction to fail completely. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Junio C Hamano +(cherry picked from commit 2ed1b64ebdeefc7f9473ae159fb45ff0c6cf121a) +--- + refs/files-backend.c | 9 ++++++--- + t/t1416-ref-transaction-hooks.sh | 7 +------ + 2 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/refs/files-backend.c b/refs/files-backend.c +index 19f43e8d29..c931dd479c 100644 +--- a/refs/files-backend.c ++++ b/refs/files-backend.c +@@ -1256,7 +1256,8 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, + if (packed_refs_lock(refs->packed_ref_store, 0, &err)) + goto error; + +- transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, &err); ++ transaction = ref_store_transaction_begin(refs->packed_ref_store, ++ REF_TRANSACTION_SKIP_HOOK, &err); + if (!transaction) + goto error; + +@@ -2771,7 +2772,8 @@ static int files_transaction_prepare(struct ref_store *ref_store, + */ + if (!packed_transaction) { + packed_transaction = ref_store_transaction_begin( +- refs->packed_ref_store, 0, err); ++ refs->packed_ref_store, ++ REF_TRANSACTION_SKIP_HOOK, err); + if (!packed_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; +@@ -3042,7 +3044,8 @@ static int files_initial_transaction_commit(struct ref_store *ref_store, + &affected_refnames)) + BUG("initial ref transaction called with existing refs"); + +- packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, err); ++ packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, ++ REF_TRANSACTION_SKIP_HOOK, err); + if (!packed_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; +diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh +index f9d3d5213f..4e1e84a91f 100755 +--- a/t/t1416-ref-transaction-hooks.sh ++++ b/t/t1416-ref-transaction-hooks.sh +@@ -175,16 +175,11 @@ test_expect_success 'deleting packed ref calls hook once' ' + git update-ref -d refs/heads/to-be-deleted $POST_OID && + + # We only expect a single hook invocation, which is the logical +- # deletion. But currently, we see two interleaving transactions, once +- # for deleting the loose refs and once for deleting the packed ref. ++ # deletion. + cat >expect <<-EOF && +- prepared +- $ZERO_OID $ZERO_OID refs/heads/to-be-deleted + prepared + $POST_OID $ZERO_OID refs/heads/to-be-deleted + committed +- $ZERO_OID $ZERO_OID refs/heads/to-be-deleted +- committed + $POST_OID $ZERO_OID refs/heads/to-be-deleted + EOF + +-- +2.35.1 + diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/gitlab-git-test.git-packed-refs b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/gitlab-git-test.git-packed-refs similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/gitlab-git-test.git-packed-refs rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/gitlab-git-test.git-packed-refs diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/gitlab-test.git-packed-refs b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/gitlab-test.git-packed-refs similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/gitlab-test.git-packed-refs rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/gitlab-test.git-packed-refs diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/new-migration b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/new-migration similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/new-migration rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/new-migration diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/praefect-schema.sql b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/praefect-schema.sql similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/praefect-schema.sql rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/praefect-schema.sql index a1aa215b1b..c0874080c1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/praefect-schema.sql +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/praefect-schema.sql @@ -20,7 +20,7 @@ SET row_security = off; -- Name: praefect_database_schema; Type: DATABASE; Schema: -; Owner: - -- -CREATE DATABASE praefect_database_schema WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8'; +CREATE DATABASE praefect_database_schema WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE = 'en_US.utf8'; \connect praefect_database_schema @@ -98,8 +98,6 @@ CREATE FUNCTION public.notify_on_change() RETURNS trigger SET default_tablespace = ''; -SET default_with_oids = false; - -- -- Name: node_status; Type: TABLE; Schema: public; Owner: - -- diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/publish-gem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/publish-gem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/publish-gem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/publish-gem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/run.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/run.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/run.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/run.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/.gitignore b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/.gitignore similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/.gitignore rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/.gitignore diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/configure-demo-cluster b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/configure-demo-cluster similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/configure-demo-cluster rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/configure-demo-cluster diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/configure.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/configure.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/configure.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/configure.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/create-demo-cluster b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/create-demo-cluster similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/create-demo-cluster rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/create-demo-cluster diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/create.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/create.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/create.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/create.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/destroy-demo-cluster b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/destroy-demo-cluster similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/destroy-demo-cluster rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/destroy-demo-cluster diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/print-info b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/print-info similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/print-info rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/print-info diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/common/handlers/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/common/handlers/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/common/handlers/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/common/handlers/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/handlers/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/handlers/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/handlers/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/handlers/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/tasks/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/tasks/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/tasks/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/tasks/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/templates/hosts.ini.j2 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/templates/hosts.ini.j2 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/templates/hosts.ini.j2 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/templates/hosts.ini.j2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/templates/terraform.tfvars.j2 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/templates/terraform.tfvars.j2 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/deploy/templates/terraform.tfvars.j2 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/deploy/templates/terraform.tfvars.j2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitaly/tasks/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitaly/tasks/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitaly/tasks/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitaly/tasks/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitaly/templates/gitaly-gitlab.rb.j2 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitaly/templates/gitaly-gitlab.rb.j2 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitaly/templates/gitaly-gitlab.rb.j2 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitaly/templates/gitaly-gitlab.rb.j2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/handlers/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/handlers/main.yml similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/handlers/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/handlers/main.yml index 08d1c835cd..c6fc7e57a8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/handlers/main.yml +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/handlers/main.yml @@ -13,6 +13,6 @@ - name: verify gitaly-hooks configuration command: - cmd: /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml + cmd: /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml delegate_to: '{{ item }}' with_items: '{{ groups.gitalies }}' diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/tasks/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/tasks/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/tasks/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/tasks/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/templates/gitlab-gitlab.rb.j2 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/templates/gitlab-gitlab.rb.j2 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/gitlab/templates/gitlab-gitlab.rb.j2 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/gitlab/templates/gitlab-gitlab.rb.j2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/handlers/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/handlers/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/handlers/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/handlers/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/tasks/main.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/tasks/main.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/tasks/main.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/tasks/main.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/templates/praefect-gitlab.rb.j2 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/templates/praefect-gitlab.rb.j2 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/roles/praefect/templates/praefect-gitlab.rb.j2 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/roles/praefect/templates/praefect-gitlab.rb.j2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/terraform/main.tf b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/terraform/main.tf similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/terraform/terraform/main.tf rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/terraform/terraform/main.tf diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/test-boot b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/test-boot similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/test-boot rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/test-boot index c92c254acc..095c61eb06 100755 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/test-boot +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/_support/test-boot @@ -16,7 +16,7 @@ def main(params) if params[:"bundled-git"] ['', true] else - [File.join(build_dir, 'deps', 'git', 'install', 'bin', 'git'), false] + [File.join(build_dir, 'deps', 'git-distribution', 'bin-wrappers', 'git'), false] end version = IO.popen("#{File.join(bin_dir, 'gitaly')} -version").read.delete_prefix('Gitaly, version ').strip diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/extract_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/extract_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/extract_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/extract_test.go index 349d817db8..393a5b8917 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/extract_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/extract_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package gitalyauth import ( @@ -6,7 +8,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestCheckTokenV2(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/rpccredentials.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/rpccredentials.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/rpccredentials.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/rpccredentials.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/token.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/token.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/auth/token.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/auth/token.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/client_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/client_test.go new file mode 100644 index 0000000000..b386a04298 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/client_test.go @@ -0,0 +1,13 @@ +//go:build !gitaly_test_sha256 + +package client + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial.go index 352003d09f..2a4cb7f345 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial.go @@ -3,8 +3,8 @@ package client import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" "google.golang.org/grpc" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial_test.go index 41e775a213..758ff1013f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/dial_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/dial_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package client import ( @@ -16,10 +18,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/uber/jaeger-client-go" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - proxytestdata "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - gitalyx509 "gitlab.com/gitlab-org/gitaly/v14/internal/x509" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + gitalyx509 "gitlab.com/gitlab-org/gitaly/v15/internal/x509" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" @@ -29,6 +31,7 @@ import ( "google.golang.org/grpc/credentials/insecure" healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" + "google.golang.org/grpc/test/grpc_testing" ) var proxyEnvironmentKeys = []string{"http_proxy", "https_proxy", "no_proxy"} @@ -128,8 +131,9 @@ func TestDial(t *testing.T) { } if tt.envSSLCertFile != "" { - testhelper.ModifyEnvironment(t, gitalyx509.SSLCertFile, tt.envSSLCertFile) + t.Setenv(gitalyx509.SSLCertFile, tt.envSSLCertFile) } + ctx := testhelper.Context(t) conn, err := Dial(tt.rawAddress, tt.dialOpts) @@ -216,8 +220,9 @@ func TestDialSidechannel(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.envSSLCertFile != "" { - testhelper.ModifyEnvironment(t, gitalyx509.SSLCertFile, tt.envSSLCertFile) + t.Setenv(gitalyx509.SSLCertFile, tt.envSSLCertFile) } + ctx := testhelper.Context(t) conn, err := DialSidechannel(ctx, tt.rawAddress, registry, tt.dialOpts) @@ -253,22 +258,22 @@ func TestDialSidechannel(t *testing.T) { } type testSvc struct { - proxytestdata.UnimplementedTestServiceServer - PingMethod func(context.Context, *proxytestdata.PingRequest) (*proxytestdata.PingResponse, error) - PingStreamMethod func(stream proxytestdata.TestService_PingStreamServer) error + grpc_testing.UnimplementedTestServiceServer + unaryCall func(context.Context, *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) + fullDuplexCall func(stream grpc_testing.TestService_FullDuplexCallServer) error } -func (ts *testSvc) Ping(ctx context.Context, r *proxytestdata.PingRequest) (*proxytestdata.PingResponse, error) { - if ts.PingMethod != nil { - return ts.PingMethod(ctx, r) +func (ts *testSvc) UnaryCall(ctx context.Context, r *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { + if ts.unaryCall != nil { + return ts.unaryCall(ctx, r) } - return &proxytestdata.PingResponse{}, nil + return &grpc_testing.SimpleResponse{}, nil } -func (ts *testSvc) PingStream(stream proxytestdata.TestService_PingStreamServer) error { - if ts.PingStreamMethod != nil { - return ts.PingStreamMethod(stream) +func (ts *testSvc) FullDuplexCall(stream grpc_testing.TestService_FullDuplexCallServer) error { + if ts.fullDuplexCall != nil { + return ts.fullDuplexCall(stream) } return nil @@ -283,27 +288,29 @@ func TestDial_Correlation(t *testing.T) { grpcServer := grpc.NewServer(grpc.UnaryInterceptor(grpccorrelation.UnaryServerCorrelationInterceptor())) svc := &testSvc{ - PingMethod: func(ctx context.Context, r *proxytestdata.PingRequest) (*proxytestdata.PingResponse, error) { + unaryCall: func(ctx context.Context, r *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { cid := correlation.ExtractFromContext(ctx) assert.Equal(t, "correlation-id-1", cid) - return &proxytestdata.PingResponse{}, nil + return &grpc_testing.SimpleResponse{}, nil }, } - proxytestdata.RegisterTestServiceServer(grpcServer, svc) + grpc_testing.RegisterTestServiceServer(grpcServer, svc) go func() { assert.NoError(t, grpcServer.Serve(listener)) }() defer grpcServer.Stop() ctx := testhelper.Context(t) - cc, err := DialContext(ctx, "unix://"+serverSocketPath, nil) + cc, err := DialContext(ctx, "unix://"+serverSocketPath, []grpc.DialOption{ + internalclient.UnaryInterceptor(), internalclient.StreamInterceptor(), + }) require.NoError(t, err) defer cc.Close() - client := proxytestdata.NewTestServiceClient(cc) + client := grpc_testing.NewTestServiceClient(cc) ctx = correlation.ContextWithCorrelation(ctx, "correlation-id-1") - _, err = client.Ping(ctx, &proxytestdata.PingRequest{}) + _, err = client.UnaryCall(ctx, &grpc_testing.SimpleRequest{}) require.NoError(t, err) }) @@ -315,31 +322,33 @@ func TestDial_Correlation(t *testing.T) { grpcServer := grpc.NewServer(grpc.StreamInterceptor(grpccorrelation.StreamServerCorrelationInterceptor())) svc := &testSvc{ - PingStreamMethod: func(stream proxytestdata.TestService_PingStreamServer) error { + fullDuplexCall: func(stream grpc_testing.TestService_FullDuplexCallServer) error { cid := correlation.ExtractFromContext(stream.Context()) assert.Equal(t, "correlation-id-1", cid) _, err := stream.Recv() assert.NoError(t, err) - return stream.Send(&proxytestdata.PingResponse{}) + return stream.Send(&grpc_testing.StreamingOutputCallResponse{}) }, } - proxytestdata.RegisterTestServiceServer(grpcServer, svc) + grpc_testing.RegisterTestServiceServer(grpcServer, svc) go func() { assert.NoError(t, grpcServer.Serve(listener)) }() defer grpcServer.Stop() ctx := testhelper.Context(t) - cc, err := DialContext(ctx, "unix://"+serverSocketPath, nil) + cc, err := DialContext(ctx, "unix://"+serverSocketPath, []grpc.DialOption{ + internalclient.UnaryInterceptor(), internalclient.StreamInterceptor(), + }) require.NoError(t, err) defer cc.Close() - client := proxytestdata.NewTestServiceClient(cc) + client := grpc_testing.NewTestServiceClient(cc) ctx = correlation.ContextWithCorrelation(ctx, "correlation-id-1") - stream, err := client.PingStream(ctx) + stream, err := client.FullDuplexCall(ctx) require.NoError(t, err) - require.NoError(t, stream.Send(&proxytestdata.PingRequest{})) + require.NoError(t, stream.Send(&grpc_testing.StreamingOutputCallRequest{})) require.NoError(t, stream.CloseSend()) _, err = stream.Recv() @@ -363,13 +372,13 @@ func TestDial_Tracing(t *testing.T) { grpc.StreamInterceptor(grpctracing.StreamServerTracingInterceptor()), ) svc := &testSvc{ - PingMethod: func(ctx context.Context, r *proxytestdata.PingRequest) (*proxytestdata.PingResponse, error) { + unaryCall: func(ctx context.Context, r *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { span, _ := opentracing.StartSpanFromContext(ctx, "nested-span") defer span.Finish() span.LogKV("was", "called") - return &proxytestdata.PingResponse{}, nil + return &grpc_testing.SimpleResponse{}, nil }, - PingStreamMethod: func(stream proxytestdata.TestService_PingStreamServer) error { + fullDuplexCall: func(stream grpc_testing.TestService_FullDuplexCallServer) error { // synchronize the client has returned from CloseSend as the client span finishing // races with sending the stream close to the server select { @@ -384,7 +393,7 @@ func TestDial_Tracing(t *testing.T) { return nil }, } - proxytestdata.RegisterTestServiceServer(grpcServer, svc) + grpc_testing.RegisterTestServiceServer(grpcServer, svc) go func() { require.NoError(t, grpcServer.Serve(listener)) }() defer grpcServer.Stop() @@ -400,7 +409,9 @@ func TestDial_Tracing(t *testing.T) { // This needs to be run after setting up the global tracer as it will cause us to // create the span when executing the RPC call further down below. - cc, err := DialContext(ctx, "unix://"+serverSocketPath, nil) + cc, err := DialContext(ctx, "unix://"+serverSocketPath, []grpc.DialOption{ + internalclient.UnaryInterceptor(), internalclient.StreamInterceptor(), + }) require.NoError(t, err) defer cc.Close() @@ -415,7 +426,7 @@ func TestDial_Tracing(t *testing.T) { // We're now invoking the unary RPC with the span injected into // the context. This should create a span that's nested into // the "stream-check" span. - _, err = proxytestdata.NewTestServiceClient(cc).Ping(ctx, &proxytestdata.PingRequest{}) + _, err = grpc_testing.NewTestServiceClient(cc).UnaryCall(ctx, &grpc_testing.SimpleRequest{}) require.NoError(t, err) span.Finish() @@ -434,7 +445,7 @@ func TestDial_Tracing(t *testing.T) { // This span is the RPC call to TestService/Ping. It // inherits the "unary-check" we set up and thus has // baggage. - {baggage: "stub", operation: "/mwitkow.testproto.TestService/Ping"}, + {baggage: "stub", operation: "/grpc.testing.TestService/UnaryCall"}, // And this finally is the outermost span which we // manually set up before the RPC call. {baggage: "stub", operation: "unary-check"}, @@ -457,7 +468,9 @@ func TestDial_Tracing(t *testing.T) { // This needs to be run after setting up the global tracer as it will cause us to // create the span when executing the RPC call further down below. - cc, err := DialContext(ctx, "unix://"+serverSocketPath, nil) + cc, err := DialContext(ctx, "unix://"+serverSocketPath, []grpc.DialOption{ + internalclient.UnaryInterceptor(), internalclient.StreamInterceptor(), + }) require.NoError(t, err) defer cc.Close() @@ -470,7 +483,7 @@ func TestDial_Tracing(t *testing.T) { // We're now invoking the streaming RPC with the span injected into the context. // This should create a span that's nested into the "stream-check" span. - stream, err := proxytestdata.NewTestServiceClient(cc).PingStream(ctx) + stream, err := grpc_testing.NewTestServiceClient(cc).FullDuplexCall(ctx) require.NoError(t, err) require.NoError(t, stream.CloseSend()) close(clientSendClosed) @@ -490,7 +503,7 @@ func TestDial_Tracing(t *testing.T) { operation string }{ // This span is the RPC call to TestService/Ping. - {baggage: "stub", operation: "/mwitkow.testproto.TestService/PingStream"}, + {baggage: "stub", operation: "/grpc.testing.TestService/FullDuplexCall"}, // This is the second span we expect, which is the "nested-span" span which // we've manually created inside of PingMethod. This is different than for // unary RPCs: given that one can send multiple messages to the RPC, we may @@ -522,9 +535,9 @@ func (*healthServer) Check(context.Context, *healthpb.HealthCheckRequest) (*heal } // startTCPListener will start a insecure TCP listener on a random unused port -func startTCPListener(t testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { +func startTCPListener(tb testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { listener, err := net.Listen("tcp", "localhost:0") - require.NoError(t, err) + require.NoError(tb, err) tcpPort := listener.Addr().(*net.TCPAddr).Port address := fmt.Sprintf("%d", tcpPort) @@ -538,11 +551,11 @@ func startTCPListener(t testing.TB, factory func(credentials.TransportCredential } // startUnixListener will start a unix socket listener using a temporary file -func startUnixListener(t testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { - serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(t) +func startUnixListener(tb testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { + serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(tb) listener, err := net.Listen("unix", serverSocketPath) - require.NoError(t, err) + require.NoError(tb, err) grpcServer := factory(insecure.NewCredentials()) go grpcServer.Serve(listener) @@ -554,15 +567,15 @@ func startUnixListener(t testing.TB, factory func(credentials.TransportCredentia // startTLSListener will start a secure TLS listener on a random unused port //go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out testdata/gitalycert.pem -keyout testdata/gitalykey.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost" -addext "subjectAltName = IP:127.0.0.1, DNS:localhost" -func startTLSListener(t testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { +func startTLSListener(tb testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), string) { listener, err := net.Listen("tcp", "localhost:0") - require.NoError(t, err) + require.NoError(tb, err) tcpPort := listener.Addr().(*net.TCPAddr).Port address := fmt.Sprintf("%d", tcpPort) cert, err := tls.LoadX509KeyPair("testdata/gitalycert.pem", "testdata/gitalykey.pem") - require.NoError(t, err) + require.NoError(tb, err) grpcServer := factory( credentials.NewTLS(&tls.Config{ @@ -584,11 +597,11 @@ var listeners = map[string]func(testing.TB, func(credentials.TransportCredential } // startListeners will start all the different listeners used in this test -func startListeners(t testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), map[string]string) { +func startListeners(tb testing.TB, factory func(credentials.TransportCredentials) *grpc.Server) (func(), map[string]string) { var closers []func() connectionMap := map[string]string{} for k, v := range listeners { - closer, address := v(t, factory) + closer, address := v(tb, factory) closers = append(closers, closer) connectionMap[k] = address } @@ -622,9 +635,15 @@ func TestHealthCheckDialer(t *testing.T) { _, err := HealthCheckDialer(DialContext)(ctx, addr, nil) testhelper.RequireGrpcError(t, status.Error(codes.Unauthenticated, "authentication required"), err) - cc, err := HealthCheckDialer(DialContext)(ctx, addr, []grpc.DialOption{grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2("token"))}) + cc, err := HealthCheckDialer(DialContext)(ctx, addr, []grpc.DialOption{ + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2("token")), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor(), + }) require.NoError(t, err) require.NoError(t, cc.Close()) } -func newLogger(t testing.TB) *logrus.Entry { return logrus.NewEntry(testhelper.NewDiscardingLogger(t)) } +func newLogger(tb testing.TB) *logrus.Entry { + return logrus.NewEntry(testhelper.NewDiscardingLogger(tb)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool.go index 1c414870b3..4fcd3835e8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool.go @@ -6,7 +6,7 @@ import ( "fmt" "sync" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_options.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_options.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_options.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_options.go index 35f924c410..decb2a8120 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_options.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_options.go @@ -7,7 +7,7 @@ type poolOptions struct { dialOptions []grpc.DialOption } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type PoolOption func(*poolOptions) func applyPoolOptions(options []PoolOption) *poolOptions { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_test.go index 924146fd71..586c752871 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/pool_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/pool_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package client import ( @@ -9,11 +11,11 @@ import ( grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - gitalycfgauth "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + gitalycfgauth "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/health" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/receive_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/receive_pack.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/receive_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/receive_pack.go index 3f1e988641..7d081d4c01 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/receive_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/receive_pack.go @@ -4,9 +4,9 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/sidechannel.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/sidechannel.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/sidechannel.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/sidechannel.go index fc79502eaa..100d327385 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/sidechannel.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/sidechannel.go @@ -5,9 +5,9 @@ import ( "io" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/testdata/gitalycert.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/testdata/gitalycert.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/testdata/gitalycert.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/testdata/gitalycert.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/testdata/gitalykey.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/testdata/gitalykey.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/testdata/gitalykey.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/testdata/gitalykey.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_archive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_archive.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_archive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_archive.go index 8bd0c34078..559eba93a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_archive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_archive.go @@ -4,9 +4,9 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_pack.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_pack.go index 8d971804b5..863465068b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/upload_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/client/upload_pack.go @@ -4,9 +4,9 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create.go index 6c1ef8dfab..1faa69446d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create.go @@ -10,10 +10,11 @@ import ( "time" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backup" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type serverRepository struct { @@ -52,7 +53,7 @@ func (cmd *createSubcommand) Run(ctx context.Context, stdin io.Reader, stdout io return fmt.Errorf("create: resolve locator: %w", err) } - pool := client.NewPool() + pool := client.NewPool(internalclient.UnaryInterceptor(), internalclient.StreamInterceptor()) defer pool.Close() manager := backup.NewManager(sink, locator, pool, cmd.backupID) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create_test.go index 2d1613dc98..324afdaad7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/create_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/create_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -10,12 +12,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestCreateSubcommand(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/main.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/main.go index 2ce6ccafa5..808c67a3a2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/main.go @@ -6,7 +6,7 @@ import ( "io" "os" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) type subcmd interface { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore.go index 3780aba494..525269464b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore.go @@ -11,10 +11,11 @@ import ( "time" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backup" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type restoreRequest struct { @@ -50,7 +51,7 @@ func (cmd *restoreSubcommand) Run(ctx context.Context, stdin io.Reader, stdout i return fmt.Errorf("restore: resolve locator: %w", err) } - pool := client.NewPool() + pool := client.NewPool(internalclient.UnaryInterceptor(), internalclient.StreamInterceptor()) defer pool.Close() manager := backup.NewManager(sink, locator, pool, time.Now().UTC().Format("20060102150405")) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore_test.go index 9414c28bae..5e3b0ae0d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/restore_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/restore_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -10,12 +12,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestRestoreSubcommand(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/testhelper_test.go index 64d8edae54..6b4c7f0f6a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-backup/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-backup/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package main import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/config.toml.example b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/config.toml.example similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/config.toml.example rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/config.toml.example diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/main.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/main.go index c0d2481ec0..83a4672063 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-blackbox/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-blackbox/main.go @@ -7,9 +7,9 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/blackbox" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/internal/blackbox" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" ) var flagVersion = flag.Bool("version", false, "Print version and exit") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/analyzehttp.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/analyzehttp.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/analyzehttp.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/analyzehttp.go index 805094ac72..4dc3a8cba4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/analyzehttp.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/analyzehttp.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" ) func analyzeHTTPClone(cloneURL string) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/bitmap.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/bitmap.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/bitmap.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/bitmap.go index 36e2b514b9..c5ec2234e5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/bitmap.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/bitmap.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile" ) func listBitmapPack(idxFile string) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/main.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/main.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/simulatehttp.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/simulatehttp.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/simulatehttp.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/simulatehttp.go index f2cf35dab0..45bd965313 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-debug/simulatehttp.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-debug/simulatehttp.go @@ -9,7 +9,7 @@ import ( "regexp" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) func simulateHTTPClone(gitDir string) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/apply.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/apply.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/apply.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/apply.go index fd3d9eb71d..e5cc1339a8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/apply.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/apply.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -16,8 +15,8 @@ import ( "path/filepath" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type patchIterator struct { @@ -43,12 +42,14 @@ func (iter *patchIterator) Value() git2go.Patch { return iter.value } func (iter *patchIterator) Err() error { return iter.error } type applySubcommand struct { - gitBinaryPath string + gitBinaryPath string + signingKeyPath string } func (cmd *applySubcommand) Flags() *flag.FlagSet { fs := flag.NewFlagSet("apply", flag.ExitOnError) fs.StringVar(&cmd.gitBinaryPath, "git-binary-path", "", "Path to the Git binary.") + fs.StringVar(&cmd.signingKeyPath, "signing-key", "", "Path to the OpenPGP signing key.") return fs } @@ -127,30 +128,35 @@ func (cmd *applySubcommand) applyPatch( } } - patchedTree, err := patchedIndex.WriteTreeTo(repo) + patchedTreeOID, err := patchedIndex.WriteTreeTo(repo) if err != nil { return nil, fmt.Errorf("write patched tree: %w", err) } + patchedTree, err := repo.LookupTree(patchedTreeOID) + if err != nil { + return nil, fmt.Errorf("lookup tree: %w", err) + } author := git.Signature(patch.Author) - patchedCommitOID, err := repo.CreateCommitFromIds("", &author, committer, patch.Message, patchedTree, parentCommitOID) + patchedCommitID, err := git2goutil.NewCommitSubmitter(repo, cmd.signingKeyPath). + Commit(&author, committer, git.MessageEncodingUTF8, patch.Message, patchedTree, parentCommit) if err != nil { return nil, fmt.Errorf("create commit: %w", err) } - return patchedCommitOID, nil + return patchedCommitID, nil } // threeWayMerge attempts a three-way merge as a fallback if applying the patch fails. // Fallback three-way merge is only possible if the patch records the pre-image blobs // and the repository contains them. It works as follows: // -// 1. An index that contains only the pre-image blobs of the patch is built. This is done -// by calling `git apply --build-fake-ancestor`. The tree of the index is the fake -// ancestor tree. -// 2. The fake ancestor tree is patched to produce the post-image tree of the patch. -// 3. Three-way merge is performed with fake ancestor tree as the common ancestor, the -// base commit's tree as our tree and the patched fake ancestor tree as their tree. +// 1. An index that contains only the pre-image blobs of the patch is built. This is done +// by calling `git apply --build-fake-ancestor`. The tree of the index is the fake +// ancestor tree. +// 2. The fake ancestor tree is patched to produce the post-image tree of the patch. +// 3. Three-way merge is performed with fake ancestor tree as the common ancestor, the +// base commit's tree as our tree and the patched fake ancestor tree as their tree. func (cmd *applySubcommand) threeWayMerge( ctx context.Context, repo *git.Repository, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick.go index 605abcc394..1a185a7e25 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -11,8 +10,8 @@ import ( "fmt" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type cherryPickSubcommand struct{} @@ -93,24 +92,36 @@ func (cmd *cherryPickSubcommand) cherryPick(ctx context.Context, r *git2go.Cherr } if index.HasConflicts() { - return "", git2go.HasConflictsError{} + conflictingFiles, err := getConflictingFiles(index) + if err != nil { + return "", fmt.Errorf("getting conflicting files: %w", err) + } + + return "", git2go.ConflictingFilesError{ + ConflictingFiles: conflictingFiles, + } } - tree, err := index.WriteTreeTo(repo) + treeOID, err := index.WriteTreeTo(repo) if err != nil { return "", fmt.Errorf("could not write tree: %w", err) } + tree, err := repo.LookupTree(treeOID) + if err != nil { + return "", fmt.Errorf("lookup tree: %w", err) + } - if tree.Equal(ours.TreeId()) { + if treeOID.Equal(ours.TreeId()) { return "", git2go.EmptyError{} } committer := git.Signature(git2go.NewSignature(r.CommitterName, r.CommitterMail, r.CommitterDate)) - commit, err := repo.CreateCommitFromIds("", pick.Author(), &committer, r.Message, tree, ours.Id()) + commitID, err := git2goutil.NewCommitSubmitter(repo, r.SigningKey). + Commit(pick.Author(), &committer, git.MessageEncodingUTF8, r.Message, tree, ours) if err != nil { - return "", fmt.Errorf("could not create cherry-pick commit: %w", err) + return "", fmt.Errorf("create not create cherry-pick commit: %w", err) } - return commit.String(), nil + return commitID.String(), nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick_test.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick_test.go index a578893ca4..4522f3d94f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/cherry_pick_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/cherry_pick_test.go @@ -1,21 +1,19 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main import ( - "errors" "testing" "time" git "github.com/libgit2/git2go/v33" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - cmdtesthelper "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestCherryPick_validation(t *testing.T) { @@ -81,9 +79,9 @@ func TestCherryPick_validation(t *testing.T) { func TestCherryPick(t *testing.T) { testcases := []struct { desc string - base map[string]string - ours map[string]string - commit map[string]string + base []gittest.TreeEntry + ours []gittest.TreeEntry + commit []gittest.TreeEntry expected map[string]string expectedCommitID string expectedErr error @@ -91,44 +89,44 @@ func TestCherryPick(t *testing.T) { }{ { desc: "trivial cherry-pick succeeds", - base: map[string]string{ - "file": "foo", + base: []gittest.TreeEntry{ + {Path: "file", Content: "foo", Mode: "100644"}, }, - ours: map[string]string{ - "file": "foo", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "foo", Mode: "100644"}, }, - commit: map[string]string{ - "file": "foobar", + commit: []gittest.TreeEntry{ + {Path: "file", Content: "foobar", Mode: "100644"}, }, expected: map[string]string{ "file": "foobar", }, - expectedCommitID: "aa3c9f5ad67ad86e313129a851f6d64614be7f6e", + expectedCommitID: "a54ea83118c363c34cc605a6e61fd7abc4795cc4", }, { desc: "conflicting cherry-pick fails", - base: map[string]string{ - "file": "foo", + base: []gittest.TreeEntry{ + {Path: "file", Content: "foo", Mode: "100644"}, }, - ours: map[string]string{ - "file": "fooqux", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "fooqux", Mode: "100644"}, }, - commit: map[string]string{ - "file": "foobar", + commit: []gittest.TreeEntry{ + {Path: "file", Content: "foobar", Mode: "100644"}, }, - expectedErr: git2go.HasConflictsError{}, - expectedErrMsg: "cherry-pick: could not apply due to conflicts", + expectedErr: git2go.ConflictingFilesError{}, + expectedErrMsg: "cherry-pick: there are conflicting files", }, { desc: "empty cherry-pick fails", - base: map[string]string{ - "file": "foo", + base: []gittest.TreeEntry{ + {Path: "file", Content: "foo", Mode: "100644"}, }, - ours: map[string]string{ - "file": "fooqux", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "fooqux", Mode: "100644"}, }, - commit: map[string]string{ - "file": "fooqux", + commit: []gittest.TreeEntry{ + {Path: "file", Content: "fooqux", Mode: "100644"}, }, expectedErr: git2go.EmptyError{}, expectedErrMsg: "cherry-pick: could not apply because the result was empty", @@ -139,8 +137,8 @@ func TestCherryPick(t *testing.T) { }, { desc: "fails on nonexistent cherry-pick commit", - ours: map[string]string{ - "file": "fooqux", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "fooqux", Mode: "100644"}, }, expectedErrMsg: "cherry-pick: commit lookup: lookup commit \"nonexistent\": revspec 'nonexistent' not found", }, @@ -150,14 +148,14 @@ func TestCherryPick(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) executor := buildExecutor(t, cfg) - base := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{nil}, tc.base) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(tc.base...)) ours, commit := "nonexistent", "nonexistent" if len(tc.ours) > 0 { - ours = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.ours).String() + ours = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.ours...)).String() } if len(tc.commit) > 0 { - commit = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.commit).String() + commit = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.commit...)).String() } t.Run(tc.desc, func(t *testing.T) { @@ -183,7 +181,7 @@ func TestCherryPick(t *testing.T) { require.EqualError(t, err, tc.expectedErrMsg) if tc.expectedErr != nil { - require.True(t, errors.Is(err, tc.expectedErr)) + require.ErrorAs(t, err, &tc.expectedErr) } return } @@ -200,7 +198,7 @@ func TestCherryPick(t *testing.T) { commit, err := repo.LookupCommit(commitOid) require.NoError(t, err) - require.Equal(t, &cmdtesthelper.DefaultAuthor, commit.Author()) + require.Equal(t, &DefaultAuthor, commit.Author()) require.Equal(t, &committer, commit.Committer()) tree, err := commit.Tree() @@ -218,3 +216,57 @@ func TestCherryPick(t *testing.T) { }) } } + +func TestCherryPickStructuredErrors(t *testing.T) { + ctx := testhelper.Context(t) + + cfg, repo, repoPath := testcfg.BuildWithRepo(t) + + testcfg.BuildGitalyGit2Go(t, cfg) + executor := buildExecutor(t, cfg) + + base := gittest.WriteCommit( + t, + cfg, + repoPath, + gittest.WithTreeEntries(gittest.TreeEntry{ + Path: "file", Content: "foo", Mode: "100644", + })) + + ours := gittest.WriteCommit( + t, + cfg, + repoPath, + gittest.WithParents(base), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Content: "fooqux", Mode: "100644"}, + )).String() + + commit := gittest.WriteCommit( + t, + cfg, + repoPath, + gittest.WithParents(base), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Content: "foobar", Mode: "100644"}, + )).String() + + committer := git.Signature{ + Name: "Baz", + Email: "baz@example.com", + When: time.Date(2021, 1, 17, 14, 45, 51, 0, time.FixedZone("", +2*60*60)), + } + + _, err := executor.CherryPick(ctx, repo, git2go.CherryPickCommand{ + Repository: repoPath, + CommitterName: committer.Name, + CommitterMail: committer.Email, + CommitterDate: committer.When, + Message: "Foo", + Ours: ours, + Commit: commit, + }) + + require.EqualError(t, err, "cherry-pick: there are conflicting files") + require.ErrorAs(t, err, &git2go.ConflictingFilesError{}) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit.go new file mode 100644 index 0000000000..0dbf90d249 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit.go @@ -0,0 +1,21 @@ +//go:build static && system_libgit2 + +package main + +import ( + "context" + "encoding/gob" + "flag" + + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit" +) + +type commitSubcommand struct{} + +func (cmd *commitSubcommand) Flags() *flag.FlagSet { + return flag.NewFlagSet("commit", flag.ExitOnError) +} + +func (cmd *commitSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { + return commit.Run(ctx, decoder, encoder) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/change_file_mode.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/change_file_mode.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/change_file_mode.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/change_file_mode.go index 74d27c1429..e07db9ba48 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/change_file_mode.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/change_file_mode.go @@ -1,11 +1,10 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit import ( git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyChangeFileMode(action git2go.ChangeFileMode, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/commit.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/commit.go index 2992dc7f3f..e26acd5598 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/commit.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit @@ -10,13 +9,13 @@ import ( "fmt" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) // Run runs the commit subcommand. func Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { - var params git2go.CommitParams + var params git2go.CommitCommand if err := decoder.Decode(¶ms); err != nil { return err } @@ -28,8 +27,8 @@ func Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error }) } -func commit(ctx context.Context, params git2go.CommitParams) (string, error) { - repo, err := git2goutil.OpenRepository(params.Repository) +func commit(ctx context.Context, request git2go.CommitCommand) (string, error) { + repo, err := git2goutil.OpenRepository(request.Repository) if err != nil { return "", fmt.Errorf("open repository: %w", err) } @@ -39,20 +38,20 @@ func commit(ctx context.Context, params git2go.CommitParams) (string, error) { return "", fmt.Errorf("new index: %w", err) } - var parents []*git.Oid - if params.Parent != "" { - parentOID, err := git.NewOid(params.Parent) + var parents []*git.Commit + if request.Parent != "" { + parentOID, err := git.NewOid(request.Parent) if err != nil { return "", fmt.Errorf("parse base commit oid: %w", err) } - parents = []*git.Oid{parentOID} - baseCommit, err := repo.LookupCommit(parentOID) if err != nil { return "", fmt.Errorf("lookup commit: %w", err) } + parents = []*git.Commit{baseCommit} + baseTree, err := baseCommit.Tree() if err != nil { return "", fmt.Errorf("lookup tree: %w", err) @@ -63,7 +62,7 @@ func commit(ctx context.Context, params git2go.CommitParams) (string, error) { } } - for _, action := range params.Actions { + for _, action := range request.Actions { if err := apply(action, repo, index); err != nil { if git.IsErrorClass(err, git.ErrorClassIndex) { err = git2go.IndexError(err.Error()) @@ -77,10 +76,15 @@ func commit(ctx context.Context, params git2go.CommitParams) (string, error) { if err != nil { return "", fmt.Errorf("write tree: %w", err) } + tree, err := repo.LookupTree(treeOID) + if err != nil { + return "", fmt.Errorf("lookup tree: %w", err) + } - author := git.Signature(params.Author) - committer := git.Signature(params.Committer) - commitID, err := repo.CreateCommitFromIds("", &author, &committer, params.Message, treeOID, parents...) + author := git.Signature(request.Author) + committer := git.Signature(request.Committer) + commitID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey). + Commit(&author, &committer, git.MessageEncodingUTF8, request.Message, tree, parents...) if err != nil { if git.IsErrorClass(err, git.ErrorClassInvalid) { return "", git2go.InvalidArgumentError(err.Error()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_directory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_directory.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_directory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_directory.go index cb9da2a223..061666ed36 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_directory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_directory.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit @@ -8,7 +7,7 @@ import ( "path/filepath" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyCreateDirectory(action git2go.CreateDirectory, repo *git.Repository, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_file.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_file.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_file.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_file.go index 4aafc6f18d..9269165613 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/create_file.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/create_file.go @@ -1,11 +1,10 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit import ( git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyCreateFile(action git2go.CreateFile, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/delete_file.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/delete_file.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/delete_file.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/delete_file.go index a8a3ad8707..a5af77b7b2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/delete_file.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/delete_file.go @@ -1,11 +1,10 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit import ( git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyDeleteFile(action git2go.DeleteFile, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/move_file.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/move_file.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/move_file.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/move_file.go index 2bdf114d8d..b31853c962 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/move_file.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/move_file.go @@ -1,11 +1,10 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit import ( git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyMoveFile(action git2go.MoveFile, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/update_file.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/update_file.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/update_file.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/update_file.go index 1972872bdf..cea5d629b9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/update_file.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/update_file.go @@ -1,11 +1,10 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit import ( git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func applyUpdateFile(action git2go.UpdateFile, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/validate.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/validate.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/validate.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/validate.go index 52b2faaff9..ab3f972b11 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/commit/validate.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/commit/validate.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package commit @@ -7,7 +6,7 @@ import ( "os" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) func validateFileExists(index *git.Index, path string) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts.go index 1923fec42f..954483cad9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -11,9 +10,9 @@ import ( "fmt" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -33,7 +32,7 @@ func (cmd *conflictsSubcommand) Run(_ context.Context, decoder *gob.Decoder, enc return encoder.Encode(res) } -func (conflictsSubcommand) conflicts(request git2go.ConflictsCommand) git2go.ConflictsResult { +func (*conflictsSubcommand) conflicts(request git2go.ConflictsCommand) git2go.ConflictsResult { repo, err := git2goutil.OpenRepository(request.Repository) if err != nil { return conflictError(codes.Internal, fmt.Errorf("could not open repository: %w", err).Error()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts_test.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts_test.go index b7e3adeb23..c8e9848eb7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/conflicts_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/conflicts_test.go @@ -1,5 +1,4 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main @@ -7,13 +6,12 @@ import ( "fmt" "testing" - git "github.com/libgit2/git2go/v33" "github.com/stretchr/testify/require" - cmdtesthelper "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper" - glgit "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + glgit "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -21,34 +19,34 @@ import ( func TestConflicts(t *testing.T) { testcases := []struct { desc string - base map[string]string - ours map[string]string - theirs map[string]string + base []gittest.TreeEntry + ours []gittest.TreeEntry + theirs []gittest.TreeEntry conflicts []git2go.Conflict }{ { desc: "no conflicts", - base: map[string]string{ - "file": "a", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file": "a", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "b", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "b", Mode: "100644"}, }, conflicts: nil, }, { desc: "single file", - base: map[string]string{ - "file": "a", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file": "b", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "b", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "c", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "c", Mode: "100644"}, }, conflicts: []git2go.Conflict{ { @@ -61,17 +59,17 @@ func TestConflicts(t *testing.T) { }, { desc: "multiple files with single conflict", - base: map[string]string{ - "file-1": "a", - "file-2": "a", + base: []gittest.TreeEntry{ + {Path: "file-1", Content: "a", Mode: "100644"}, + {Path: "file-2", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file-1": "b", - "file-2": "b", + ours: []gittest.TreeEntry{ + {Path: "file-1", Content: "b", Mode: "100644"}, + {Path: "file-2", Content: "b", Mode: "100644"}, }, - theirs: map[string]string{ - "file-1": "a", - "file-2": "c", + theirs: []gittest.TreeEntry{ + {Path: "file-1", Content: "a", Mode: "100644"}, + {Path: "file-2", Content: "c", Mode: "100644"}, }, conflicts: []git2go.Conflict{ { @@ -84,17 +82,17 @@ func TestConflicts(t *testing.T) { }, { desc: "multiple conflicts", - base: map[string]string{ - "file-1": "a", - "file-2": "a", + base: []gittest.TreeEntry{ + {Path: "file-1", Content: "a", Mode: "100644"}, + {Path: "file-2", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file-1": "b", - "file-2": "b", + ours: []gittest.TreeEntry{ + {Path: "file-1", Content: "b", Mode: "100644"}, + {Path: "file-2", Content: "b", Mode: "100644"}, }, - theirs: map[string]string{ - "file-1": "c", - "file-2": "c", + theirs: []gittest.TreeEntry{ + {Path: "file-1", Content: "c", Mode: "100644"}, + {Path: "file-2", Content: "c", Mode: "100644"}, }, conflicts: []git2go.Conflict{ { @@ -113,14 +111,14 @@ func TestConflicts(t *testing.T) { }, { desc: "modified-delete-conflict", - base: map[string]string{ - "file": "content", + base: []gittest.TreeEntry{ + {Path: "file", Content: "content", Mode: "100644"}, }, - ours: map[string]string{ - "file": "changed", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "changed", Mode: "100644"}, }, - theirs: map[string]string{ - "different-file": "unrelated", + theirs: []gittest.TreeEntry{ + {Path: "different-file", Content: "unrelated", Mode: "100644"}, }, conflicts: []git2go.Conflict{ { @@ -136,14 +134,14 @@ func TestConflicts(t *testing.T) { // detection and so don't we. The rename conflict is // thus split up into three conflicts. desc: "rename-rename-conflict", - base: map[string]string{ - "file": "a\nb\nc\nd\ne\nf\ng\n", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"}, }, - ours: map[string]string{ - "renamed-1": "a\nb\nc\nd\ne\nf\ng\n", + ours: []gittest.TreeEntry{ + {Path: "renamed-1", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"}, }, - theirs: map[string]string{ - "renamed-2": "a\nb\nc\nd\ne\nf\ng\n", + theirs: []gittest.TreeEntry{ + {Path: "renamed-2", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"}, }, conflicts: []git2go.Conflict{ { @@ -174,9 +172,9 @@ func TestConflicts(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) - base := cmdtesthelper.BuildCommit(t, repoPath, nil, tc.base) - ours := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.ours) - theirs := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.theirs) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(tc.base...)) + ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.ours...)) + theirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.theirs...)) t.Run(tc.desc, func(t *testing.T) { ctx := testhelper.Context(t) @@ -195,7 +193,7 @@ func TestConflicts(t *testing.T) { func TestConflicts_checkError(t *testing.T) { cfg, repo, repoPath := testcfg.BuildWithRepo(t) - base := cmdtesthelper.BuildCommit(t, repoPath, nil, nil) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries()) validOID := glgit.ObjectID(base.String()) executor := buildExecutor(t, cfg) @@ -241,20 +239,20 @@ func TestConflicts_checkError(t *testing.T) { }, { desc: "ours OID doesn't exist", - ours: glgit.ZeroOID, + ours: glgit.ObjectHashSHA1.ZeroOID, theirs: validOID, expErr: status.Error(codes.InvalidArgument, "odb: cannot read object: null OID cannot exist"), }, { desc: "invalid object type", - ours: glgit.EmptyTreeOID, + ours: glgit.ObjectHashSHA1.EmptyTreeOID, theirs: validOID, expErr: status.Error(codes.InvalidArgument, "the requested type does not match the type in the ODB"), }, { desc: "theirs OID doesn't exist", ours: validOID, - theirs: glgit.ZeroOID, + theirs: glgit.ObjectHashSHA1.ZeroOID, expErr: status.Error(codes.InvalidArgument, "odb: cannot read object: null OID cannot exist"), }, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/featureflags.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/featureflags.go new file mode 100644 index 0000000000..720320901c --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/featureflags.go @@ -0,0 +1,41 @@ +//go:build static && system_libgit2 && gitaly_test + +package main + +import ( + "context" + "encoding/gob" + "flag" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" +) + +// This subcommand is only called in tests, so we don't want to register it like +// the other subcommands but instead will do it in an init block. The gitaly_test build +// flag will guarantee that this is not built and registered in the +// gitaly-git2go binary +func init() { + subcommands["feature-flags"] = &featureFlagsSubcommand{} +} + +type featureFlagsSubcommand struct{} + +func (featureFlagsSubcommand) Flags() *flag.FlagSet { + return flag.NewFlagSet("feature-flags", flag.ExitOnError) +} + +func (featureFlagsSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { + var flags []git2go.FeatureFlag + for flag, value := range featureflag.FromContext(ctx) { + flags = append(flags, git2go.FeatureFlag{ + Name: flag.Name, + MetadataKey: flag.MetadataKey(), + Value: value, + }) + } + + return encoder.Encode(git2go.FeatureFlags{ + Flags: flags, + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/commit.go new file mode 100644 index 0000000000..7f45640add --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/commit.go @@ -0,0 +1,47 @@ +package git2goutil + +import ( + "fmt" + + git "github.com/libgit2/git2go/v33" +) + +// CommitSubmitter is the helper struct to make signed Commits conveniently. +type CommitSubmitter struct { + Repo *git.Repository + SigningKeyPath string +} + +// NewCommitSubmitter creates a new CommitSubmitter. +func NewCommitSubmitter(repo *git.Repository, signingKeyPath string) *CommitSubmitter { + return &CommitSubmitter{ + Repo: repo, + SigningKeyPath: signingKeyPath, + } +} + +// Commit commits a commit with or without OpenPGP signature depends on SigningKeyPath value. +func (cs *CommitSubmitter) Commit( + author, committer *git.Signature, + messageEncoding git.MessageEncoding, + message string, + tree *git.Tree, + parents ...*git.Commit, +) (*git.Oid, error) { + commitBytes, err := cs.Repo.CreateCommitBuffer(author, committer, messageEncoding, message, tree, parents...) + if err != nil { + return nil, err + } + + signature, err := CreateCommitSignature(cs.SigningKeyPath, string(commitBytes)) + if err != nil { + return nil, fmt.Errorf("create commit signature: %w", err) + } + + commitID, err := cs.Repo.CreateCommitWithSignature(string(commitBytes), signature, "") + if err != nil { + return nil, err + } + + return commitID, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/repo.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil/repo.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/repo.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/sign.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/sign.go new file mode 100644 index 0000000000..b8437d9ad4 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/sign.go @@ -0,0 +1,43 @@ +//go:build !gitaly_test_signing + +package git2goutil + +import ( + "bytes" + "fmt" + "os" + "strings" + + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/packet" +) + +// CreateCommitSignature reads the given signing key and produces PKCS#7 detached signature. +// When the path to the signing key is not present, an empty signature is returned. +func CreateCommitSignature(signingKeyPath, contentToSign string) (string, error) { + if signingKeyPath == "" { + return "", nil + } + + file, err := os.Open(signingKeyPath) + if err != nil { + return "", fmt.Errorf("open file: %w", err) + } + + entity, err := openpgp.ReadEntity(packet.NewReader(file)) + if err != nil { + return "", fmt.Errorf("read entity: %w", err) + } + + sigBuf := new(bytes.Buffer) + if err := openpgp.ArmoredDetachSignText( + sigBuf, + entity, + strings.NewReader(contentToSign), + &packet.Config{}, + ); err != nil { + return "", fmt.Errorf("sign commit: %w", err) + } + + return sigBuf.String(), nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/test_sign.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/test_sign.go new file mode 100644 index 0000000000..9903449102 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil/test_sign.go @@ -0,0 +1,49 @@ +//go:build gitaly_test_signing + +package git2goutil + +import ( + "bytes" + "fmt" + "os" + "strings" + "time" + + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/packet" +) + +// CreateCommitSignature reads the given signing key and produces PKCS#7 detached signature. +// When the path to the signing key is not present, an empty signature is returned. +// Test version creates deterministic signature which is the same with the same data every run. +func CreateCommitSignature(signingKeyPath, contentToSign string) (string, error) { + if signingKeyPath == "" { + return "", nil + } + + file, err := os.Open(signingKeyPath) + if err != nil { + return "", fmt.Errorf("open file: %w", err) + } + + entity, err := openpgp.ReadEntity(packet.NewReader(file)) + if err != nil { + return "", fmt.Errorf("read entity: %w", err) + } + + sigBuf := new(bytes.Buffer) + if err := openpgp.ArmoredDetachSignText( + sigBuf, + entity, + strings.NewReader(contentToSign), + &packet.Config{ + Time: func() time.Time { + return time.Date(2022, 8, 20, 11, 22, 33, 0, time.UTC) + }, + }, + ); err != nil { + return "", fmt.Errorf("sign commit: %w", err) + } + + return sigBuf.String(), nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/main.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/main.go index 3f403c9d4a..8ee0e7fd02 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/main.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -9,12 +8,14 @@ import ( "flag" "fmt" "os" + "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" git "github.com/libgit2/git2go/v33" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - glog "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + glog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/labkit/correlation" ) @@ -26,7 +27,7 @@ type subcmd interface { var subcommands = map[string]subcmd{ "apply": &applySubcommand{}, "cherry-pick": &cherryPickSubcommand{}, - "commit": commitSubcommand{}, + "commit": &commitSubcommand{}, "conflicts": &conflictsSubcommand{}, "merge": &mergeSubcommand{}, "rebase": &rebaseSubcommand{}, @@ -61,11 +62,22 @@ func main() { encoder := gob.NewEncoder(os.Stdout) var logFormat, logLevel, correlationID string + var enabledFeatureFlags, disabledFeatureFlags featureFlagArg flags := flag.NewFlagSet(git2go.BinaryName, flag.PanicOnError) flags.StringVar(&logFormat, "log-format", "", "logging format") flags.StringVar(&logLevel, "log-level", "", "logging level") flags.StringVar(&correlationID, "correlation-id", "", "correlation ID used for request tracing") + flags.Var( + &enabledFeatureFlags, + "enabled-feature-flags", + "comma separated list of explicitly enabled feature flags", + ) + flags.Var( + &disabledFeatureFlags, + "disabled-feature-flags", + "comma separated list of explicitly disabled feature flags", + ) _ = flags.Parse(os.Args[1:]) if correlationID == "" { @@ -76,8 +88,10 @@ func main() { ctx := correlation.ContextWithCorrelation(context.Background(), correlationID) logger := glog.Default().WithFields(logrus.Fields{ - "command.name": git2go.BinaryName, - "correlation_id": correlationID, + "command.name": git2go.BinaryName, + "correlation_id": correlationID, + "enabled_feature_flags": enabledFeatureFlags, + "disabled_feature_flags": disabledFeatureFlags, }) if flags.NArg() < 1 { @@ -102,10 +116,23 @@ func main() { fatalf(logger, encoder, "enable fsync: %s", err) } + for _, configLevel := range []git.ConfigLevel{ + git.ConfigLevelSystem, + git.ConfigLevelXDG, + git.ConfigLevelGlobal, + } { + if err := git.SetSearchPath(configLevel, "/dev/null"); err != nil { + fatalf(logger, encoder, "setting search path: %s", err) + } + } + subcmdLogger := logger.WithField("command.subcommand", subcmdFlags.Name()) subcmdLogger.Infof("starting %s command", subcmdFlags.Name()) ctx = ctxlogrus.ToContext(ctx, subcmdLogger) + ctx = enabledFeatureFlags.ToContext(ctx, true) + ctx = disabledFeatureFlags.ToContext(ctx, false) + if err := subcmd.Run(ctx, decoder, encoder); err != nil { subcmdLogger.WithError(err).Errorf("%s command failed", subcmdFlags.Name()) fatalf(logger, encoder, "%s: %s", subcmdFlags.Name(), err) @@ -113,3 +140,38 @@ func main() { subcmdLogger.Infof("%s command finished", subcmdFlags.Name()) } + +type featureFlagArg []featureflag.FeatureFlag + +func (v *featureFlagArg) String() string { + metadataKeys := make([]string, 0, len(*v)) + for _, flag := range *v { + metadataKeys = append(metadataKeys, flag.MetadataKey()) + } + return strings.Join(metadataKeys, ",") +} + +func (v *featureFlagArg) Set(s string) error { + if s == "" { + return nil + } + + for _, metadataKey := range strings.Split(s, ",") { + flag, err := featureflag.FromMetadataKey(metadataKey) + if err != nil { + return err + } + + *v = append(*v, flag) + } + + return nil +} + +func (v featureFlagArg) ToContext(ctx context.Context, enabled bool) context.Context { + for _, flag := range v { + ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, flag, enabled) + } + + return ctx +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge.go index 14589c96c9..21922b24aa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -12,15 +11,14 @@ import ( "time" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type mergeSubcommand struct{} func (cmd *mergeSubcommand) Flags() *flag.FlagSet { - flags := flag.NewFlagSet("merge", flag.ExitOnError) - return flags + return flag.NewFlagSet("merge", flag.ExitOnError) } func (cmd *mergeSubcommand) Run(_ context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { @@ -33,7 +31,7 @@ func (cmd *mergeSubcommand) Run(_ context.Context, decoder *gob.Decoder, encoder request.AuthorDate = time.Now() } - commitID, err := merge(request) + commitID, err := cmd.merge(request) return encoder.Encode(git2go.Result{ CommitID: commitID, @@ -41,7 +39,7 @@ func (cmd *mergeSubcommand) Run(_ context.Context, decoder *gob.Decoder, encoder }) } -func merge(request git2go.MergeCommand) (string, error) { +func (cmd *mergeSubcommand) merge(request git2go.MergeCommand) (string, error) { repo, err := git2goutil.OpenRepository(request.Repository) if err != nil { return "", fmt.Errorf("could not open repository: %w", err) @@ -87,10 +85,14 @@ func merge(request git2go.MergeCommand) (string, error) { } } - tree, err := index.WriteTreeTo(repo) + treeOID, err := index.WriteTreeTo(repo) if err != nil { return "", fmt.Errorf("could not write tree: %w", err) } + tree, err := repo.LookupTree(treeOID) + if err != nil { + return "", fmt.Errorf("lookup tree: %w", err) + } author := git.Signature(git2go.NewSignature(request.AuthorName, request.AuthorMail, request.AuthorDate)) committer := author @@ -98,18 +100,20 @@ func merge(request git2go.MergeCommand) (string, error) { committer = git.Signature(git2go.NewSignature(request.CommitterName, request.CommitterMail, request.CommitterDate)) } - var parents []*git.Oid + var parents []*git.Commit if request.Squash { - parents = []*git.Oid{ours.Id()} + parents = []*git.Commit{ours} } else { - parents = []*git.Oid{ours.Id(), theirs.Id()} + parents = []*git.Commit{ours, theirs} } - commit, err := repo.CreateCommitFromIds("", &author, &committer, request.Message, tree, parents...) + + commitID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey). + Commit(&author, &committer, git.MessageEncodingUTF8, request.Message, tree, parents...) if err != nil { return "", fmt.Errorf("could not create merge commit: %w", err) } - return commit.String(), nil + return commitID.String(), nil } func resolveConflicts(repo *git.Repository, index *git.Index) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge_test.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge_test.go index 708a010b87..1ae181c2fa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/merge_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/merge_test.go @@ -1,5 +1,4 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main @@ -8,15 +7,15 @@ import ( "testing" "time" - git "github.com/libgit2/git2go/v33" + libgit2 "github.com/libgit2/git2go/v33" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - cmdtesthelper "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestMerge_missingArguments(t *testing.T) { @@ -113,9 +112,9 @@ func TestMerge_trees(t *testing.T) { testcases := []struct { desc string - base map[string]string - ours map[string]string - theirs map[string]string + base []gittest.TreeEntry + ours []gittest.TreeEntry + theirs []gittest.TreeEntry expected map[string]string withCommitter bool squash bool @@ -124,113 +123,113 @@ func TestMerge_trees(t *testing.T) { }{ { desc: "trivial merge succeeds", - base: map[string]string{ - "file": "a", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file": "a", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "a", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, expected: map[string]string{ "file": "a", }, expectedResponse: git2go.MergeResult{ - CommitID: "7d5ae8fb6d2b301c53560bd728004d77778998df", + CommitID: "0db317551c49eddadde2b337550d8e57d9536886", }, }, { desc: "trivial merge with different committer succeeds", - base: map[string]string{ - "file": "a", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file": "a", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "a", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, expected: map[string]string{ "file": "a", }, withCommitter: true, expectedResponse: git2go.MergeResult{ - CommitID: "cba8c5ddf5a5a24f2f606e4b62d348feb1214b70", + CommitID: "38dcbe72d91ed5621286290f70df9a5dd08f5cb6", }, }, { desc: "trivial squash succeeds", - base: map[string]string{ - "file": "a", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - ours: map[string]string{ - "file": "a", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "a", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "a", Mode: "100644"}, }, expected: map[string]string{ "file": "a", }, squash: true, expectedResponse: git2go.MergeResult{ - CommitID: "d4c52f063cd6544959d6b0d9a3d8fa8463c34086", + CommitID: "a0781480ce3cbba80440e6c112c5ee7f718ed3c2", }, }, { desc: "non-trivial merge succeeds", - base: map[string]string{ - "file": "a\nb\nc\nd\ne\nf\n", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a\nb\nc\nd\ne\nf\n", Mode: "100644"}, }, - ours: map[string]string{ - "file": "0\na\nb\nc\nd\ne\nf\n", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "0\na\nb\nc\nd\ne\nf\n", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "a\nb\nc\nd\ne\nf\n0\n", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "a\nb\nc\nd\ne\nf\n0\n", Mode: "100644"}, }, expected: map[string]string{ "file": "0\na\nb\nc\nd\ne\nf\n0\n", }, expectedResponse: git2go.MergeResult{ - CommitID: "348b9b489c3ca128a4555c7a51b20335262519c7", + CommitID: "3c030d1ee80bbb005666619375fa0629c86b9534", }, }, { desc: "non-trivial squash succeeds", - base: map[string]string{ - "file": "a\nb\nc\nd\ne\nf\n", + base: []gittest.TreeEntry{ + {Path: "file", Content: "a\nb\nc\nd\ne\nf\n", Mode: "100644"}, }, - ours: map[string]string{ - "file": "0\na\nb\nc\nd\ne\nf\n", + ours: []gittest.TreeEntry{ + {Path: "file", Content: "0\na\nb\nc\nd\ne\nf\n", Mode: "100644"}, }, - theirs: map[string]string{ - "file": "a\nb\nc\nd\ne\nf\n0\n", + theirs: []gittest.TreeEntry{ + {Path: "file", Content: "a\nb\nc\nd\ne\nf\n0\n", Mode: "100644"}, }, expected: map[string]string{ "file": "0\na\nb\nc\nd\ne\nf\n0\n", }, squash: true, expectedResponse: git2go.MergeResult{ - CommitID: "7ef7460f69503265a247e06218391cfa57c521fc", + CommitID: "43853c4a027a67c7e39afa8e7ef0a34a1874ef26", }, }, { desc: "multiple files succeed", - base: map[string]string{ - "1": "foo", - "2": "bar", - "3": "qux", + base: []gittest.TreeEntry{ + {Path: "1", Content: "foo", Mode: "100644"}, + {Path: "2", Content: "bar", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, - ours: map[string]string{ - "1": "foo", - "2": "modified", - "3": "qux", + ours: []gittest.TreeEntry{ + {Path: "1", Content: "foo", Mode: "100644"}, + {Path: "2", Content: "modified", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, - theirs: map[string]string{ - "1": "modified", - "2": "bar", - "3": "qux", + theirs: []gittest.TreeEntry{ + {Path: "1", Content: "modified", Mode: "100644"}, + {Path: "2", Content: "bar", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, expected: map[string]string{ "1": "modified", @@ -238,25 +237,25 @@ func TestMerge_trees(t *testing.T) { "3": "qux", }, expectedResponse: git2go.MergeResult{ - CommitID: "e9be4578f89ea52d44936fb36517e837d698b34b", + CommitID: "6be1fdb2c4116881c7a82575be41618e8a690ff4", }, }, { desc: "multiple files squash succeed", - base: map[string]string{ - "1": "foo", - "2": "bar", - "3": "qux", + base: []gittest.TreeEntry{ + {Path: "1", Content: "foo", Mode: "100644"}, + {Path: "2", Content: "bar", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, - ours: map[string]string{ - "1": "foo", - "2": "modified", - "3": "qux", + ours: []gittest.TreeEntry{ + {Path: "1", Content: "foo", Mode: "100644"}, + {Path: "2", Content: "modified", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, - theirs: map[string]string{ - "1": "modified", - "2": "bar", - "3": "qux", + theirs: []gittest.TreeEntry{ + {Path: "1", Content: "modified", Mode: "100644"}, + {Path: "2", Content: "bar", Mode: "100644"}, + {Path: "3", Content: "qux", Mode: "100644"}, }, expected: map[string]string{ "1": "modified", @@ -265,19 +264,19 @@ func TestMerge_trees(t *testing.T) { }, squash: true, expectedResponse: git2go.MergeResult{ - CommitID: "a680459fe541be728c8494fb76c233a344c04460", + CommitID: "fe094a98b22ac53e1da1a9eb16118ce49f01fdbe", }, }, { desc: "conflicting merge fails", - base: map[string]string{ - "1": "foo", + base: []gittest.TreeEntry{ + {Path: "1", Content: "foo", Mode: "100644"}, }, - ours: map[string]string{ - "1": "bar", + ours: []gittest.TreeEntry{ + {Path: "1", Content: "bar", Mode: "100644"}, }, - theirs: map[string]string{ - "1": "qux", + theirs: []gittest.TreeEntry{ + {Path: "1", Content: "qux", Mode: "100644"}, }, expectedErr: fmt.Errorf("merge: %w", git2go.ConflictingFilesError{ ConflictingFiles: []string{"1"}, @@ -290,9 +289,9 @@ func TestMerge_trees(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) executor := buildExecutor(t, cfg) - base := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{nil}, tc.base) - ours := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.ours) - theirs := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, tc.theirs) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(tc.base...)) + ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.ours...)) + theirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.theirs...)) authorDate := time.Date(2020, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60)) committerDate := time.Date(2021, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60)) @@ -327,7 +326,7 @@ func TestMerge_trees(t *testing.T) { require.NoError(t, err) defer repo.Free() - commitOid, err := git.NewOid(response.CommitID) + commitOid, err := libgit2.NewOid(response.CommitID) require.NoError(t, err) commit, err := repo.LookupCommit(commitOid) @@ -358,15 +357,15 @@ func TestMerge_squash(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) executor := buildExecutor(t, cfg) - baseFiles := map[string]string{"file.txt": "b\nc"} - ourFiles := map[string]string{"file.txt": "a\nb\nc"} - theirFiles1 := map[string]string{"file.txt": "b\nc\nd"} - theirFiles2 := map[string]string{"file.txt": "b\nc\nd\ne"} + baseFile := gittest.TreeEntry{Path: "file.txt", Content: "b\nc", Mode: "100644"} + ourFile := gittest.TreeEntry{Path: "file.txt", Content: "a\nb\nc", Mode: "100644"} + theirFile1 := gittest.TreeEntry{Path: "file.txt", Content: "b\nc\nd", Mode: "100644"} + theirFile2 := gittest.TreeEntry{Path: "file.txt", Content: "b\nc\nd\ne", Mode: "100644"} - base := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{nil}, baseFiles) - ours := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, ourFiles) - theirs1 := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, theirFiles1) - theirs2 := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{theirs1}, theirFiles2) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(baseFile)) + ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(ourFile)) + theirs1 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(theirFile1)) + theirs2 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(theirs1), gittest.WithTreeEntries(theirFile2)) date := time.Date(2020, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60)) response, err := executor.Merge(ctx, repoProto, git2go.MergeCommand{ @@ -380,15 +379,17 @@ func TestMerge_squash(t *testing.T) { Squash: true, }) require.NoError(t, err) - assert.Equal(t, "027d909803fbb3d17c3b10c1dfe8f120d99392e4", response.CommitID) + assert.Equal(t, "882b43b68d160876e3833dc6bbabf7032058e837", response.CommitID) repo, err := git2goutil.OpenRepository(repoPath) require.NoError(t, err) - commitOid, err := git.NewOid(response.CommitID) + commitOid, err := libgit2.NewOid(response.CommitID) require.NoError(t, err) - isDescendant, err := repo.DescendantOf(commitOid, theirs2) + theirs2Oid, err := libgit2.NewOid(theirs2.String()) + require.NoError(t, err) + isDescendant, err := repo.DescendantOf(commitOid, theirs2Oid) require.NoError(t, err) require.False(t, isDescendant) @@ -396,7 +397,7 @@ func TestMerge_squash(t *testing.T) { require.NoError(t, err) require.Equal(t, uint(1), commit.ParentCount()) - require.Equal(t, ours, commit.ParentId(0)) + require.Equal(t, ours.String(), commit.ParentId(0).String()) tree, err := commit.Tree() require.NoError(t, err) @@ -417,17 +418,25 @@ func TestMerge_recursive(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) executor := buildExecutor(t, cfg) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) - base := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{"base": "base\n"}) + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "base", Content: "base\n", Mode: "100644"}, + )) - oursContents := map[string]string{"base": "base\n", "ours": "ours-0\n"} - ours := make([]*git.Oid, git2go.MergeRecursionLimit) - ours[0] = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, oursContents) + ours := make([]git.ObjectID, git2go.MergeRecursionLimit) + ours[0] = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "base", Content: "base\n", Mode: "100644"}, + gittest.TreeEntry{Path: "ours", Content: "ours-0\n", Mode: "100644"}, + )) - theirsContents := map[string]string{"base": "base\n", "theirs": "theirs-0\n"} - theirs := make([]*git.Oid, git2go.MergeRecursionLimit) - theirs[0] = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, theirsContents) + theirs := make([]git.ObjectID, git2go.MergeRecursionLimit) + theirs[0] = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "base", Content: "base\n", Mode: "100644"}, + gittest.TreeEntry{Path: "theirs", Content: "theirs-0\n", Mode: "100644"}, + )) // We're now creating a set of criss-cross merges which look like the following graph: // @@ -441,13 +450,17 @@ func TestMerge_recursive(t *testing.T) { // is not unique, and as a result the merge will generate virtual merge bases for each of // the criss-cross merges. This operation may thus be heavily expensive to perform. for i := 1; i < git2go.MergeRecursionLimit; i++ { - oursContents["ours"] = fmt.Sprintf("ours-%d\n", i) - oursContents["theirs"] = fmt.Sprintf("theirs-%d\n", i-1) - theirsContents["ours"] = fmt.Sprintf("ours-%d\n", i-1) - theirsContents["theirs"] = fmt.Sprintf("theirs-%d\n", i) + ours[i] = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(ours[i-1], theirs[i-1]), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "base", Content: "base\n", Mode: "100644"}, + gittest.TreeEntry{Path: "ours", Content: fmt.Sprintf("ours-%d\n", i), Mode: "100644"}, + gittest.TreeEntry{Path: "theirs", Content: fmt.Sprintf("theirs-%d\n", i-1), Mode: "100644"}, + )) - ours[i] = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{ours[i-1], theirs[i-1]}, oursContents) - theirs[i] = cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{theirs[i-1], ours[i-1]}, theirsContents) + theirs[i] = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(theirs[i-1], ours[i-1]), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "base", Content: "base\n", Mode: "100644"}, + gittest.TreeEntry{Path: "ours", Content: fmt.Sprintf("ours-%d\n", i-1), Mode: "100644"}, + gittest.TreeEntry{Path: "theirs", Content: fmt.Sprintf("theirs-%d\n", i), Mode: "100644"}, + )) } authorDate := time.Date(2020, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60)) @@ -500,7 +513,7 @@ func TestMerge_recursive(t *testing.T) { repo, err := git2goutil.OpenRepository(repoPath) require.NoError(t, err) - commitOid, err := git.NewOid(response.CommitID) + commitOid, err := libgit2.NewOid(response.CommitID) require.NoError(t, err) commit, err := repo.LookupCommit(commitOid) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase.go index 1c2e9acd06..1fa23984ee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -11,8 +10,8 @@ import ( "fmt" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type rebaseSubcommand struct{} @@ -74,6 +73,7 @@ func (cmd *rebaseSubcommand) rebase(ctx context.Context, request *git2go.RebaseC return "", fmt.Errorf("get rebase options: %w", err) } opts.InMemory = 1 + opts.CommitCreateCallback = git2goutil.NewCommitSubmitter(repo, request.SigningKey).Commit var commit *git.AnnotatedCommit if request.BranchName != "" { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase_test.go index f3756e9f6e..2ef76db620 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/rebase_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/rebase_test.go @@ -1,5 +1,4 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main @@ -10,13 +9,12 @@ import ( git "github.com/libgit2/git2go/v33" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - cmdtesthelper "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper" - gitalygit "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + gitalygit "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) var masterRevision = "1e292f8fedd741b75372e19097c76d327140c312" @@ -117,38 +115,38 @@ func TestRebase_rebase(t *testing.T) { { desc: "Partially merged branch", branch: "branch-merged-plus-one", - setupRepo: func(t testing.TB, repo *git.Repository) { + setupRepo: func(tb testing.TB, repo *git.Repository) { head, err := lookupCommit(repo, "branch-merged") - require.NoError(t, err) + require.NoError(tb, err) other, err := lookupCommit(repo, "gitaly-rename-test") - require.NoError(t, err) + require.NoError(tb, err) tree, err := other.Tree() - require.NoError(t, err) - newOid, err := repo.CreateCommitFromIds("refs/heads/branch-merged-plus-one", &cmdtesthelper.DefaultAuthor, &cmdtesthelper.DefaultAuthor, "Message", tree.Object.Id(), head.Object.Id()) - require.NoError(t, err) - require.Equal(t, "5da601ef10e314884bbade9d5b063be37579ccf9", newOid.String()) + require.NoError(tb, err) + newOid, err := repo.CreateCommitFromIds("refs/heads/branch-merged-plus-one", &DefaultAuthor, &DefaultAuthor, "Message", tree.Object.Id(), head.Object.Id()) + require.NoError(tb, err) + require.Equal(tb, "8665d9b4b56f6b8ab8c4128a5549d1820bf68bf5", newOid.String()) }, commitsAhead: 1, - expected: "591b29084164bcc58fa4fb851a3c409290b17bfe", + expected: "56bafb70922008232d171b78930be6cdb722bb39", }, { desc: "With upstream merged into", branch: "csv-plus-merge", - setupRepo: func(t testing.TB, repo *git.Repository) { + setupRepo: func(tb testing.TB, repo *git.Repository) { ours, err := lookupCommit(repo, "csv") - require.NoError(t, err) + require.NoError(tb, err) theirs, err := lookupCommit(repo, "b83d6e391c22777fca1ed3012fce84f633d7fed0") - require.NoError(t, err) + require.NoError(tb, err) index, err := repo.MergeCommits(ours, theirs, nil) - require.NoError(t, err) + require.NoError(tb, err) tree, err := index.WriteTreeTo(repo) - require.NoError(t, err) + require.NoError(tb, err) - newOid, err := repo.CreateCommitFromIds("refs/heads/csv-plus-merge", &cmdtesthelper.DefaultAuthor, &cmdtesthelper.DefaultAuthor, "Message", tree, ours.Object.Id(), theirs.Object.Id()) - require.NoError(t, err) - require.Equal(t, "5cfe4a597b54c8f2b7ae85212f67599a1492009c", newOid.String()) + newOid, err := repo.CreateCommitFromIds("refs/heads/csv-plus-merge", &DefaultAuthor, &DefaultAuthor, "Message", tree, ours.Object.Id(), theirs.Object.Id()) + require.NoError(tb, err) + require.Equal(tb, "5b2d6bd7be0b1b9f7e46b64d02fe9882c133a128", newOid.String()) }, commitsAhead: 5, // Same as "Multiple commits" expected: "2f8365edc69d3683e22c4209ae9641642d84dd4a", @@ -248,7 +246,7 @@ func TestRebase_skipEmptyCommit(t *testing.T) { // Set up history with two diverging lines of branches, where both sides have implemented // the same changes. During rebase, the diff will thus become empty. base := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithParents(), gittest.WithTreeEntries(gittest.TreeEntry{ + gittest.WithTreeEntries(gittest.TreeEntry{ Path: "a", Content: "base", Mode: "100644", }), ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/resolve_conflicts.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/resolve_conflicts.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/resolve_conflicts.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/resolve_conflicts.go index 13c06243e8..6d05f59c70 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/resolve_conflicts.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/resolve_conflicts.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -14,9 +13,9 @@ import ( "time" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type resolveSubcommand struct{} @@ -181,26 +180,31 @@ func (cmd resolveSubcommand) Run(_ context.Context, decoder *gob.Decoder, encode return fmt.Errorf("Missing resolutions for the following files: %s", strings.Join(conflictPaths, ", ")) //nolint } - tree, err := index.WriteTreeTo(repo) + treeOID, err := index.WriteTreeTo(repo) if err != nil { return fmt.Errorf("write tree to repo: %w", err) } + tree, err := repo.LookupTree(treeOID) + if err != nil { + return fmt.Errorf("lookup tree: %w", err) + } - signature := git2go.NewSignature(request.AuthorName, request.AuthorMail, request.AuthorDate) + sign := git2go.NewSignature(request.AuthorName, request.AuthorMail, request.AuthorDate) committer := &git.Signature{ - Name: signature.Name, - Email: signature.Email, + Name: sign.Name, + Email: sign.Email, When: request.AuthorDate, } - commit, err := repo.CreateCommitFromIds("", committer, committer, request.Message, tree, ours.Id(), theirs.Id()) + commitID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey). + Commit(committer, committer, git.MessageEncodingUTF8, request.Message, tree, ours, theirs) if err != nil { - return fmt.Errorf("could not create resolve conflict commit: %w", err) + return fmt.Errorf("create commit: %w", err) } response := git2go.ResolveResult{ MergeResult: git2go.MergeResult{ - CommitID: commit.String(), + CommitID: commitID.String(), }, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert.go index acb9e9d3db..725502289a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -11,8 +10,8 @@ import ( "fmt" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type revertSubcommand struct{} @@ -86,20 +85,25 @@ func (cmd *revertSubcommand) revert(ctx context.Context, request *git2go.RevertC return "", git2go.HasConflictsError{} } - tree, err := index.WriteTreeTo(repo) + treeOID, err := index.WriteTreeTo(repo) if err != nil { return "", fmt.Errorf("write tree: %w", err) } + tree, err := repo.LookupTree(treeOID) + if err != nil { + return "", fmt.Errorf("lookup tree: %w", err) + } - if tree.Equal(ours.TreeId()) { + if treeOID.Equal(ours.TreeId()) { return "", git2go.EmptyError{} } committer := git.Signature(git2go.NewSignature(request.AuthorName, request.AuthorMail, request.AuthorDate)) - commit, err := repo.CreateCommitFromIds("", &committer, &committer, request.Message, tree, ours.Id()) + commitID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey). + Commit(&committer, &committer, git.MessageEncodingUTF8, request.Message, tree, ours) if err != nil { - return "", fmt.Errorf("create revert commit: %w", err) + return "", fmt.Errorf("create commit: %w", err) } - return commit.String(), nil + return commitID.String(), nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert_test.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert_test.go index fb0235e608..aa3d8df371 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/revert_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/revert_test.go @@ -1,5 +1,4 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main @@ -11,11 +10,12 @@ import ( git "github.com/libgit2/git2go/v33" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - cmdtesthelper "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestRevert_validation(t *testing.T) { @@ -77,7 +77,7 @@ func TestRevert_validation(t *testing.T) { func TestRevert_trees(t *testing.T) { testcases := []struct { desc string - setupRepo func(t testing.TB, repoPath string) (ours, revert string) + setupRepo func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) expected map[string]string expectedCommitID string expectedErr string @@ -85,20 +85,21 @@ func TestRevert_trees(t *testing.T) { }{ { desc: "trivial revert succeeds", - setupRepo: func(t testing.TB, repoPath string) (ours, revert string) { - baseOid := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{ - "a": "apple", - "b": "banana", - }) - revertOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{baseOid}, map[string]string{ - "a": "apple", - "b": "pineapple", - }) - oursOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{revertOid}, map[string]string{ - "a": "apple", - "b": "pineapple", - "c": "carrot", - }) + setupRepo: func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) { + baseOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + gittest.TreeEntry{Path: "b", Content: "banana", Mode: "100644"}, + )) + revertOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithParents(baseOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + gittest.TreeEntry{Path: "b", Content: "pineapple", Mode: "100644"}, + )) + oursOid := gittest.WriteCommit(tb, cfg, repoPath, + gittest.WithParents(revertOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + gittest.TreeEntry{Path: "b", Content: "pineapple", Mode: "100644"}, + gittest.TreeEntry{Path: "c", Content: "carrot", Mode: "100644"}, + )) return oursOid.String(), revertOid.String() }, @@ -107,20 +108,20 @@ func TestRevert_trees(t *testing.T) { "b": "banana", "c": "carrot", }, - expectedCommitID: "0be709b57f18ad3f592a8cb7c57f920861392573", + expectedCommitID: "c9a58d2273b265cb229f02a5a88037bbdc96ad26", }, { desc: "conflicting revert fails", - setupRepo: func(t testing.TB, repoPath string) (ours, revert string) { - baseOid := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{ - "a": "apple", - }) - revertOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{baseOid}, map[string]string{ - "a": "pineapple", - }) - oursOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{revertOid}, map[string]string{ - "a": "carrot", - }) + setupRepo: func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) { + baseOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + )) + revertOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithParents(baseOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "pineapple", Mode: "100644"}, + )) + oursOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithParents(revertOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "carrot", Mode: "100644"}, + )) return oursOid.String(), revertOid.String() }, @@ -129,16 +130,16 @@ func TestRevert_trees(t *testing.T) { }, { desc: "empty revert fails", - setupRepo: func(t testing.TB, repoPath string) (ours, revert string) { - baseOid := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{ - "a": "apple", - }) - revertOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{baseOid}, map[string]string{ - "a": "banana", - }) - oursOid := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{revertOid}, map[string]string{ - "a": "apple", - }) + setupRepo: func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) { + baseOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + )) + revertOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithParents(baseOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "banana", Mode: "100644"}, + )) + oursOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithParents(revertOid), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + )) return oursOid.String(), revertOid.String() }, @@ -147,10 +148,10 @@ func TestRevert_trees(t *testing.T) { }, { desc: "nonexistent ours fails", - setupRepo: func(t testing.TB, repoPath string) (ours, revert string) { - revertOid := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{ - "a": "apple", - }) + setupRepo: func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) { + revertOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + )) return "nonexistent", revertOid.String() }, @@ -158,10 +159,10 @@ func TestRevert_trees(t *testing.T) { }, { desc: "nonexistent revert fails", - setupRepo: func(t testing.TB, repoPath string) (ours, revert string) { - oursOid := cmdtesthelper.BuildCommit(t, repoPath, nil, map[string]string{ - "a": "apple", - }) + setupRepo: func(tb testing.TB, cfg config.Cfg, repoPath string) (ours, revert string) { + oursOid := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Content: "apple", Mode: "100644"}, + )) return oursOid.String(), "nonexistent" }, @@ -174,7 +175,7 @@ func TestRevert_trees(t *testing.T) { testcfg.BuildGitalyGit2Go(t, cfg) executor := buildExecutor(t, cfg) - ours, revert := tc.setupRepo(t, repoPath) + ours, revert := tc.setupRepo(t, cfg, repoPath) ctx := testhelper.Context(t) authorDate := time.Date(2020, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule.go index 24e3fef7e3..4596a5ff96 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main @@ -11,8 +10,8 @@ import ( "time" git "github.com/libgit2/git2go/v33" - "gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/git2goutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/git2goutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" ) type submoduleSubcommand struct{} @@ -122,14 +121,16 @@ func (cmd *submoduleSubcommand) run(request git2go.SubmoduleCommand) (*git2go.Su request.AuthorDate, ), ) - newCommitOID, err := repo.CreateCommit( - "", // caller should update branch with hooks - &committer, - &committer, - request.Message, - newTree, - startCommit, - ) + + newCommitOID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey). + Commit( + &committer, + &committer, + git.MessageEncodingUTF8, + request.Message, + newTree, + startCommit, + ) if err != nil { return nil, fmt.Errorf( "%s: %w", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule_test.go index 98ba9cbe6e..c05bc0af50 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/submodule_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/submodule_test.go @@ -1,5 +1,4 @@ -//go:build static && system_libgit2 -// +build static,system_libgit2 +//go:build static && system_libgit2 && !gitaly_test_sha256 package main @@ -9,13 +8,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestSubmodule(t *testing.T) { @@ -120,7 +119,7 @@ func TestSubmodule(t *testing.T) { fmt.Sprintf("%s^{tree}:", response.CommitID), tc.command.Submodule, ) - parser := lstree.NewParser(bytes.NewReader(entry)) + parser := lstree.NewParser(bytes.NewReader(entry), git.ObjectHashSHA1) parsedEntry, err := parser.NextEntry() require.NoError(t, err) require.Equal(t, tc.command.Submodule, parsedEntry.Path) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/testhelper_test.go new file mode 100644 index 0000000000..274687cb65 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/testhelper_test.go @@ -0,0 +1,44 @@ +//go:build static && system_libgit2 && !gitaly_test_sha256 + +package main + +import ( + "fmt" + "testing" + + git "github.com/libgit2/git2go/v33" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +// DefaultAuthor is the author used by BuildCommit +var DefaultAuthor = git.Signature{ + Name: gittest.DefaultCommitterName, + Email: gittest.DefaultCommitterMail, + When: gittest.DefaultCommitTime, +} + +func TestMain(m *testing.M) { + testhelper.Run(m, testhelper.WithSetup(func() error { + // We use Git2go to access repositories in our tests, so we must tell it to ignore + // any configuration files that happen to exist. We do the same in `main()`, so + // this is not only specific to tests. + for _, configLevel := range []git.ConfigLevel{ + git.ConfigLevelSystem, + git.ConfigLevelXDG, + git.ConfigLevelGlobal, + } { + if err := git.SetSearchPath(configLevel, "/dev/null"); err != nil { + return fmt.Errorf("setting Git2go search path: %s", err) + } + } + + return nil + })) +} + +func buildExecutor(tb testing.TB, cfg config.Cfg) *git2go.Executor { + return git2go.NewExecutor(cfg, gittest.NewCommandFactory(tb, cfg), config.NewLocator(cfg)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/util.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/util.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/util.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/util.go index feed724abb..7a94371c3d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-git2go-v14/util.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go/util.go @@ -1,5 +1,4 @@ //go:build static && system_libgit2 -// +build static,system_libgit2 package main diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/.gitignore b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/.gitignore similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/.gitignore rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/.gitignore diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/README.md new file mode 100644 index 0000000000..715a2566a1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/README.md @@ -0,0 +1,3 @@ +# gitaly-hooks + +See the [hooks documentation](../../doc/hooks.md) for how `gitaly-hooks` fits into Gitaly. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks.go index 125be64d60..39d0e4ba4a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks.go @@ -9,22 +9,19 @@ import ( "os" "path/filepath" - "github.com/sirupsen/logrus" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "gitlab.com/gitlab-org/labkit/tracing" "google.golang.org/grpc" + "google.golang.org/grpc/metadata" ) type hookError struct { @@ -87,31 +84,6 @@ func run(args []string) error { subCmd := args[1] switch subCmd { - case "check": - logrus.SetLevel(logrus.ErrorLevel) - if len(args) != 3 { - fmt.Fprint(os.Stderr, "no configuration file path provided invoke with: gitaly-hooks check ") - os.Exit(1) - } - - configPath := args[2] - fmt.Print("Checking GitLab API access: ") - - info, err := check(configPath) - if err != nil { - fmt.Print("FAIL\n") - fmt.Fprint(os.Stderr, err) - os.Exit(1) - } - - fmt.Print("OK\n") - fmt.Printf("GitLab version: %s\n", info.Version) - fmt.Printf("GitLab revision: %s\n", info.Revision) - fmt.Printf("GitLab Api version: %s\n", info.APIVersion) - fmt.Printf("Redis reachable for GitLab: %t\n", info.RedisReachable) - fmt.Println("OK") - - return nil case "git": return executeHook(hookCommand{ exec: packObjectsHook, @@ -160,7 +132,10 @@ func executeHook(cmd hookCommand, args []string) error { hookClient := gitalypb.NewHookServiceClient(conn) - ctx = featureflag.OutgoingWithRaw(ctx, payload.FeatureFlags) + for _, flag := range payload.FeatureFlagsWithValue { + ctx = featureflag.OutgoingCtxWithFeatureFlag(ctx, flag.Flag, flag.Enabled) + } + if err := cmd.exec(ctx, payload, hookClient, args); err != nil { return err } @@ -211,32 +186,6 @@ func sendFunc(reqWriter io.Writer, stream grpc.ClientStream, stdin io.Reader) fu } } -func check(configPath string) (*gitlab.CheckInfo, error) { - cfgFile, err := os.Open(configPath) - if err != nil { - return nil, fmt.Errorf("failed to open config file: %w", err) - } - defer cfgFile.Close() - - cfg, err := config.Load(cfgFile) - if err != nil { - return nil, err - } - - gitlabAPI, err := gitlab.NewHTTPClient(logrus.New(), cfg.Gitlab, cfg.TLS, prometheus.Config{}) - if err != nil { - return nil, err - } - - gitCmdFactory, cleanup, err := git.NewExecCommandFactory(cfg) - if err != nil { - return nil, err - } - defer cleanup() - - return hook.NewManager(cfg, config.NewLocator(cfg), gitCmdFactory, nil, gitlabAPI).Check(context.TODO()) -} - func updateHook(ctx context.Context, payload git.HooksPayload, hookClient gitalypb.HookServiceClient, args []string) error { if len(args) != 3 { return fmt.Errorf("update hook expects exactly three arguments, got %q", args) @@ -387,9 +336,42 @@ func handlePackObjectsWithSidechannel(ctx context.Context, payload git.HooksPayl } defer wt.Close() + var glID, glUsername, gitProtocol string + + // TODO: remove this conditional in 15.2. + // Since the git2go binary is replaced before the gitaly binary, there + // is a period of time during an upgrade when the gitaly binary is older + // than the corresponding git2go binary, which means gitaly will still + // be sending ReceiveHooksPayload until the upgrade is finished. + if payload.UserDetails != nil { + glID = payload.UserDetails.UserID + glUsername = payload.UserDetails.Username + gitProtocol = payload.UserDetails.Protocol + } else if payload.ReceiveHooksPayload != nil { + glID = payload.ReceiveHooksPayload.UserID + glUsername = payload.ReceiveHooksPayload.Username + gitProtocol = payload.ReceiveHooksPayload.Protocol + } + + ctx = metadata.AppendToOutgoingContext( + ctx, + "user_id", + glID, + "username", + glUsername, + "protocol", + gitProtocol, + ) + if _, err := hookClient.PackObjectsHookWithSidechannel( ctx, - &gitalypb.PackObjectsHookWithSidechannelRequest{Repository: payload.Repo, Args: args}, + &gitalypb.PackObjectsHookWithSidechannelRequest{ + Repository: payload.Repo, + Args: args, + GlId: glID, + GlUsername: glUsername, + GitProtocol: gitProtocol, + }, ); err != nil { return fmt.Errorf("call PackObjectsHookWithSidechannel: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks_test.go index 2a529366c7..b5479123c0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-hooks/hooks_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-hooks/hooks_test.go @@ -1,9 +1,10 @@ +//go:build !gitaly_test_sha256 + package main import ( "bytes" "context" - "encoding/json" "fmt" "os" "os/exec" @@ -12,27 +13,27 @@ import ( "strings" "testing" - "github.com/pelletier/go-toml" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - internallog "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + internallog "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -50,20 +51,20 @@ var ( disabledFeatureFlag = featureflag.FeatureFlag{Name: "disabled-feature-flag", OnByDefault: true} ) -func rawFeatureFlags(ctx context.Context) featureflag.Raw { +func featureFlags(ctx context.Context) map[featureflag.FeatureFlag]bool { ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, enabledFeatureFlag, true) ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, disabledFeatureFlag, false) - return featureflag.RawFromContext(ctx) + return featureflag.FromContext(ctx) } // envForHooks generates a set of environment variables for gitaly hooks -func envForHooks(t testing.TB, ctx context.Context, cfg config.Cfg, repo *gitalypb.Repository, glHookValues glHookValues, proxyValues proxyValues, gitPushOptions ...string) []string { - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.ReceiveHooksPayload{ +func envForHooks(tb testing.TB, ctx context.Context, cfg config.Cfg, repo *gitalypb.Repository, glHookValues glHookValues, proxyValues proxyValues, gitPushOptions ...string) []string { + payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ UserID: glHookValues.GLID, Username: glHookValues.GLUsername, Protocol: glHookValues.GLProtocol, - }, git.AllHooks, rawFeatureFlags(ctx)).Env() - require.NoError(t, err) + }, git.AllHooks, featureFlags(ctx)).Env() + require.NoError(tb, err) env := append(command.AllowedEnvironment(os.Environ()), []string{ payload, @@ -161,8 +162,6 @@ func testHooksPrePostReceive(t *testing.T, cfg config.Cfg, repo *gitalypb.Reposi cfg.Gitlab.HTTPSettings.User = gitlabUser cfg.Gitlab.HTTPSettings.Password = gitlabPassword - gitalyHooksPath := filepath.Join(cfg.BinDir, "gitaly-hooks") - gitlabClient, err := gitlab.NewHTTPClient(logger, cfg.Gitlab, cfg.TLS, prometheus.Config{}) require.NoError(t, err) @@ -180,7 +179,7 @@ func testHooksPrePostReceive(t *testing.T, cfg config.Cfg, repo *gitalypb.Reposi var stderr, stdout bytes.Buffer stdin := bytes.NewBuffer([]byte(changes)) require.NoError(t, err) - cmd := exec.Command(gitalyHooksPath) + cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) cmd.Args = []string{hookName} cmd.Stderr = &stderr cmd.Stdout = &stdout @@ -274,30 +273,29 @@ func TestHooksUpdate(t *testing.T) { } func testHooksUpdate(t *testing.T, ctx context.Context, cfg config.Cfg, glValues glHookValues) { - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) refval, oldval, newval := "refval", strings.Repeat("a", 40), strings.Repeat("b", 40) - cmd := exec.Command(filepath.Join(cfg.BinDir, "gitaly-hooks")) + // Write a custom update hook that dumps all arguments seen by the hook... + customHookArgsPath := filepath.Join(testhelper.TempDir(t), "containsarguments") + testhelper.WriteExecutable(t, + filepath.Join(repoPath, "custom_hooks", "update.d", "dumpargsscript"), + []byte(fmt.Sprintf(`#!/bin/bash + echo "$@" >%q + `, customHookArgsPath)), + ) + + // ... and a second custom hook that dumps the environment variables. + customHookEnvPath := gittest.WriteEnvToCustomHook(t, repoPath, "update") + + var stdout, stderr bytes.Buffer + cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) cmd.Args = []string{"update", refval, oldval, newval} cmd.Env = envForHooks(t, ctx, cfg, repo, glValues, proxyValues{}) cmd.Dir = repoPath - - tempDir := testhelper.TempDir(t) - - customHookArgsPath := filepath.Join(tempDir, "containsarguments") - dumpArgsToTempfileScript := fmt.Sprintf(`#!/usr/bin/env ruby -require 'json' -open('%s', 'w') { |f| f.puts(JSON.dump(ARGV)) } -`, customHookArgsPath) - // write a custom hook to path/to/repo.git/custom_hooks/update.d/dumpargsscript which dumps the args into a tempfile - testhelper.WriteExecutable(t, filepath.Join(repoPath, "custom_hooks", "update.d", "dumpargsscript"), []byte(dumpArgsToTempfileScript)) - - // write a custom hook to path/to/repo.git/custom_hooks/update which dumps the env into a tempfile - customHookOutputPath := gittest.WriteEnvToCustomHook(t, repoPath, "update") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout cmd.Stderr = &stderr cmd.Dir = repoPath @@ -306,15 +304,14 @@ open('%s', 'w') { |f| f.puts(JSON.dump(ARGV)) } require.Empty(t, stdout.String()) require.Empty(t, stderr.String()) - require.FileExists(t, customHookArgsPath) + // Ensure that the hook was executed with the expected arguments... + require.Equal(t, + fmt.Sprintf("%s %s %s", refval, oldval, newval), + text.ChompBytes(testhelper.MustReadFile(t, customHookArgsPath)), + ) - var inputs []string - - b := testhelper.MustReadFile(t, customHookArgsPath) - require.NoError(t, json.Unmarshal(b, &inputs)) - require.Equal(t, []string{refval, oldval, newval}, inputs) - - output := string(testhelper.MustReadFile(t, customHookOutputPath)) + // ... and with the expected environment variables. + output := string(testhelper.MustReadFile(t, customHookEnvPath)) require.Contains(t, output, "GL_USERNAME="+glValues.GLUsername) require.Contains(t, output, "GL_ID="+glValues.GLID) require.Contains(t, output, "GL_REPOSITORY="+repo.GetGlRepository()) @@ -407,13 +404,13 @@ func TestHooksPostReceiveFailed(t *testing.T) { Node: "node", Primary: tc.primary, }, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: glID, Username: glUsername, Protocol: glProtocol, }, git.PostReceiveHook, - rawFeatureFlags(ctx), + featureFlags(ctx), ).Env() require.NoError(t, err) @@ -492,93 +489,6 @@ func TestHooksNotAllowed(t *testing.T) { require.NoFileExists(t, customHookOutputPath) } -func TestCheckOK(t *testing.T) { - user, password := "user123", "password321" - - c := gitlab.TestServerOptions{ - User: user, - Password: password, - SecretToken: "", - GLRepository: "", - Changes: "", - PostReceiveCounterDecreased: false, - Protocol: "ssh", - } - serverURL, cleanup := gitlab.NewTestServer(t, c) - defer cleanup() - - cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ - Gitlab: config.Gitlab{ - URL: serverURL, - HTTPSettings: config.HTTPSettings{ - User: user, - Password: password, - }, - SecretFile: gitlab.WriteShellSecretFile(t, testhelper.TempDir(t), "the secret"), - }, - })) - testcfg.BuildGitalyHooks(t, cfg) - testcfg.BuildGitalySSH(t, cfg) - - configPath := writeTemporaryGitalyConfigFile(t, cfg) - - cmd := exec.Command(filepath.Join(cfg.BinDir, "gitaly-hooks"), "check", configPath) - - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - - err := cmd.Run() - require.NoError(t, err) - require.Empty(t, stderr.String()) - - output := stdout.String() - require.Contains(t, output, "Checking GitLab API access: OK") - require.Contains(t, output, "Redis reachable for GitLab: true") -} - -func TestCheckBadCreds(t *testing.T) { - user, password := "user123", "password321" - - c := gitlab.TestServerOptions{ - User: user, - Password: password, - SecretToken: "", - GLRepository: "", - Changes: "", - PostReceiveCounterDecreased: false, - Protocol: "ssh", - GitPushOptions: nil, - } - serverURL, cleanup := gitlab.NewTestServer(t, c) - defer cleanup() - - cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ - Gitlab: config.Gitlab{ - URL: serverURL, - HTTPSettings: config.HTTPSettings{ - User: "wrong", - Password: password, - }, - SecretFile: gitlab.WriteShellSecretFile(t, testhelper.TempDir(t), "the secret"), - }, - })) - testcfg.BuildGitalyHooks(t, cfg) - testcfg.BuildGitalySSH(t, cfg) - - configPath := writeTemporaryGitalyConfigFile(t, cfg) - - cmd := exec.Command(filepath.Join(cfg.BinDir, "gitaly-hooks"), "check", configPath) - - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - - require.Error(t, cmd.Run()) - require.Contains(t, stderr.String(), "HTTP GET to GitLab endpoint /check failed: authorization failed") - require.Regexp(t, `Checking GitLab API access: .* level=error msg="Internal API error" .* error="authorization failed" method=GET status=401 url="http://127.0.0.1:[0-9]+/api/v4/internal/check"\nFAIL`, stdout.String()) -} - func runHookServiceServer(t *testing.T, cfg config.Cfg, serverOpts ...testserver.GitalyServerOpt) { runHookServiceWithGitlabClient(t, cfg, gitlab.NewMockClient( t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, @@ -624,7 +534,7 @@ func (svc featureFlagAsserter) PackObjectsHookWithSidechannel(ctx context.Contex func runHookServiceWithGitlabClient(t *testing.T, cfg config.Cfg, gitlabClient gitlab.Client, serverOpts ...testserver.GitalyServerOpt) { testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterHookServiceServer(srv, featureFlagAsserter{ - t: t, wrapped: hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache()), + t: t, wrapped: hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker()), }) }, append(serverOpts, testserver.WithGitLabClient(gitlabClient))...) } @@ -652,7 +562,7 @@ func TestGitalyHooksPackObjects(t *testing.T) { baseArgs := []string{ "clone", "-u", - "git -c uploadpack.allowFilter -c uploadpack.packObjectsHook=" + cfg.BinDir + "/gitaly-hooks upload-pack", + "git -c uploadpack.allowFilter -c uploadpack.packObjectsHook=" + cfg.BinaryPath("gitaly-hooks") + " upload-pack", "--quiet", "--no-local", "--bare", @@ -702,7 +612,7 @@ func TestRequestedHooks(t *testing.T) { payload, err := git.NewHooksPayload(cfg, &gitalypb.Repository{}, nil, nil, git.AllHooks&^hook, nil).Env() require.NoError(t, err) - cmd := exec.Command(filepath.Join(cfg.BinDir, "gitaly-hooks")) + cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) cmd.Args = hookArgs cmd.Env = []string{payload} require.NoError(t, cmd.Run()) @@ -716,7 +626,7 @@ func TestRequestedHooks(t *testing.T) { payload, err := git.NewHooksPayload(cfg, &gitalypb.Repository{}, nil, nil, hook, nil).Env() require.NoError(t, err) - cmd := exec.Command(filepath.Join(cfg.BinDir, "gitaly-hooks")) + cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) cmd.Args = hookArgs cmd.Env = []string{payload} @@ -729,17 +639,3 @@ func TestRequestedHooks(t *testing.T) { }) } } - -// writeTemporaryGitalyConfigFile writes the given Gitaly configuration into a temporary file and -// returns its path. -func writeTemporaryGitalyConfigFile(t testing.TB, cfg config.Cfg) string { - t.Helper() - - path := filepath.Join(testhelper.TempDir(t), "config.toml") - - contents, err := toml.Marshal(cfg) - require.NoError(t, err) - require.NoError(t, os.WriteFile(path, contents, 0o644)) - - return path -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main.go new file mode 100644 index 0000000000..51a63a6b43 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/labkit/tracing" +) + +func requireStdin(msg string) { + var out string + + stat, err := os.Stdin.Stat() + if err != nil { + out = fmt.Sprintf("Cannot read from STDIN. %s (%s)", msg, err) + } else if (stat.Mode() & os.ModeCharDevice) != 0 { + out = fmt.Sprintf("Cannot read from STDIN. %s", msg) + } + + if len(out) > 0 { + fmt.Println(out) + os.Exit(1) + } +} + +func main() { + requireStdin("This command should be run by the Git 'smudge' filter") + + closer, err := initLogging(os.Environ()) + if err != nil { + fmt.Fprintf(os.Stderr, "error initializing log file for gitaly-lfs-smudge: %v", err) + } + defer closer.Close() + + if err := run(os.Environ(), os.Stdout, os.Stdin); err != nil { + log.WithError(err).Error(err) + os.Exit(1) + } +} + +func initLogging(environment []string) (io.Closer, error) { + path := env.ExtractValue(environment, gitalylog.GitalyLogDirEnvKey) + if path == "" { + return log.Initialize(log.WithWriter(io.Discard)) + } + + filepath := filepath.Join(path, "gitaly_lfs_smudge.log") + + return log.Initialize( + log.WithFormatter("json"), + log.WithLogLevel("info"), + log.WithOutputName(filepath), + ) +} + +func run(environment []string, out io.Writer, in io.Reader) error { + // Since the environment is sanitized at the moment, we're only + // using this to extract the correlation ID. The finished() call + // to clean up the tracing will be a NOP here. + ctx, finished := tracing.ExtractFromEnv(context.Background()) + defer finished() + + cfg, err := smudge.ConfigFromEnvironment(environment) + if err != nil { + return fmt.Errorf("loading configuration: %w", err) + } + + switch cfg.DriverType { + case smudge.DriverTypeFilter: + if err := filter(ctx, cfg, out, in); err != nil { + return fmt.Errorf("running smudge filter: %w", err) + } + + return nil + case smudge.DriverTypeProcess: + if err := process(ctx, cfg, out, in); err != nil { + return fmt.Errorf("running smudge process: %w", err) + } + + return nil + default: + return fmt.Errorf("unknown driver type: %v", cfg.DriverType) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main_test.go new file mode 100644 index 0000000000..86662a8232 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/main_test.go @@ -0,0 +1,211 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "bytes" + "encoding/json" + "io" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +const logName = "gitaly_lfs_smudge.log" + +func TestGitalyLFSSmudge(t *testing.T) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + binary := testcfg.BuildGitalyLFSSmudge(t, cfg) + + gitlabCfg, cleanup := runTestServer(t, defaultOptions) + defer cleanup() + + tlsCfg := config.TLS{ + CertPath: certPath, + KeyPath: keyPath, + } + + marshalledGitlabCfg, err := json.Marshal(gitlabCfg) + require.NoError(t, err) + + marshalledTLSCfg, err := json.Marshal(tlsCfg) + require.NoError(t, err) + + standardEnv := func(logDir string) []string { + return []string{ + "GL_REPOSITORY=project-1", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_LOG_DIR=" + logDir, + "GITALY_TLS=" + string(marshalledTLSCfg), + } + } + + for _, tc := range []struct { + desc string + setup func(t *testing.T) ([]string, string) + stdin io.Reader + expectedErr string + expectedStdout string + expectedStderr string + expectedLogRegexp string + }{ + { + desc: "success", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + return standardEnv(logDir), filepath.Join(logDir, logName) + }, + stdin: strings.NewReader(lfsPointer), + expectedStdout: "hello world", + expectedLogRegexp: "Finished HTTP request", + }, + { + desc: "success with single envvar", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + + cfg := smudge.Config{ + GlRepository: "project-1", + Gitlab: gitlabCfg, + TLS: tlsCfg, + } + + env, err := cfg.Environment() + require.NoError(t, err) + + return []string{ + env, + "GITALY_LOG_DIR=" + logDir, + }, filepath.Join(logDir, "gitaly_lfs_smudge.log") + }, + stdin: strings.NewReader(lfsPointer), + expectedStdout: "hello world", + expectedLogRegexp: "Finished HTTP request", + }, + { + desc: "missing Gitlab repository", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + + return []string{ + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_LOG_DIR=" + logDir, + "GITALY_TLS=" + string(marshalledTLSCfg), + }, filepath.Join(logDir, logName) + }, + stdin: strings.NewReader(lfsPointer), + expectedErr: "exit status 1", + expectedLogRegexp: "error loading project: GL_REPOSITORY is not defined", + }, + { + desc: "missing Gitlab configuration", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + + return []string{ + "GL_REPOSITORY=project-1", + "GITALY_LOG_DIR=" + logDir, + "GITALY_TLS=" + string(marshalledTLSCfg), + }, filepath.Join(logDir, logName) + }, + stdin: strings.NewReader(lfsPointer), + expectedErr: "exit status 1", + expectedLogRegexp: "unable to retrieve GL_INTERNAL_CONFIG", + }, + { + desc: "missing TLS configuration", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + + return []string{ + "GL_REPOSITORY=project-1", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_LOG_DIR=" + logDir, + }, filepath.Join(logDir, logName) + }, + stdin: strings.NewReader(lfsPointer), + expectedErr: "exit status 1", + expectedLogRegexp: "unable to retrieve GITALY_TLS", + }, + { + desc: "missing log configuration", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + + return []string{ + "GL_REPOSITORY=project-1", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_TLS=" + string(marshalledTLSCfg), + }, filepath.Join(logDir, "gitaly_lfs_smudge.log") + }, + stdin: strings.NewReader(lfsPointer), + expectedStdout: "hello world", + }, + { + desc: "missing stdin", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + return standardEnv(logDir), filepath.Join(logDir, logName) + }, + expectedErr: "exit status 1", + expectedStdout: "Cannot read from STDIN. This command should be run by the Git 'smudge' filter\n", + }, + { + desc: "non-LFS-pointer input", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + return standardEnv(logDir), filepath.Join(logDir, logName) + }, + stdin: strings.NewReader("somethingsomething"), + expectedStdout: "somethingsomething", + expectedLogRegexp: "^$", + }, + { + desc: "mixed input", + setup: func(t *testing.T) ([]string, string) { + logDir := testhelper.TempDir(t) + return standardEnv(logDir), filepath.Join(logDir, logName) + }, + stdin: strings.NewReader(lfsPointer + "\nsomethingsomething\n"), + expectedStdout: lfsPointer + "\nsomethingsomething\n", + expectedLogRegexp: "^$", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + env, logFile := tc.setup(t) + + var stdout, stderr bytes.Buffer + cmd, err := command.New(ctx, []string{binary}, + command.WithStdin(tc.stdin), + command.WithStdout(&stdout), + command.WithStderr(&stderr), + command.WithEnvironment(env), + ) + require.NoError(t, err) + + err = cmd.Wait() + if tc.expectedErr == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tc.expectedErr) + } + require.Equal(t, tc.expectedStdout, stdout.String()) + require.Equal(t, tc.expectedStderr, stderr.String()) + + if tc.expectedLogRegexp == "" { + require.NoFileExists(t, logFile) + } else { + logData := testhelper.MustReadFile(t, logFile) + require.Regexp(t, tc.expectedLogRegexp, string(logData)) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge.go new file mode 100644 index 0000000000..875a084c2a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge.go @@ -0,0 +1,320 @@ +package main + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "io" + "net/url" + + "github.com/git-lfs/git-lfs/v3/lfs" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/labkit/log" +) + +func filter(ctx context.Context, cfg smudge.Config, to io.Writer, from io.Reader) (returnedErr error) { + client, err := gitlab.NewHTTPClient(log.ContextLogger(ctx), cfg.Gitlab, cfg.TLS, prometheus.Config{}) + if err != nil { + return fmt.Errorf("creating HTTP client: %w", err) + } + + output, err := smudgeOneObject(ctx, cfg, client, from) + if err != nil { + return fmt.Errorf("smudging contents: %w", err) + } + defer func() { + if err := output.Close(); err != nil && returnedErr == nil { + returnedErr = fmt.Errorf("closing LFS object: %w", err) + } + }() + + if _, err := io.Copy(to, output); err != nil { + return fmt.Errorf("writing smudged contents: %w", err) + } + + return nil +} + +// processState encodes a state machine for handling long-running filter processes. +type processState int + +const ( + // processStateAnnounce is the initial state where we expect the client to announce its + // presence. + processStateAnnounce = processState(iota) + // processStateVersions is the state where the client announces all its known versions. + processStateVersions + // processStateCapabilities is the state where we have announced our own supported version + // to the client. The client now starts to send its supported capabilities. + processStateCapabilities + // processStateCommand is the state where the client sends the command it wants us to + // perform. + processStateCommand + // processStateSmudgeMetadata is the state where the client sends metadata of the file + // that should be smudged. + processStateSmudgeMetadata + // processStateSmudgeContent is the state where the client sends the contents of the file + // that should be smudged. + processStateSmudgeContent +) + +func process(ctx context.Context, cfg smudge.Config, to io.Writer, from io.Reader) error { + client, err := gitlab.NewHTTPClient(log.ContextLogger(ctx), cfg.Gitlab, cfg.TLS, prometheus.Config{}) + if err != nil { + return fmt.Errorf("creating HTTP client: %w", err) + } + + scanner := pktline.NewScanner(from) + + writer := bufio.NewWriter(to) + + buf := make([]byte, pktline.MaxPktSize-4) + var content bytes.Buffer + + clientSupportsVersion2 := false + clientSupportsSmudgeCapability := false + + state := processStateAnnounce + for scanner.Scan() { + line := scanner.Bytes() + + var data []byte + if !pktline.IsFlush(line) { + payload, err := pktline.Payload(line) + if err != nil { + return fmt.Errorf("getting payload: %w", err) + } + + data = payload + } + + switch state { + case processStateAnnounce: + if !bytes.Equal(data, []byte("git-filter-client\n")) { + return fmt.Errorf("invalid client %q", string(data)) + } + + state = processStateVersions + case processStateVersions: + // The client will announce one or more supported versions to us. We need to + // collect them all in order to determine whether we do in fact support one + // of the announced versions. + if !pktline.IsFlush(line) { + if !bytes.HasPrefix(data, []byte("version=")) { + return fmt.Errorf("expected version, got %q", string(data)) + } + + // We only support version two of this protocol, so we have to check + // whether that version is announced by the client. + if bytes.Equal(data, []byte("version=2\n")) { + clientSupportsVersion2 = true + } + + break + } + + // We have gotten a flush packet, so the client is done announcing its + // versions. If we haven't seen our version announced then it's time to + // quit. + if !clientSupportsVersion2 { + return fmt.Errorf("client does not support version 2") + } + + // Announce that we're a server and that we're talking version 2 of this + // protocol. + if _, err := pktline.WriteString(writer, "git-filter-server\n"); err != nil { + return fmt.Errorf("announcing server presence: %w", err) + } + + if _, err := pktline.WriteString(writer, "version=2\n"); err != nil { + return fmt.Errorf("announcing server version: %w", err) + } + + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing announcement: %w", err) + } + + state = processStateCapabilities + case processStateCapabilities: + // Similar as above, the client will now announce all the capabilities it + // supports. We only support the "smudging" capability. + if !pktline.IsFlush(line) { + if !bytes.HasPrefix(data, []byte("capability=")) { + return fmt.Errorf("expected capability, got: %q", string(data)) + } + + // We only support smudging contents. + if bytes.Equal(data, []byte("capability=smudge\n")) { + clientSupportsSmudgeCapability = true + } + + break + } + + // If the client doesn't support smudging then we're done. + if !clientSupportsSmudgeCapability { + return fmt.Errorf("client does not support smudge capability") + } + + // Announce that the only capability we support ourselves is smudging. + if _, err := pktline.WriteString(writer, "capability=smudge\n"); err != nil { + return fmt.Errorf("announcing smudge capability: %w", err) + } + + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing capability announcement: %w", err) + } + + state = processStateCommand + case processStateCommand: + // We're now in the processing loop where the client may announce one or + // more smudge commands. + if !bytes.Equal(data, []byte("command=smudge\n")) { + return fmt.Errorf("expected smudge command, got %q", string(data)) + } + + state = processStateSmudgeMetadata + case processStateSmudgeMetadata: + // The client sends us various information about the blob like the path + // name or treeish. We don't care about that information, so we just wait + // until we get the flush packet. + if !pktline.IsFlush(line) { + break + } + + content.Reset() + + state = processStateSmudgeContent + case processStateSmudgeContent: + // When we receive a flush packet we know that the client is done sending us + // the clean data. + if pktline.IsFlush(line) { + smudgedReader, err := smudgeOneObject(ctx, cfg, client, &content) + if err != nil { + log.ContextLogger(ctx).WithError(err).Error("failed smudging LFS pointer") + + if _, err := pktline.WriteString(writer, "status=error\n"); err != nil { + return fmt.Errorf("reporting failure: %w", err) + } + + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing error: %w", err) + } + + state = processStateCommand + break + } + defer smudgedReader.Close() + + if _, err := pktline.WriteString(writer, "status=success\n"); err != nil { + return fmt.Errorf("sending status: %w", err) + } + + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing status: %w", err) + } + + // Read the smudged results in batches and relay it to the client. + // Because pktlines are limited in size we only ever read at most + // that many bytes. + var isEOF bool + for !isEOF { + n, err := smudgedReader.Read(buf) + if err != nil { + if !errors.Is(err, io.EOF) { + return fmt.Errorf("reading smudged contents: %w", err) + } + + isEOF = true + } + + if n > 0 { + if _, err := pktline.WriteString(writer, string(buf[:n])); err != nil { + return fmt.Errorf("writing smudged contents: %w", err) + } + } + } + smudgedReader.Close() + + // We're done writing the smudged contents to the client, so we need + // to tell the client. + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing smudged contents: %w", err) + } + + // We now have the opportunity to correct the status in case an + // error happened. For now we don't bother though and just abort the + // whole process in case we failed to read an LFS object, and that's + // why we just flush a second time. + if err := pktline.WriteFlush(writer); err != nil { + return fmt.Errorf("flushing final status: %w", err) + } + + // We are now ready to accept another command. + state = processStateCommand + break + } + + // Write the pktline into our buffer. Ideally, we could avoid slurping the + // whole content into memory first. But unfortunately, this is impossible in + // the context of long-running processes: the server-side _must not_ answer + // to the client before it has received all contents. And in the case we got + // a non-LFS-pointer as input, this means we have to slurp in all of its + // contents so that we can echo it back to the caller. + if _, err := content.Write(data); err != nil { + return fmt.Errorf("could not write clean data: %w", err) + } + } + + if err := writer.Flush(); err != nil { + return fmt.Errorf("could not flush: %w", err) + } + } + + if err := scanner.Err(); err != nil && !errors.Is(err, io.EOF) { + return fmt.Errorf("error scanning input: %w", err) + } + + if state != processStateCommand { + return fmt.Errorf("unexpected termination in state %v", state) + } + + return nil +} + +func smudgeOneObject(ctx context.Context, cfg smudge.Config, gitlabClient *gitlab.HTTPClient, from io.Reader) (io.ReadCloser, error) { + logger := log.ContextLogger(ctx) + + ptr, contents, err := lfs.DecodeFrom(from) + if err != nil { + // This isn't a valid LFS pointer. Just copy the existing pointer data. + return io.NopCloser(contents), nil + } + + logger.WithField("oid", ptr.Oid).Debug("decoded LFS OID") + + qs := url.Values{} + qs.Set("oid", ptr.Oid) + qs.Set("gl_repository", cfg.GlRepository) + u := url.URL{Path: "/lfs", RawQuery: qs.Encode()} + + response, err := gitlabClient.Get(ctx, u.String()) + if err != nil { + return nil, fmt.Errorf("error loading LFS object: %v", err) + } + + if response.StatusCode == 200 { + return response.Body, nil + } + + if err := response.Body.Close(); err != nil { + logger.WithError(err).Error("closing LFS pointer body: %w", err) + } + + return io.NopCloser(contents), nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge_test.go new file mode 100644 index 0000000000..54a8de8ad6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/smudge_test.go @@ -0,0 +1,562 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "bytes" + "fmt" + "net/http" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +const ( + lfsOid = "3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa" + lfsPointer = `version https://git-lfs.github.com/spec/v1 +oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa +size 177735 +` + lfsPointerWithCRLF = `version https://git-lfs.github.com/spec/v1 +oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa` + "\r\nsize 177735" + invalidLfsPointer = `version https://git-lfs.github.com/spec/v1 +oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa&gl_repository=project-51 +size 177735 +` + invalidLfsPointerWithNonHex = `version https://git-lfs.github.com/spec/v1 +oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12z- +size 177735` + glRepository = "project-1" + secretToken = "topsecret" + testData = "hello world" + certPath = "../../internal/gitlab/testdata/certs/server.crt" + keyPath = "../../internal/gitlab/testdata/certs/server.key" +) + +var defaultOptions = gitlab.TestServerOptions{ + SecretToken: secretToken, + LfsBody: testData, + LfsOid: lfsOid, + GlRepository: glRepository, + ClientCACertPath: certPath, + ServerCertPath: certPath, + ServerKeyPath: keyPath, +} + +func TestFilter_successful(t *testing.T) { + testCases := []struct { + desc string + data string + }{ + { + desc: "regular LFS pointer", + data: lfsPointer, + }, + { + desc: "LFS pointer with CRLF", + data: lfsPointerWithCRLF, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + + var b bytes.Buffer + reader := strings.NewReader(tc.data) + + gitlabCfg, cleanup := runTestServer(t, defaultOptions) + defer cleanup() + + cfg := smudge.Config{ + GlRepository: "project-1", + Gitlab: gitlabCfg, + TLS: config.TLS{ + CertPath: certPath, + KeyPath: keyPath, + }, + } + + require.NoError(t, filter(ctx, cfg, &b, reader)) + require.Equal(t, testData, b.String()) + }) + } +} + +func TestFilter_unsuccessful(t *testing.T) { + defaultConfig := func(t *testing.T, gitlabCfg config.Gitlab) smudge.Config { + return smudge.Config{ + GlRepository: "project-1", + Gitlab: gitlabCfg, + } + } + + testCases := []struct { + desc string + setupCfg func(*testing.T, config.Gitlab) smudge.Config + data string + expectedError bool + options gitlab.TestServerOptions + expectedGitalyTLS string + }{ + { + desc: "bad LFS pointer", + data: "test data", + setupCfg: defaultConfig, + options: defaultOptions, + expectedError: false, + }, + { + desc: "invalid LFS pointer", + data: invalidLfsPointer, + setupCfg: defaultConfig, + options: defaultOptions, + expectedError: false, + }, + { + desc: "invalid LFS pointer with non-hex characters", + data: invalidLfsPointerWithNonHex, + setupCfg: defaultConfig, + options: defaultOptions, + expectedError: false, + }, + { + desc: "missing GL_REPOSITORY", + data: lfsPointer, + setupCfg: func(t *testing.T, gitlabCfg config.Gitlab) smudge.Config { + cfg := defaultConfig(t, gitlabCfg) + cfg.GlRepository = "" + return cfg + }, + options: defaultOptions, + expectedError: true, + }, + { + desc: "missing GL_INTERNAL_CONFIG", + data: lfsPointer, + setupCfg: func(t *testing.T, gitlabCfg config.Gitlab) smudge.Config { + cfg := defaultConfig(t, gitlabCfg) + cfg.Gitlab = config.Gitlab{} + return cfg + }, + options: defaultOptions, + expectedError: true, + }, + { + desc: "failed HTTP response", + data: lfsPointer, + setupCfg: defaultConfig, + options: gitlab.TestServerOptions{ + SecretToken: secretToken, + LfsBody: testData, + LfsOid: lfsOid, + GlRepository: glRepository, + LfsStatusCode: http.StatusInternalServerError, + }, + expectedError: true, + }, + { + desc: "invalid TLS paths", + data: lfsPointer, + setupCfg: func(t *testing.T, gitlabCfg config.Gitlab) smudge.Config { + cfg := defaultConfig(t, gitlabCfg) + cfg.TLS = config.TLS{CertPath: "fake-path", KeyPath: "not-real"} + return cfg + }, + options: defaultOptions, + expectedError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + + gitlabCfg, cleanup := runTestServer(t, tc.options) + defer cleanup() + + cfg := tc.setupCfg(t, gitlabCfg) + + var b bytes.Buffer + err := filter(ctx, cfg, &b, strings.NewReader(tc.data)) + + if tc.expectedError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.data, b.String()) + } + }) + } +} + +func TestProcess(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + gitlabCfg, cleanup := runTestServer(t, defaultOptions) + defer cleanup() + + defaultSmudgeCfg := smudge.Config{ + GlRepository: "project-1", + Gitlab: gitlabCfg, + TLS: config.TLS{ + CertPath: certPath, + KeyPath: keyPath, + }, + DriverType: smudge.DriverTypeProcess, + } + + pkt := func(data string) string { + return fmt.Sprintf("%04x%s", len(data)+4, data) + } + flush := "0000" + + for _, tc := range []struct { + desc string + cfg smudge.Config + input []string + expectedErr error + expectedOutput string + }{ + { + desc: "unsupported client", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-foobar-client\n"), + pkt("version=2\n"), + flush, + }, + expectedErr: fmt.Errorf("invalid client %q", "git-foobar-client\n"), + }, + { + desc: "unsupported version", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=3\n"), + flush, + }, + expectedErr: fmt.Errorf("client does not support version 2"), + }, + { + desc: "unsupported capability", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=foobar\n"), + flush, + }, + expectedErr: fmt.Errorf("client does not support smudge capability"), + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + }, ""), + }, + { + desc: "unsupported command", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=clean\n"), + flush, + }, + expectedErr: fmt.Errorf("expected smudge command, got %q", "command=clean\n"), + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + }, ""), + }, + { + desc: "single non-LFS blob", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=smudge\n"), + pkt("some=metadata\n"), + pkt("more=metadata\n"), + flush, + pkt("something"), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("something"), + flush, + flush, + }, ""), + }, + { + desc: "single non-LFS blob with multiline contents", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=smudge\n"), + pkt("some=metadata\n"), + pkt("more=metadata\n"), + flush, + pkt("some"), + pkt("thing"), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("something"), + flush, + flush, + }, ""), + }, + { + desc: "multiple non-LFS blobs", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=smudge\n"), + flush, + pkt("first"), + flush, + pkt("command=smudge\n"), + flush, + pkt("second"), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("first"), + flush, + flush, + pkt("status=success\n"), + flush, + pkt("second"), + flush, + flush, + }, ""), + }, + { + desc: "single LFS blob", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=smudge\n"), + flush, + pkt(lfsPointer), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("hello world"), + flush, + flush, + }, ""), + }, + { + desc: "multiple LFS blobs", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("command=smudge\n"), + flush, + pkt(lfsPointer), + flush, + pkt("command=smudge\n"), + flush, + pkt(lfsPointer), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("hello world"), + flush, + flush, + pkt("status=success\n"), + flush, + pkt("hello world"), + flush, + flush, + }, ""), + }, + { + desc: "full-blown session", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=1\n"), + pkt("version=2\n"), + pkt("version=99\n"), + flush, + pkt("capability=frobnicate\n"), + pkt("capability=smudge\n"), + pkt("capability=clean\n"), + flush, + // First blob. + pkt("command=smudge\n"), + pkt("unused=metadata\n"), + flush, + pkt("something something"), + flush, + // Second blob. + pkt("command=smudge\n"), + pkt("more=unused=metadata\n"), + flush, + pkt(lfsPointer), + flush, + // Third blob. + pkt("command=smudge\n"), + pkt("this=is a huge binary blob\n"), + flush, + pkt(strings.Repeat("1", pktline.MaxPktSize-4)), + pkt(strings.Repeat("2", pktline.MaxPktSize-4)), + pkt(strings.Repeat("3", pktline.MaxPktSize-4)), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=success\n"), + flush, + pkt("something something"), + flush, + flush, + pkt("status=success\n"), + flush, + pkt("hello world"), + flush, + flush, + pkt("status=success\n"), + flush, + // This looks a bit funny, but can be attributed to the fact that we + // use an io.Multireader to read the first 1024 bytes when parsing + // the LFS pointer. + pkt(strings.Repeat("1", 1024)), + pkt(strings.Repeat("1", pktline.MaxPktSize-4-1024) + strings.Repeat("2", 1024)), + pkt(strings.Repeat("2", pktline.MaxPktSize-4-1024) + strings.Repeat("3", 1024)), + pkt(strings.Repeat("3", pktline.MaxPktSize-4-1024)), + flush, + flush, + }, ""), + }, + { + desc: "partial failure", + cfg: defaultSmudgeCfg, + input: []string{ + pkt("git-filter-client\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + // The first command sends an unknown LFS pointer that should cause + // an error. + pkt("command=smudge\n"), + flush, + pkt(strings.Join([]string{ + "version https://git-lfs.github.com/spec/v1", + "oid sha256:1111111111111111111111111111111111111111111111111111111111111111", + "size 177735", + }, "\n") + "\n"), + flush, + // And the second command sends a known LFS pointer that should + // still be processed as expected, regardless of the initial error. + pkt("command=smudge\n"), + flush, + pkt(lfsPointer), + flush, + }, + expectedOutput: strings.Join([]string{ + pkt("git-filter-server\n"), + pkt("version=2\n"), + flush, + pkt("capability=smudge\n"), + flush, + pkt("status=error\n"), + flush, + pkt("status=success\n"), + flush, + pkt("hello world"), + flush, + flush, + }, ""), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + var inputBuffer bytes.Buffer + for _, input := range tc.input { + _, err := inputBuffer.WriteString(input) + require.NoError(t, err) + } + + var outputBuffer bytes.Buffer + require.Equal(t, tc.expectedErr, process(ctx, tc.cfg, &outputBuffer, &inputBuffer)) + require.Equal(t, tc.expectedOutput, outputBuffer.String()) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/testhelper_test.go new file mode 100644 index 0000000000..282f81e541 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-lfs-smudge/testhelper_test.go @@ -0,0 +1,31 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "path/filepath" + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func runTestServer(t *testing.T, options gitlab.TestServerOptions) (config.Gitlab, func()) { + tempDir := testhelper.TempDir(t) + + gitlab.WriteShellSecretFile(t, tempDir, secretToken) + secretFilePath := filepath.Join(tempDir, ".gitlab_shell_secret") + + serverURL, serverCleanup := gitlab.NewTestServer(t, options) + + c := config.Gitlab{URL: serverURL, SecretFile: secretFilePath, HTTPSettings: config.HTTPSettings{CAFile: certPath}} + + return c, func() { + serverCleanup() + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/auth_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/auth_test.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/auth_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/auth_test.go index 070006ce5f..8a59214320 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/auth_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/auth_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -10,23 +12,23 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/x509" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/x509" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/encoding/protojson" ) @@ -47,9 +49,9 @@ func TestConnectivity(t *testing.T) { require.NoError(t, os.RemoveAll(relativeSocketPath)) require.NoError(t, os.Symlink(cfg.SocketPath, relativeSocketPath)) - runGitaly := func(t testing.TB, cfg config.Cfg) string { - t.Helper() - return testserver.RunGitalyServer(t, cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + runGitaly := func(tb testing.TB, cfg config.Cfg) string { + tb.Helper() + return testserver.RunGitalyServer(tb, cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) } testCases := []struct { @@ -96,8 +98,7 @@ func TestConnectivity(t *testing.T) { name: "tls", addr: func(t *testing.T, cfg config.Cfg) (string, string) { certFile, keyFile := testhelper.GenerateCerts(t) - - testhelper.ModifyEnvironment(t, x509.SSLCertFile, certFile) + t.Setenv(x509.SSLCertFile, certFile) cfg.TLSListenAddr = "localhost:0" cfg.TLS = config.TLS{ @@ -123,7 +124,7 @@ func TestConnectivity(t *testing.T) { fmt.Sprintf("GITALY_ADDRESS=%s", addr), fmt.Sprintf("GITALY_WD=%s", cwd), fmt.Sprintf("PATH=.:%s", os.Getenv("PATH")), - fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", filepath.Join(cfg.BinDir, "gitaly-ssh")), + fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", cfg.BinaryPath("gitaly-ssh")), fmt.Sprintf("SSL_CERT_FILE=%s", certFile), } if testcase.proxy { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main.go index 137ec690b1..7284ca6c00 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main.go @@ -9,9 +9,10 @@ import ( "strings" "github.com/sirupsen/logrus" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/labkit/tracing" "google.golang.org/grpc" ) @@ -143,7 +144,7 @@ func dialOpts() []grpc.DialOption { connOpts = append(connOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(token))) } - return connOpts + return append(connOpts, internalclient.UnaryInterceptor(), internalclient.StreamInterceptor()) } func useSidechannel() bool { return os.Getenv("GITALY_USE_SIDECHANNEL") == "1" } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main_test.go index 76327740a5..ca402f3f57 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/main_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/main_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -7,8 +9,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/receive_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/receive_pack.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/receive_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/receive_pack.go index 62cc84e65e..0c8ed00dde 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/receive_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/receive_pack.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/protojson" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/testhelper_test.go index 64d8edae54..6b4c7f0f6a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package main import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_archive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_archive.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_archive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_archive.go index 618bb92d60..eb1eea6de5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_archive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_archive.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/protojson" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack.go index 97ba6b7c78..2901d490a4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/protojson" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack_test.go index 745f9b5581..92f562960b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/upload_pack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-ssh/upload_pack_test.go @@ -1,20 +1,21 @@ +//go:build !gitaly_test_sha256 + package main import ( "bytes" "fmt" "os" - "path/filepath" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/encoding/protojson" ) @@ -32,11 +33,11 @@ func TestVisibilityOfHiddenRefs(t *testing.T) { _, clean := runServer(t, false, cfg, "unix", socketPath) defer clean() - _, clean = runServer(t, false, cfg, "unix", cfg.GitalyInternalSocketPath()) + _, clean = runServer(t, false, cfg, "unix", cfg.InternalSocketPath()) defer clean() // Create a keep-around ref - existingSha := "1e292f8fedd741b75372e19097c76d327140c312" + existingSha := git.ObjectID("1e292f8fedd741b75372e19097c76d327140c312") keepAroundRef := fmt.Sprintf("%s/%s", keepAroundNamespace, existingSha) gitCmdFactory := gittest.NewCommandFactory(t, cfg) @@ -85,7 +86,7 @@ func TestVisibilityOfHiddenRefs(t *testing.T) { fmt.Sprintf("GITALY_ADDRESS=unix:%s", socketPath), fmt.Sprintf("GITALY_WD=%s", wd), fmt.Sprintf("PATH=.:%s", os.Getenv("PATH")), - fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", filepath.Join(cfg.BinDir, "gitaly-ssh")), + fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", cfg.BinaryPath("gitaly-ssh")), } stdout := &bytes.Buffer{} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main.go index 2ce2037c46..ff1342bff4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main.go @@ -12,10 +12,10 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/ps" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/ps" "golang.org/x/sys/unix" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main_test.go index bc4dad609a..5a78f90a19 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-wrapper/main_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/main_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -13,9 +15,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) // TestStolenPid tests for regressions in https://gitlab.com/gitlab-org/gitaly/issues/1661 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/testhelper_test.go index 64d8edae54..6b4c7f0f6a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly-ssh/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-wrapper/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package main import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check.go new file mode 100644 index 0000000000..00dcb7603f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" +) + +func execCheck() { + logrus.SetLevel(logrus.ErrorLevel) + + checkCmd := flag.NewFlagSet("check", flag.ExitOnError) + checkCmd.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %v check \n", os.Args[0]) + checkCmd.PrintDefaults() + } + + _ = checkCmd.Parse(os.Args[2:]) + + if checkCmd.NArg() != 1 || checkCmd.Arg(0) == "" { + fmt.Fprintf(os.Stderr, "error: invalid argument(s)") + checkCmd.Usage() + os.Exit(2) + } + + configPath := checkCmd.Arg(0) + + fmt.Print("Checking GitLab API access: ") + info, err := checkAPI(configPath) + if err != nil { + fmt.Println("FAILED") + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + fmt.Println("OK") + fmt.Printf("GitLab version: %s\n", info.Version) + fmt.Printf("GitLab revision: %s\n", info.Revision) + fmt.Printf("GitLab Api version: %s\n", info.APIVersion) + fmt.Printf("Redis reachable for GitLab: %t\n", info.RedisReachable) + fmt.Println("OK") + + os.Exit(0) +} + +func checkAPI(configPath string) (*gitlab.CheckInfo, error) { + cfg, err := loadConfig(configPath) + if err != nil { + return nil, fmt.Errorf("load config: config_path %q: %w", configPath, err) + } + + gitlabAPI, err := gitlab.NewHTTPClient(logrus.New(), cfg.Gitlab, cfg.TLS, prometheus.Config{}) + if err != nil { + return nil, err + } + + gitCmdFactory, cleanup, err := git.NewExecCommandFactory(cfg) + if err != nil { + return nil, err + } + defer cleanup() + + return hook.NewManager(cfg, config.NewLocator(cfg), gitCmdFactory, nil, gitlabAPI).Check(context.Background()) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check_test.go new file mode 100644 index 0000000000..19f5a3ea16 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/check_test.go @@ -0,0 +1,119 @@ +package main + +import ( + "bytes" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/pelletier/go-toml/v2" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func TestCheckOK(t *testing.T) { + user, password := "user123", "password321" + + c := gitlab.TestServerOptions{ + User: user, + Password: password, + SecretToken: "", + GLRepository: "", + Changes: "", + PostReceiveCounterDecreased: false, + Protocol: "ssh", + } + serverURL, cleanup := gitlab.NewTestServer(t, c) + defer cleanup() + + cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ + Gitlab: config.Gitlab{ + URL: serverURL, + HTTPSettings: config.HTTPSettings{ + User: user, + Password: password, + }, + SecretFile: gitlab.WriteShellSecretFile(t, testhelper.TempDir(t), "the secret"), + }, + })) + testcfg.BuildGitaly(t, cfg) + + configPath := writeTemporaryGitalyConfigFile(t, cfg) + + cmd := exec.Command(cfg.BinaryPath("gitaly"), "check", configPath) + + var stderr, stdout bytes.Buffer + cmd.Stderr = &stderr + cmd.Stdout = &stdout + + err := cmd.Run() + require.NoError(t, err) + require.Empty(t, stderr.String()) + + output := stdout.String() + require.Contains(t, output, "Checking GitLab API access: OK") + require.Contains(t, output, "Redis reachable for GitLab: true") +} + +func TestCheckBadCreds(t *testing.T) { + user, password := "user123", "password321" + + c := gitlab.TestServerOptions{ + User: user, + Password: password, + SecretToken: "", + GLRepository: "", + Changes: "", + PostReceiveCounterDecreased: false, + Protocol: "ssh", + GitPushOptions: nil, + } + serverURL, cleanup := gitlab.NewTestServer(t, c) + defer cleanup() + + cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ + Gitlab: config.Gitlab{ + URL: serverURL, + HTTPSettings: config.HTTPSettings{ + User: "wrong", + Password: password, + }, + SecretFile: gitlab.WriteShellSecretFile(t, testhelper.TempDir(t), "the secret"), + }, + })) + testcfg.BuildGitaly(t, cfg) + + configPath := writeTemporaryGitalyConfigFile(t, cfg) + + cmd := exec.Command(cfg.BinaryPath("gitaly"), "check", configPath) + + var stderr, stdout bytes.Buffer + cmd.Stderr = &stderr + cmd.Stdout = &stdout + + require.Error(t, cmd.Run()) + require.Contains(t, stderr.String(), "HTTP GET to GitLab endpoint /check failed: authorization failed") + require.Regexp(t, `Checking GitLab API access: .* level=error msg="Internal API error" .* error="authorization failed" method=GET status=401 url="http://127.0.0.1:[0-9]+/api/v4/internal/check"\nFAIL`, stdout.String()) +} + +// writeTemporaryGitalyConfigFile writes the given Gitaly configuration into a temporary file and +// returns its path. +func writeTemporaryGitalyConfigFile(tb testing.TB, cfg config.Cfg) string { + tb.Helper() + + path := filepath.Join(testhelper.TempDir(tb), "config.toml") + + contents, err := toml.Marshal(cfg) + require.NoError(tb, err) + require.NoError(tb, os.WriteFile(path, contents, 0o644)) + + return path +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/main.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/main.go index b0c1240384..e1097b8666 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/gitaly/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly/main.go @@ -11,39 +11,41 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - "gitlab.com/gitlab-org/gitaly/v14/internal/boring" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - glog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/streamcache" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + glog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/streamcache" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/monitoring" "gitlab.com/gitlab-org/labkit/tracing" "google.golang.org/grpc" @@ -72,11 +74,17 @@ func loadConfig(configPath string) (config.Cfg, error) { func flagUsage() { fmt.Println(version.GetVersionString()) - fmt.Printf("Usage: %v [OPTIONS] configfile\n", os.Args[0]) + fmt.Printf("Usage: %v [command] [options] \n", os.Args[0]) flag.PrintDefaults() + fmt.Printf("\nThe commands are:\n\n\tcheck\tchecks accessability of internal Rails API\n") } func main() { + // If invoked with subcommand check + if len(os.Args) > 1 && os.Args[1] == "check" { + execCheck() + } + flag.Usage = flagUsage flag.Parse() @@ -91,15 +99,20 @@ func main() { os.Exit(2) } - log.Info("Starting Gitaly", "version", version.GetVersionString()) - boring.CheckBoring() + log.Infof("Starting %s", version.GetVersionString()) + fips.Check() cfg, err := configure(flag.Arg(0)) if err != nil { log.Fatal(err) } - log.WithError(run(cfg)).Error("shutting down") - log.Info("Gitaly stopped") + + if err := run(cfg); err != nil { + log.WithError(err).Error("Gitaly shutdown") + os.Exit(1) + } + + log.Info("Gitaly shutdown") } func configure(configPath string) (config.Cfg, error) { @@ -110,10 +123,6 @@ func configure(configPath string) (config.Cfg, error) { glog.Configure(glog.Loggers, cfg.Logging.Format, cfg.Logging.Level) - if err := cgroups.NewManager(cfg.Cgroups).Setup(); err != nil { - return config.Cfg{}, fmt.Errorf("failed setting up cgroups: %w", err) - } - sentry.ConfigureSentry(version.GetVersion(), sentry.Config(cfg.Logging.Sentry)) cfg.Prometheus.Configure() tracing.Initialize(tracing.WithServiceName("gitaly")) @@ -136,12 +145,45 @@ func run(cfg config.Cfg) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + if cfg.RuntimeDir != "" { + if err := config.PruneOldGitalyProcessDirectories(log.StandardLogger(), cfg.RuntimeDir); err != nil { + return fmt.Errorf("prune runtime directories: %w", err) + } + } + + runtimeDir, err := config.SetupRuntimeDirectory(cfg, os.Getpid()) + if err != nil { + return fmt.Errorf("setup runtime directory: %w", err) + } + cfg.RuntimeDir = runtimeDir + + // When cgroups are configured, we create a directory structure each + // time a gitaly process is spawned. Look through the hierarchy root + // to find any cgroup directories that belong to old gitaly processes + // and remove them. + cgroups.PruneOldCgroups(cfg.Cgroups, log.StandardLogger()) + cgroupMgr := cgroups.NewManager(cfg.Cgroups, os.Getpid()) + + if err := cgroupMgr.Setup(); err != nil { + return fmt.Errorf("failed setting up cgroups: %w", err) + } + + defer func() { + if err := cgroupMgr.Cleanup(); err != nil { + log.WithError(err).Warn("error cleaning up cgroups") + } + }() + defer func() { if err := os.RemoveAll(cfg.RuntimeDir); err != nil { log.Warn("could not clean up runtime dir") } }() + if err := gitaly.UnpackAuxiliaryBinaries(cfg.RuntimeDir); err != nil { + return fmt.Errorf("unpack auxiliary binaries: %w", err) + } + b, err := bootstrap.New(promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_connections_total", @@ -205,7 +247,11 @@ func run(cfg config.Cfg) error { conns := client.NewPoolWithOptions( client.WithDialer(client.HealthCheckDialer(client.DialContext)), - client.WithDialOptions(client.FailOnNonTempDialError()...), + client.WithDialOptions(append( + client.FailOnNonTempDialError(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor())..., + ), ) defer conns.Close() @@ -257,10 +303,12 @@ func run(cfg config.Cfg) error { defer rubySrv.Stop() streamCache := streamcache.New(cfg.PackObjectsCache, glog.Default()) + concurrencyTracker := hook.NewConcurrencyTracker() + prometheus.MustRegister(concurrencyTracker) for _, c := range []starter.Config{ {Name: starter.Unix, Addr: cfg.SocketPath, HandoverOnUpgrade: true}, - {Name: starter.Unix, Addr: cfg.GitalyInternalSocketPath(), HandoverOnUpgrade: false}, + {Name: starter.Unix, Addr: cfg.InternalSocketPath(), HandoverOnUpgrade: false}, {Name: starter.TCP, Addr: cfg.ListenAddr, HandoverOnUpgrade: true}, {Name: starter.TLS, Addr: cfg.TLSListenAddr, HandoverOnUpgrade: true}, } { @@ -282,20 +330,21 @@ func run(cfg config.Cfg) error { } setup.RegisterAll(srv, &service.Dependencies{ - Cfg: cfg, - RubyServer: rubySrv, - GitalyHookManager: hookManager, - TransactionManager: transactionManager, - StorageLocator: locator, - ClientPool: conns, - GitCmdFactory: gitCmdFactory, - Linguist: ling, - CatfileCache: catfileCache, - DiskCache: diskCache, - PackObjectsCache: streamCache, - Git2goExecutor: git2goExecutor, - UpdaterWithHooks: updaterWithHooks, - HousekeepingManager: housekeepingManager, + Cfg: cfg, + RubyServer: rubySrv, + GitalyHookManager: hookManager, + TransactionManager: transactionManager, + StorageLocator: locator, + ClientPool: conns, + GitCmdFactory: gitCmdFactory, + Linguist: ling, + CatfileCache: catfileCache, + DiskCache: diskCache, + PackObjectsCache: streamCache, + PackObjectsConcurrencyTracker: concurrencyTracker, + Git2goExecutor: git2goExecutor, + UpdaterWithHooks: updaterWithHooks, + HousekeepingManager: housekeepingManager, }) b.RegisterStarter(starter.New(c, srv)) } @@ -349,12 +398,6 @@ func run(cfg config.Cfg) error { } defer shutdownWorkers() - defer func() { - if err := cgroups.NewManager(cfg.Cgroups).Cleanup(); err != nil { - log.WithError(err).Warn("error cleaning up cgroups") - } - }() - gracefulStopTicker := helper.NewTimerTicker(cfg.GracefulRestartTimeout.Duration()) defer gracefulStopTicker.Stop() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main.go index ab28bdea0f..76cb2071ba 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main.go @@ -72,26 +72,27 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" "gitlab.com/gitlab-org/labkit/monitoring" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -357,7 +358,8 @@ func run( db, nodeSet.Connections(), hm, - conf.BackgroundVerification.VerificationInterval, + conf.BackgroundVerification.VerificationInterval.Duration(), + conf.BackgroundVerification.DeleteInvalidRecords, ) promreg.MustRegister(verifier) @@ -434,21 +436,22 @@ func run( protoregistry.GitalyProtoPreregistered, nodeSet.Connections(), primaryGetter, + service.AllChecks(), ) ) metricsCollectors = append(metricsCollectors, transactionManager, coordinator, repl) if db != nil { dbMetricCollectors := []prometheus.Collector{ - datastore.NewRepositoryStoreCollector(logger, conf.VirtualStorageNames(), db, conf.Prometheus.ScrapeTimeout), - datastore.NewQueueDepthCollector(logger, db, conf.Prometheus.ScrapeTimeout), + datastore.NewRepositoryStoreCollector(logger, conf.VirtualStorageNames(), db, conf.Prometheus.ScrapeTimeout.Duration()), + datastore.NewQueueDepthCollector(logger, db, conf.Prometheus.ScrapeTimeout.Duration()), } if conf.BackgroundVerification.VerificationInterval > 0 { dbMetricCollectors = append(dbMetricCollectors, datastore.NewVerificationQueueDepthCollector( logger, db, - conf.Prometheus.ScrapeTimeout, - conf.BackgroundVerification.VerificationInterval, + conf.Prometheus.ScrapeTimeout.Duration(), + conf.BackgroundVerification.VerificationInterval.Duration(), conf.StorageNames(), )) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main_test.go index 082b7efe36..3879a54374 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/main_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/main_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -9,12 +11,12 @@ import ( dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd.go index e62ead65c3..53df26eeed 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd.go @@ -10,12 +10,12 @@ import ( "os/signal" "time" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" "google.golang.org/grpc" ) @@ -42,17 +42,12 @@ var subcommands = map[string]subcmd{ setReplicationFactorCmdName: newSetReplicatioFactorSubcommand(os.Stdout), removeRepositoryCmdName: newRemoveRepository(logger, os.Stdout), trackRepositoryCmdName: newTrackRepository(logger, os.Stdout), + trackRepositoriesCmdName: newTrackRepositories(logger, os.Stdout), listUntrackedRepositoriesName: newListUntrackedRepositories(logger, os.Stdout), - checkCmdName: newCheckSubcommand( - os.Stdout, - praefect.NewPraefectMigrationCheck, - praefect.NewGitalyNodeConnectivityCheck, - praefect.NewPostgresReadWriteCheck, - praefect.NewUnavailableReposCheck, - praefect.NewClockSyncCheck(helper.CheckClockSync), - ), - metadataCmdName: newMetadataSubcommand(os.Stdout), - verifyCmdName: newVerifySubcommand(os.Stdout), + checkCmdName: newCheckSubcommand(os.Stdout, service.AllChecks()...), + metadataCmdName: newMetadataSubcommand(os.Stdout), + verifyCmdName: newVerifySubcommand(os.Stdout), + listStoragesCmdName: newListStorages(os.Stdout), } // subCommand returns an exit code, to be fed into os.Exit. @@ -128,6 +123,8 @@ func subCmdDial(ctx context.Context, addr, token string, timeout time.Duration, opts = append(opts, grpc.WithBlock(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor(), ) if len(token) > 0 { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss.go index 944c55e895..026b8e5658 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss.go @@ -5,8 +5,8 @@ import ( "flag" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss_test.go index 00d757ab94..ea22e19d3a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_accept_dataloss_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_accept_dataloss_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -5,12 +7,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestAcceptDatalossSubcommand(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check.go index 5755b20084..7e69140d98 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check.go @@ -8,8 +8,8 @@ import ( "io" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" ) const ( @@ -19,10 +19,10 @@ const ( type checkSubcommand struct { w io.Writer quiet bool - checkFuncs []praefect.CheckFunc + checkFuncs []service.CheckFunc } -func newCheckSubcommand(writer io.Writer, checkFuncs ...praefect.CheckFunc) *checkSubcommand { +func newCheckSubcommand(writer io.Writer, checkFuncs ...service.CheckFunc) *checkSubcommand { return &checkSubcommand{ w: writer, checkFuncs: checkFuncs, @@ -43,8 +43,8 @@ func (cmd *checkSubcommand) FlagSet() *flag.FlagSet { var errFatalChecksFailed = errors.New("checks failed") -func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error { - var allChecks []*praefect.Check +func (cmd *checkSubcommand) Exec(_ *flag.FlagSet, cfg config.Config) error { + var allChecks []*service.Check for _, checkFunc := range cmd.checkFuncs { allChecks = append(allChecks, checkFunc(cfg, cmd.w, cmd.quiet)) } @@ -60,7 +60,7 @@ func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error { if err := check.Run(ctx); err != nil { failedChecks++ - if check.Severity == praefect.Fatal { + if check.Severity == service.Fatal { passed = false } fmt.Fprintf(cmd.w, "Failed (%s) error: %s\n", check.Severity, err.Error()) @@ -85,7 +85,7 @@ func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error { return nil } -func (cmd *checkSubcommand) printCheckDetails(check *praefect.Check) { +func (cmd *checkSubcommand) printCheckDetails(check *service.Check) { if cmd.quiet { fmt.Fprintf(cmd.w, "Checking %s...", check.Name) return diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check_test.go index ef6d489d56..3df258a472 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_check_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_check_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -9,8 +11,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" ) func TestCheckSubcommand_Exec(t *testing.T) { @@ -18,36 +20,36 @@ func TestCheckSubcommand_Exec(t *testing.T) { testCases := []struct { desc string - checks []praefect.CheckFunc + checks []service.CheckFunc expectedQuietOutput string expectedOutput string expectedError error }{ { desc: "all checks pass", - checks: []praefect.CheckFunc{ - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + checks: []service.CheckFunc{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 1", Description: "checks a", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 2", Description: "checks b", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 3", Description: "checks c", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, }, @@ -70,29 +72,29 @@ All checks passed. }, { desc: "a fatal check fails", - checks: []praefect.CheckFunc{ - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + checks: []service.CheckFunc{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 1", Description: "checks a", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 2", Description: "checks b", Run: func(ctx context.Context) error { return errors.New("i failed") }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 3", Description: "checks c", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, }, @@ -115,29 +117,29 @@ Checking check 3...Passed }, { desc: "only warning checks fail", - checks: []praefect.CheckFunc{ - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + checks: []service.CheckFunc{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 1", Description: "checks a", Run: func(ctx context.Context) error { return nil }, - Severity: praefect.Fatal, + Severity: service.Fatal, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 2", Description: "checks b", Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") }, - Severity: praefect.Warning, + Severity: service.Warning, } }, - func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check { - return &praefect.Check{ + func(cfg config.Config, w io.Writer, quiet bool) *service.Check { + return &service.Check{ Name: "check 3", Description: "checks c", Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") }, - Severity: praefect.Warning, + Severity: service.Warning, } }, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss.go index 5eb88f4e68..45d16328f2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss.go @@ -10,8 +10,8 @@ import ( "sort" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const datalossCmdName = "dataloss" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss_test.go index 949c7919b0..e9d73b1102 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dataloss_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dataloss_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -5,12 +7,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes.go index 71054d6ada..cc0bf31c0d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes.go @@ -6,8 +6,8 @@ import ( "io" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" ) const dialNodesCmdName = "dial-nodes" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes_test.go index fd2877f605..b1a2dc0a34 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_dial_nodes_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_dial_nodes_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -9,8 +11,8 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type mockServerService struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages.go new file mode 100644 index 0000000000..105454336d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages.go @@ -0,0 +1,91 @@ +package main + +import ( + "flag" + "fmt" + "io" + + "github.com/olekukonko/tablewriter" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" +) + +const ( + listStoragesCmdName = "list-storages" +) + +type listStorages struct { + virtualStorage string + w io.Writer +} + +func newListStorages(w io.Writer) *listStorages { + return &listStorages{w: w} +} + +func (cmd *listStorages) FlagSet() *flag.FlagSet { + fs := flag.NewFlagSet(listStoragesCmdName, flag.ExitOnError) + fs.StringVar( + &cmd.virtualStorage, + paramVirtualStorage, + "", + "name of the virtual storage to list storages for", + ) + fs.Usage = func() { + printfErr("Description:\n" + + " This command lists virtual storages and their associated storages.\n" + + " Passing a virtual-storage argument will print out the storage associated with\n" + + " that particular virtual storage.\n") + fs.PrintDefaults() + } + + return fs +} + +func (cmd listStorages) Exec(flags *flag.FlagSet, cfg config.Config) error { + if flags.NArg() > 0 { + return unexpectedPositionalArgsError{Command: flags.Name()} + } + + table := tablewriter.NewWriter(cmd.w) + table.SetHeader([]string{"VIRTUAL_STORAGE", "NODE", "ADDRESS"}) + table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) + table.SetAutoFormatHeaders(false) + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetCenterSeparator("") + table.SetColumnSeparator("") + table.SetRowSeparator("") + table.SetHeaderLine(false) + table.SetBorder(false) + table.SetTablePadding("\t") // pad with tabs + table.SetNoWhiteSpace(true) + + if cmd.virtualStorage != "" { + for _, virtualStorage := range cfg.VirtualStorages { + if virtualStorage.Name != cmd.virtualStorage { + continue + } + + for _, node := range virtualStorage.Nodes { + table.Append([]string{virtualStorage.Name, node.Storage, node.Address}) + } + + table.Render() + + return nil + } + + fmt.Fprintf(cmd.w, "No virtual storages named %s.\n", cmd.virtualStorage) + + return nil + } + + for _, virtualStorage := range cfg.VirtualStorages { + for _, node := range virtualStorage.Nodes { + table.Append([]string{virtualStorage.Name, node.Storage, node.Address}) + } + } + + table.Render() + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages_test.go new file mode 100644 index 0000000000..068cd27e6d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_storages_test.go @@ -0,0 +1,188 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "bytes" + "testing" + + "github.com/olekukonko/tablewriter" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" +) + +func TestListStorages_FlagSet(t *testing.T) { + t.Parallel() + cmd := &listStorages{} + fs := cmd.FlagSet() + require.NoError(t, fs.Parse([]string{"--virtual-storage", "vs"})) + require.Equal(t, "vs", cmd.virtualStorage) +} + +func TestListStorages_Exec(t *testing.T) { + t.Parallel() + + testCases := []struct { + desc string + virtualStorages []*config.VirtualStorage + args []string + expectedOutput func(*tablewriter.Table) + }{ + { + desc: "one virtual storage", + virtualStorages: []*config.VirtualStorage{ + { + Name: "vs-1", + Nodes: []*config.Node{ + { + Storage: "storage-1", + Address: "tcp://1.2.3.4", + }, + { + Storage: "storage-2", + Address: "tcp://4.3.2.1", + }, + }, + }, + }, + args: []string{}, + expectedOutput: func(t *tablewriter.Table) { + t.Append([]string{"vs-1", "storage-1", "tcp://1.2.3.4"}) + t.Append([]string{"vs-1", "storage-2", "tcp://4.3.2.1"}) + }, + }, + { + desc: "multiple virtual storages but only show one", + virtualStorages: []*config.VirtualStorage{ + { + Name: "vs-1", + Nodes: []*config.Node{ + { + Storage: "storage-1", + Address: "tcp://1.2.3.4", + }, + { + Storage: "storage-2", + Address: "tcp://4.3.2.1", + }, + }, + }, + { + Name: "vs-2", + Nodes: []*config.Node{ + { + Storage: "storage-3", + Address: "tcp://1.1.3.4", + }, + { + Storage: "storage-4", + Address: "tcp://1.3.2.1", + }, + }, + }, + { + Name: "vs-3", + Nodes: []*config.Node{ + { + Storage: "storage-5", + Address: "tcp://2.1.3.4", + }, + { + Storage: "storage-6", + Address: "tcp://2.3.2.1", + }, + }, + }, + }, + args: []string{"-virtual-storage", "vs-2"}, + expectedOutput: func(t *tablewriter.Table) { + t.Append([]string{"vs-2", "storage-3", "tcp://1.1.3.4"}) + t.Append([]string{"vs-2", "storage-4", "tcp://1.3.2.1"}) + }, + }, + { + desc: "one virtual storage with virtual storage arg", + virtualStorages: []*config.VirtualStorage{ + { + Name: "vs-1", + Nodes: []*config.Node{ + { + Storage: "storage-1", + Address: "tcp://1.2.3.4", + }, + { + Storage: "storage-2", + Address: "tcp://4.3.2.1", + }, + }, + }, + }, + args: []string{"-virtual-storage", "vs-1"}, + expectedOutput: func(t *tablewriter.Table) { + t.Append([]string{"vs-1", "storage-1", "tcp://1.2.3.4"}) + t.Append([]string{"vs-1", "storage-2", "tcp://4.3.2.1"}) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + var expectedOutput bytes.Buffer + table := tablewriter.NewWriter(&expectedOutput) + table.SetHeader([]string{"VIRTUAL_STORAGE", "NODE", "ADDRESS"}) + table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) + table.SetAutoFormatHeaders(false) + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetCenterSeparator("") + table.SetColumnSeparator("") + table.SetRowSeparator("") + table.SetHeaderLine(false) + table.SetBorder(false) + table.SetTablePadding("\t") // pad with tabs + table.SetNoWhiteSpace(true) + tc.expectedOutput(table) + table.Render() + + var out bytes.Buffer + cmd := &listStorages{ + w: &out, + } + + fs := cmd.FlagSet() + require.NoError(t, fs.Parse(tc.args)) + require.NoError(t, cmd.Exec(fs, config.Config{ + VirtualStorages: tc.virtualStorages, + })) + assert.Equal(t, expectedOutput.String(), out.String()) + }) + } + + t.Run("virtual storage arg matches no virtual storages", func(t *testing.T) { + var out bytes.Buffer + cmd := &listStorages{ + w: &out, + } + + fs := cmd.FlagSet() + require.NoError(t, fs.Parse([]string{"-virtual-storage", "vs-2"})) + require.NoError(t, cmd.Exec(fs, config.Config{ + VirtualStorages: []*config.VirtualStorage{ + { + Name: "vs-1", + Nodes: []*config.Node{ + { + Storage: "storage-1", + Address: "tcp://1.2.3.4", + }, + { + Storage: "storage-2", + Address: "tcp://4.3.2.1", + }, + }, + }, + }, + })) + assert.Equal(t, "No virtual storages named vs-2.\n", out.String()) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories.go index dd6563f244..201af51c36 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories.go @@ -10,11 +10,11 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" ) @@ -68,7 +68,7 @@ func (cmd listUntrackedRepositories) Exec(flags *flag.FlagSet, cfg config.Config ctx = metadata.AppendToOutgoingContext(ctx, "client_name", listUntrackedRepositoriesName) logger := cmd.logger.WithField("correlation_id", correlation.ExtractFromContext(ctx)) - logger.Debugf("starting %s command", cmd.FlagSet().Name()) + logger.Debugf("starting %s command", flags.Name()) logger.Debug("dialing to gitaly nodes...") nodeSet, err := dialGitalyStorages(ctx, cfg, defaultDialTimeout) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories_test.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories_test.go index aa6fb88481..71180d8563 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_list_untracked_repositories_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_list_untracked_repositories_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -10,15 +12,15 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestListUntrackedRepositories_FlagSet(t *testing.T) { @@ -90,21 +92,27 @@ func TestListUntrackedRepositories_Exec(t *testing.T) { out := &bytes.Buffer{} cmd := newListUntrackedRepositories(testhelper.NewDiscardingLogger(t), out) fs := cmd.FlagSet() - require.NoError(t, fs.Parse([]string{})) + require.NoError(t, fs.Parse([]string{"-older-than", "4h"})) // Repositories not managed by praefect. - repo1, repo1Path := gittest.InitRepo(t, g1Cfg, g1Cfg.Storages[0]) - repo2, repo2Path := gittest.InitRepo(t, g1Cfg, g1Cfg.Storages[0]) - _, _ = gittest.InitRepo(t, g2Cfg, g2Cfg.Storages[0]) + repo1, repo1Path := gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo2, repo2Path := gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + _, _ = gittest.CreateRepository(ctx, t, g2Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) require.NoError(t, os.Chtimes( repo1Path, - time.Now().Add(-(6*time.Hour+1*time.Second)), - time.Now().Add(-(6*time.Hour+1*time.Second)))) + time.Now().Add(-(4*time.Hour+1*time.Second)), + time.Now().Add(-(4*time.Hour+1*time.Second)))) require.NoError(t, os.Chtimes( repo2Path, - time.Now().Add(-(6*time.Hour+1*time.Second)), - time.Now().Add(-(6*time.Hour+1*time.Second)))) + time.Now().Add(-(4*time.Hour+1*time.Second)), + time.Now().Add(-(4*time.Hour+1*time.Second)))) require.NoError(t, cmd.Exec(fs, conf)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata.go index 3cc9b8292c..5b61dd5135 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata.go @@ -7,8 +7,8 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const metadataCmdName = "metadata" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata_test.go index dbca8c27c1..e70f1cb28f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_metadata_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_metadata_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -8,11 +10,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository.go index 49b049615c..9c966de6d3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository.go @@ -7,24 +7,23 @@ import ( "flag" "fmt" "io" - "strings" "sync" "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" ) const ( removeRepositoryCmdName = "remove-repository" paramApply = "apply" + paramDBOnly = "db-only" ) type writer struct { @@ -43,6 +42,7 @@ type removeRepository struct { virtualStorage string relativePath string apply bool + dbOnly bool dialTimeout time.Duration w io.Writer } @@ -55,21 +55,20 @@ func (cmd *removeRepository) FlagSet() *flag.FlagSet { fs := flag.NewFlagSet(removeRepositoryCmdName, flag.ExitOnError) fs.StringVar(&cmd.virtualStorage, paramVirtualStorage, "", "name of the repository's virtual storage") fs.BoolVar(&cmd.apply, paramApply, false, "physically remove the repository from disk and the database") + fs.BoolVar(&cmd.dbOnly, paramDBOnly, false, "remove the repository records from the database only") fs.StringVar(&cmd.relativePath, paramRelativePath, "", "relative path to the repository") fs.Usage = func() { printfErr("Description:\n" + " This command removes all state associated with a given repository from the Gitaly Cluster.\n" + " This includes both on-disk repositories on all relevant Gitaly nodes as well as any potential\n" + - " database state as tracked by Praefect.\n" + - " Runs in dry-run mode by default and lists the gitaly nodes from which the repository will be removed from " + + " database state as tracked by Praefect, or optionally only database state.\n" + + " Runs in dry-run mode by default checks whether the repository exists" + " without actually removing it from the database and disk.\n" + " When -apply is used, the repository will be removed from the database as well as\n" + - " the individual gitaly nodes on which they exist.\n") + " the individual gitaly nodes on which they exist.\n" + + " When -apply and -db-only are used, the repository will be removed from the\n" + + " database but left in-place on the gitaly nodes.") fs.PrintDefaults() - printfErr("NOTE:\n" + - " It may happen that parts of the repository continue to exist after this command, either because\n" + - " of an error that happened during deletion or because of in-flight RPC calls targeting the repository.\n" + - " It is safe and recommended to re-run this command in such a case.\n") } return fs } @@ -116,121 +115,57 @@ func (cmd *removeRepository) exec(ctx context.Context, logger logrus.FieldLogger if exists { fmt.Fprintln(cmd.w, "Repository found in the database.") } else { - fmt.Fprintln(cmd.w, "Repository is not being tracked in Praefect.") + return errors.New("repository is not being tracked in Praefect") } } - storagesOnDisk, err := cmd.getStoragesFromNodes(ctx, cfg) - if err != nil { - return err - } - - if len(storagesOnDisk) == 0 { - fmt.Fprintln(cmd.w, "Repository not found on any gitaly nodes.") - } else { - fmt.Fprintf(cmd.w, "Repository found on the following gitaly nodes: %s.\n", strings.Join(storagesOnDisk, ", ")) - } - if !cmd.apply { - fmt.Fprintln(cmd.w, "Re-run the command with -apply to remove repositories from the database and disk.") + fmt.Fprintln(cmd.w, "Re-run the command with -apply to remove repositories from the database"+ + " and disk or -apply and -db-only to remove from database only.") + return nil + } + + ticker := helper.NewTimerTicker(time.Second) + defer ticker.Stop() + + if cmd.dbOnly { + fmt.Fprintf(cmd.w, "Attempting to remove %s from the database...\n", cmd.relativePath) + if _, _, err := rs.DeleteRepository(ctx, cmd.virtualStorage, cmd.relativePath); err != nil { + return fmt.Errorf("remove repository from database: %w", err) + } + fmt.Fprintln(cmd.w, "Repository removal from database completed.") + + if err := cmd.removeReplicationEvents(ctx, logger, db, ticker); err != nil { + return fmt.Errorf("remove scheduled replication events: %w", err) + } return nil } fmt.Fprintf(cmd.w, "Attempting to remove %s from the database, and delete it from all gitaly nodes...\n", cmd.relativePath) - fmt.Fprintln(cmd.w, "Removing repository from the database...") - removed, err := cmd.removeRepositoryFromDatabase(ctx, db) + addr, err := getNodeAddress(cfg) if err != nil { - return fmt.Errorf("remove repository info from praefect database: %w", err) + return fmt.Errorf("get node address: %w", err) } - if !removed { - fmt.Fprintln(cmd.w, "The database has no information about this repository.") - } else { - fmt.Fprintln(cmd.w, "Removed repository metadata from the database.") + _, err = cmd.removeRepository(ctx, &gitalypb.Repository{ + StorageName: cmd.virtualStorage, + RelativePath: cmd.relativePath, + }, addr, cfg.Auth.Token) + if err != nil { + return fmt.Errorf("repository removal failed: %w", err) } + fmt.Fprintln(cmd.w, "Repository removal completed.") + fmt.Fprintln(cmd.w, "Removing replication events...") - ticker := helper.NewTimerTicker(time.Second) - defer ticker.Stop() if err := cmd.removeReplicationEvents(ctx, logger, db, ticker); err != nil { return fmt.Errorf("remove scheduled replication events: %w", err) } fmt.Fprintln(cmd.w, "Replication event removal completed.") - - // We should try to remove repository from each of gitaly nodes. - fmt.Fprintln(cmd.w, "Removing repository directly from gitaly nodes...") - cmd.removeRepositoryForEachGitaly(ctx, cfg, logger) - fmt.Fprintln(cmd.w, "Finished removing repository from gitaly nodes.") - return nil } -// getStoragesFromNodes looks on disk to finds the storages this repository exists for -func (cmd *removeRepository) getStoragesFromNodes(ctx context.Context, cfg config.Config) ([]string, error) { - var storages []string - for _, vs := range cfg.VirtualStorages { - if vs.Name != cmd.virtualStorage { - continue - } - - storages = make([]string, len(vs.Nodes)) - var wg sync.WaitGroup - - for i := 0; i < len(vs.Nodes); i++ { - wg.Add(1) - go func(node *config.Node, i int) { - defer wg.Done() - repo := &gitalypb.Repository{ - StorageName: node.Storage, - RelativePath: cmd.relativePath, - } - exists, err := repositoryExists(ctx, repo, node.Address, node.Token) - if err != nil { - cmd.logger.WithError(err).Errorf("checking if repository exists on %q", node.Storage) - } - if exists { - storages[i] = node.Storage - } - }(vs.Nodes[i], i) - } - - wg.Wait() - break - } - - var storagesFound []string - for _, storage := range storages { - if storage != "" { - storagesFound = append(storagesFound, storage) - } - } - - return storagesFound, nil -} - -func (cmd *removeRepository) removeRepositoryFromDatabase(ctx context.Context, db *sql.DB) (bool, error) { - var removed bool - if err := db.QueryRowContext( - ctx, - `WITH remove_storages_info AS ( - DELETE FROM storage_repositories - WHERE virtual_storage = $1 AND relative_path = $2 - ) - DELETE FROM repositories - WHERE virtual_storage = $1 AND relative_path = $2 - RETURNING TRUE`, - cmd.virtualStorage, - cmd.relativePath, - ).Scan(&removed); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return false, nil - } - return false, fmt.Errorf("query row: %w", err) - } - return removed, nil -} - func (cmd *removeRepository) removeRepository(ctx context.Context, repo *gitalypb.Repository, addr, token string) (bool, error) { conn, err := subCmdDial(ctx, addr, token, cmd.dialTimeout) if err != nil { @@ -241,10 +176,7 @@ func (cmd *removeRepository) removeRepository(ctx context.Context, repo *gitalyp ctx = metadata.AppendToOutgoingContext(ctx, "client_name", removeRepositoryCmdName) repositoryClient := gitalypb.NewRepositoryServiceClient(conn) if _, err := repositoryClient.RemoveRepository(ctx, &gitalypb.RemoveRepositoryRequest{Repository: repo}); err != nil { - if _, ok := status.FromError(err); !ok { - return false, fmt.Errorf("RemoveRepository: %w", err) - } - return false, nil + return false, err } return true, nil } @@ -291,43 +223,3 @@ func (cmd *removeRepository) removeReplicationEvents(ctx context.Context, logger } return nil } - -func (cmd *removeRepository) removeNode( - ctx context.Context, - logger logrus.FieldLogger, - node *config.Node, -) { - logger.Debugf("remove repository with gitaly %q at %q", node.Storage, node.Address) - repo := &gitalypb.Repository{ - StorageName: node.Storage, - RelativePath: cmd.relativePath, - } - removed, err := cmd.removeRepository(ctx, repo, node.Address, node.Token) - if err != nil { - logger.WithError(err).Warnf("repository removal failed for %q", node.Storage) - } else { - if removed { - fmt.Fprintf(cmd.w, "Successfully removed %s from %s\n", cmd.relativePath, node.Storage) - } else { - fmt.Fprintf(cmd.w, "Did not remove %s from %s\n", cmd.relativePath, node.Storage) - } - } - logger.Debugf("repository removal call to gitaly %q completed", node.Storage) -} - -func (cmd *removeRepository) removeRepositoryForEachGitaly(ctx context.Context, cfg config.Config, logger logrus.FieldLogger) { - for _, vs := range cfg.VirtualStorages { - if vs.Name == cmd.virtualStorage { - var wg sync.WaitGroup - for i := 0; i < len(vs.Nodes); i++ { - wg.Add(1) - go func(i int) { - defer wg.Done() - cmd.removeNode(ctx, logger, vs.Nodes[i]) - }(i) - } - wg.Wait() - break - } - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository_test.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository_test.go index 040dd40e53..e42bde82e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_remove_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_remove_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -6,24 +8,27 @@ import ( "fmt" "os" "path/filepath" - "strings" + "sync" "testing" "time" "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gitalycfg "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestRemoveRepository_FlagSet(t *testing.T) { @@ -104,64 +109,99 @@ func TestRemoveRepository_Exec(t *testing.T) { praefectStorage := conf.VirtualStorages[0].Name + repositoryExists := func(tb testing.TB, repo *gitalypb.Repository) bool { + response, err := gitalypb.NewRepositoryServiceClient(cc).RepositoryExists(ctx, &gitalypb.RepositoryExistsRequest{ + Repository: repo, + }) + require.NoError(tb, err) + return response.GetExists() + } + t.Run("dry run", func(t *testing.T) { var out bytes.Buffer repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) + cmd := &removeRepository{ logger: testhelper.NewDiscardingLogger(t), virtualStorage: repo.StorageName, relativePath: repo.RelativePath, dialTimeout: time.Second, apply: false, + dbOnly: false, w: &writer{w: &out}, } require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) - require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, repo.RelativePath)) - require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath)) + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) assert.Contains(t, out.String(), "Repository found in the database.\n") - assert.Contains(t, out.String(), "Repository found on the following gitaly nodes:") - assert.Contains(t, out.String(), "Re-run the command with -apply to remove repositories from the database and disk.\n") - - repositoryRowExists, err := datastore.NewPostgresRepositoryStore(db, nil).RepositoryExists(ctx, cmd.virtualStorage, cmd.relativePath) - require.NoError(t, err) - require.True(t, repositoryRowExists) + assert.Contains(t, out.String(), "Re-run the command with -apply to remove repositories from the database and disk or -apply and -db-only to remove from database only.") + require.True(t, repositoryExists(t, repo)) }) t.Run("ok", func(t *testing.T) { var out bytes.Buffer repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) + cmd := &removeRepository{ logger: testhelper.NewDiscardingLogger(t), virtualStorage: repo.StorageName, relativePath: repo.RelativePath, dialTimeout: time.Second, apply: true, + dbOnly: false, w: &writer{w: &out}, } require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) - require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, repo.RelativePath)) - require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath)) + require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) assert.Contains(t, out.String(), "Repository found in the database.\n") - assert.Contains(t, out.String(), "Repository found on the following gitaly nodes:") assert.Contains(t, out.String(), fmt.Sprintf("Attempting to remove %s from the database, and delete it from all gitaly nodes...\n", repo.RelativePath)) - assert.Contains(t, out.String(), fmt.Sprintf("Successfully removed %s from", repo.RelativePath)) - assert.NotContains(t, out.String(), fmt.Sprintf("Did not remove %s from", repo.RelativePath)) + assert.Contains(t, out.String(), "Repository removal completed.") + require.False(t, repositoryExists(t, repo)) + }) - var repositoryRowExists bool - require.NoError(t, db.QueryRow( - `SELECT EXISTS(SELECT FROM repositories WHERE virtual_storage = $1 AND relative_path = $2)`, - cmd.virtualStorage, cmd.relativePath, - ).Scan(&repositoryRowExists)) - require.False(t, repositoryRowExists) + t.Run("db only", func(t *testing.T) { + var out bytes.Buffer + repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) + + cmd := &removeRepository{ + logger: testhelper.NewDiscardingLogger(t), + virtualStorage: repo.StorageName, + relativePath: repo.RelativePath, + dialTimeout: time.Second, + apply: true, + dbOnly: true, + w: &writer{w: &out}, + } + require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) + + // Repo is no longer present in the Praefect DB. + require.False(t, repositoryExists(t, repo)) + + // Repo is still present on-disk on the Gitaly nodes. + require.True(t, storage.IsGitDirectory(filepath.Join(g1Cfg.Storages[0].Path, replicaPath))) + require.True(t, storage.IsGitDirectory(filepath.Join(g2Cfg.Storages[0].Path, replicaPath))) + + assert.Contains(t, out.String(), "Repository found in the database.\n") + assert.Contains(t, out.String(), fmt.Sprintf("Attempting to remove %s from the database...\n", repo.RelativePath)) + assert.Contains(t, out.String(), "Repository removal from database completed.") }) t.Run("repository doesnt exist on one gitaly", func(t *testing.T) { var out bytes.Buffer repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) - require.NoError(t, os.RemoveAll(filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath))) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.NoError(t, os.RemoveAll(filepath.Join(g2Cfg.Storages[0].Path, replicaPath))) cmd := &removeRepository{ logger: testhelper.NewDiscardingLogger(t), @@ -169,30 +209,26 @@ func TestRemoveRepository_Exec(t *testing.T) { relativePath: repo.RelativePath, dialTimeout: time.Second, apply: true, + dbOnly: false, w: &writer{w: &out}, } require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) - require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, repo.RelativePath)) - require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath)) + require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) assert.Contains(t, out.String(), "Repository found in the database.\n") - assert.Contains(t, out.String(), "Repository found on the following gitaly nodes: gitaly-1") assert.Contains(t, out.String(), fmt.Sprintf("Attempting to remove %s from the database, and delete it from all gitaly nodes...\n", repo.RelativePath)) - assert.Contains(t, out.String(), fmt.Sprintf("Successfully removed %s from gitaly-1", repo.RelativePath)) - - var repositoryRowExists bool - require.NoError(t, db.QueryRow( - `SELECT EXISTS(SELECT FROM repositories WHERE virtual_storage = $1 AND relative_path = $2)`, - cmd.virtualStorage, cmd.relativePath, - ).Scan(&repositoryRowExists)) - require.False(t, repositoryRowExists) + assert.Contains(t, out.String(), "Repository removal completed.") + require.False(t, repositoryExists(t, repo)) }) t.Run("no info about repository on praefect", func(t *testing.T) { var out bytes.Buffer repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) + repoStore := datastore.NewPostgresRepositoryStore(db.DB, nil) - _, _, err := repoStore.DeleteRepository(ctx, repo.StorageName, repo.RelativePath) + _, _, err = repoStore.DeleteRepository(ctx, repo.StorageName, repo.RelativePath) require.NoError(t, err) cmd := &removeRepository{ @@ -201,16 +237,13 @@ func TestRemoveRepository_Exec(t *testing.T) { relativePath: repo.RelativePath, dialTimeout: time.Second, apply: true, + dbOnly: false, w: &writer{w: &out}, } - require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) - assert.Contains(t, out.String(), "Repository is not being tracked in Praefect.\n") - assert.Contains(t, out.String(), "Repository found on the following gitaly nodes:") - assert.Contains(t, out.String(), "The database has no information about this repository.\n") - require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, repo.RelativePath)) - require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath)) - - requireNoDatabaseInfo(t, db, cmd) + require.Error(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf), "repository is not being tracked in Praefect") + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) + require.False(t, repositoryExists(t, repo)) }) t.Run("one of gitalies is out of service", func(t *testing.T) { @@ -218,69 +251,42 @@ func TestRemoveRepository_Exec(t *testing.T) { repo := createRepo(t, ctx, repoClient, praefectStorage, t.Name()) g2Srv.Shutdown() - logger := testhelper.NewDiscardingLogger(t) - loggerHook := test.NewLocal(logger) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalycfg.Cfg{SocketPath: praefectServer.Address()}, repo) + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) cmd := &removeRepository{ - logger: logrus.NewEntry(logger), + logger: logrus.NewEntry(testhelper.NewDiscardingLogger(t)), virtualStorage: praefectStorage, relativePath: repo.RelativePath, dialTimeout: 100 * time.Millisecond, apply: true, + dbOnly: false, w: &writer{w: &out}, } require.NoError(t, cmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) + assert.Contains(t, out.String(), "Repository removal completed.") - var checkExistsOnNodeErrFound, removeRepoFromDiskErrFound bool - for _, entry := range loggerHook.AllEntries() { - if strings.Contains(entry.Message, `checking if repository exists on "gitaly-2"`) { - checkExistsOnNodeErrFound = true - } - - if strings.Contains(entry.Message, `repository removal failed for "gitaly-2"`) { - removeRepoFromDiskErrFound = true - } - } - require.True(t, checkExistsOnNodeErrFound) - require.True(t, removeRepoFromDiskErrFound) - - require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, repo.RelativePath)) - require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, repo.RelativePath)) - - requireNoDatabaseInfo(t, db, cmd) + require.NoDirExists(t, filepath.Join(g1Cfg.Storages[0].Path, replicaPath)) + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, replicaPath)) + require.False(t, repositoryExists(t, repo)) }) } -func requireNoDatabaseInfo(t *testing.T, db testdb.DB, cmd *removeRepository) { - t.Helper() - var repositoryRowExists bool - require.NoError(t, db.QueryRow( - `SELECT EXISTS(SELECT FROM repositories WHERE virtual_storage = $1 AND relative_path = $2)`, - cmd.virtualStorage, cmd.relativePath, - ).Scan(&repositoryRowExists)) - require.False(t, repositoryRowExists) - var storageRowExists bool - require.NoError(t, db.QueryRow( - `SELECT EXISTS(SELECT FROM storage_repositories WHERE virtual_storage = $1 AND relative_path = $2)`, - cmd.virtualStorage, cmd.relativePath, - ).Scan(&storageRowExists)) - require.False(t, storageRowExists) -} - func TestRemoveRepository_removeReplicationEvents(t *testing.T) { t.Parallel() const ( virtualStorage = "praefect" relativePath = "relative_path/to/repo.git" ) - ctx := testhelper.Context(t) + ctx := testhelper.Context(t) db := testdb.New(t) queue := datastore.NewPostgresReplicationEventQueue(db) - // Set replication event in_progress. + // Create an event that is "in-progress" to verify that it is not removed by the command. inProgressEvent, err := queue.Enqueue(ctx, datastore.ReplicationEvent{ Job: datastore.ReplicationJob{ Change: datastore.CreateRepo, @@ -290,11 +296,15 @@ func TestRemoveRepository_removeReplicationEvents(t *testing.T) { }, }) require.NoError(t, err) - inProgress1, err := queue.Dequeue(ctx, virtualStorage, "gitaly-2", 10) + // Dequeue the event to move it into "in_progress" state. + dequeuedEvents, err := queue.Dequeue(ctx, virtualStorage, "gitaly-2", 10) require.NoError(t, err) - require.Len(t, inProgress1, 1) + require.Len(t, dequeuedEvents, 1) + require.Equal(t, inProgressEvent.ID, dequeuedEvents[0].ID) + require.Equal(t, datastore.JobStateInProgress, dequeuedEvents[0].State) - // New event - events in the 'ready' state should be removed. + // Create a second event that is "ready" to verify that it is getting removed by the + // command. _, err = queue.Enqueue(ctx, datastore.ReplicationEvent{ Job: datastore.ReplicationJob{ Change: datastore.UpdateRepo, @@ -306,7 +316,7 @@ func TestRemoveRepository_removeReplicationEvents(t *testing.T) { }) require.NoError(t, err) - // Failed event - should be removed as well. + // And create a third event that is in "failed" state, which should also get cleaned up. failedEvent, err := queue.Enqueue(ctx, datastore.ReplicationEvent{ Job: datastore.ReplicationJob{ Change: datastore.UpdateRepo, @@ -317,54 +327,52 @@ func TestRemoveRepository_removeReplicationEvents(t *testing.T) { }, }) require.NoError(t, err) - inProgress2, err := queue.Dequeue(ctx, virtualStorage, "gitaly-4", 10) + // Dequeue the job to move it into "in-progress". + dequeuedEvents, err = queue.Dequeue(ctx, virtualStorage, "gitaly-4", 10) require.NoError(t, err) - require.Len(t, inProgress2, 1) - // Acknowledge with failed status, so it will remain in the database for the next processing - // attempt or until it is deleted by the 'removeReplicationEvents' method. - acks2, err := queue.Acknowledge(ctx, datastore.JobStateFailed, []uint64{inProgress2[0].ID}) + require.Len(t, dequeuedEvents, 1) + require.Equal(t, failedEvent.ID, dequeuedEvents[0].ID) + require.Equal(t, datastore.JobStateInProgress, dequeuedEvents[0].State) + // And then acknowledge it to move it into "failed" state. + acknowledgedJobIDs, err := queue.Acknowledge(ctx, datastore.JobStateFailed, []uint64{failedEvent.ID}) require.NoError(t, err) - require.Equal(t, []uint64{inProgress2[0].ID}, acks2) + require.Equal(t, []uint64{failedEvent.ID}, acknowledgedJobIDs) ticker := helper.NewManualTicker() defer ticker.Stop() - errChan := make(chan error, 1) + var wg sync.WaitGroup + wg.Add(1) go func() { - cmd := &removeRepository{virtualStorage: virtualStorage, relativePath: relativePath} - errChan <- cmd.removeReplicationEvents(ctx, testhelper.NewDiscardingLogger(t), db.DB, ticker) + defer wg.Done() + + // Tick multiple times so that we know that at least one event must have been processed by + // the command. + ticker.Tick() + ticker.Tick() + ticker.Tick() + + // Verify that the database now only contains a single job, which is the "in_progress" one. + var jobIDs glsql.Uint64Provider + row := db.QueryRowContext(ctx, `SELECT id FROM replication_queue`) + assert.NoError(t, row.Scan(jobIDs.To()...)) + assert.Equal(t, []uint64{inProgressEvent.ID}, jobIDs.Values()) + + // Now we acknowledge the "in_progress" job so that it will also get pruned. This + // will also stop the processing loop as there are no more jobs left. + acknowledgedJobIDs, err = queue.Acknowledge(ctx, datastore.JobStateCompleted, []uint64{inProgressEvent.ID}) + assert.NoError(t, err) + assert.Equal(t, []uint64{inProgressEvent.ID}, acknowledgedJobIDs) + + ticker.Tick() }() - ticker.Tick() - ticker.Tick() - ticker.Tick() // blocks until previous tick is consumed + cmd := &removeRepository{virtualStorage: virtualStorage, relativePath: relativePath} + require.NoError(t, cmd.removeReplicationEvents(ctx, testhelper.NewDiscardingLogger(t), db.DB, ticker)) - // Now we acknowledge in_progress job, so it stops the processing loop or the command. - acks, err := queue.Acknowledge(ctx, datastore.JobStateCompleted, []uint64{inProgressEvent.ID}) - if assert.NoError(t, err) { - assert.Equal(t, []uint64{inProgress1[0].ID}, acks) - } - - ticker.Tick() - - timeout := time.After(time.Minute) - for checkChan, exists := errChan, true; exists; { - select { - case err := <-checkChan: - require.NoError(t, err) - close(errChan) - checkChan = nil - case <-timeout: - require.FailNow(t, "timeout reached, looks like the command hasn't made any progress") - case <-time.After(50 * time.Millisecond): - // Wait until job removed - row := db.QueryRow(`SELECT EXISTS(SELECT FROM replication_queue WHERE id = $1)`, failedEvent.ID) - require.NoError(t, row.Scan(&exists)) - } - } - // Once there are no in_progress jobs anymore the method returns. - require.NoError(t, <-errChan) + wg.Wait() + // And now we can finally assert that the replication queue is empty. var notExists bool row := db.QueryRow(`SELECT NOT EXISTS(SELECT FROM replication_queue)`) require.NoError(t, row.Scan(¬Exists)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor.go index 0da3ecdc6c..c52b7270ef 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor.go @@ -7,8 +7,8 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor_test.go index 4dc8f5a32e..dd6bc19b26 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_set_replication_factor_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_set_replication_factor_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -5,12 +7,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate.go index 1d4ee34209..670dd5ca83 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate.go @@ -7,9 +7,9 @@ import ( "time" migrate "github.com/rubenv/sql-migrate" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_down.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_down.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_down.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_down.go index c0418f11da..b5a3383e96 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_down.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_down.go @@ -6,8 +6,8 @@ import ( "fmt" "strconv" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" ) const sqlMigrateDownCmdName = "sql-migrate-down" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_status.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_status.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_status.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_status.go index 760beb22cc..c86fbed444 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_status.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_status.go @@ -6,8 +6,8 @@ import ( "sort" "github.com/olekukonko/tablewriter" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" ) const sqlMigrateStatusCmdName = "sql-migrate-status" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_test.go index d7381b82fc..5fc4f7f634 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_migrate_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_migrate_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestSubCmdSqlMigrate(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_ping.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_ping.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_ping.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_ping.go index 5fcf6c772f..b11f6da2fc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_sql_ping.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_sql_ping.go @@ -4,8 +4,8 @@ import ( "flag" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_test.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_test.go index 6eb475fccf..1d506c857f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -7,9 +9,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" ) @@ -30,13 +33,13 @@ func registerServerService(impl gitalypb.ServerServiceServer) svcRegistrar { } } -func listenAndServe(t testing.TB, svcs []svcRegistrar) (net.Listener, testhelper.Cleanup) { - t.Helper() +func listenAndServe(tb testing.TB, svcs []svcRegistrar) (net.Listener, testhelper.Cleanup) { + tb.Helper() - tmp := testhelper.TempDir(t) + tmp := testhelper.TempDir(tb) ln, err := net.Listen("unix", filepath.Join(tmp, "gitaly")) - require.NoError(t, err) + require.NoError(tb, err) srv := grpc.NewServer() @@ -44,14 +47,14 @@ func listenAndServe(t testing.TB, svcs []svcRegistrar) (net.Listener, testhelper s(srv) } - go func() { require.NoError(t, srv.Serve(ln)) }() - ctx := testhelper.Context(t) + go func() { require.NoError(tb, srv.Serve(ln)) }() + ctx := testhelper.Context(tb) // verify the service is up addr := fmt.Sprintf("%s://%s", ln.Addr().Network(), ln.Addr()) - cc, err := grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithInsecure()) - require.NoError(t, err) - require.NoError(t, cc.Close()) + cc, err := grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(tb, err) + require.NoError(tb, cc.Close()) return ln, func() { srv.Stop() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories.go new file mode 100644 index 0000000000..2ba8a88b14 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories.go @@ -0,0 +1,214 @@ +package main + +import ( + "bufio" + "context" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "time" + + "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/labkit/correlation" +) + +const ( + trackRepositoriesCmdName = "track-repositories" + paramInputPath = "input-path" +) + +type invalidRequest struct { + line int + path string + errs []error +} + +type dupPathError struct { + path string + reqNums []int +} + +func (d *dupPathError) Error() string { + return fmt.Sprintf("duplicate entries for relative_path, line %v", d.reqNums) +} + +type trackRepositories struct { + w io.Writer + logger logrus.FieldLogger + inputPath string + replicateImmediately bool +} + +func newTrackRepositories(logger logrus.FieldLogger, w io.Writer) *trackRepositories { + return &trackRepositories{w: w, logger: logger} +} + +func (cmd *trackRepositories) FlagSet() *flag.FlagSet { + fs := flag.NewFlagSet(trackRepositoryCmdName, flag.ExitOnError) + fs.BoolVar(&cmd.replicateImmediately, "replicate-immediately", false, "kick off a replication immediately") + fs.StringVar(&cmd.inputPath, paramInputPath, "", "path to file with details of repositories to track") + fs.Usage = func() { + printfErr("Description:\n" + + " This command allows bulk requests for repositories to be tracked by Praefect.\n" + + " The -input-path flag must be the path of a file containing the details of the repositories\n" + + " to track as a list of newline-delimited JSON objects. Each line must contain the details for\n" + + " one and only one repository. Each item must contain the following keys:\n\n" + + " relative_path - The relative path of the repository on-disk.\n" + + " virtual_storage - The Praefect virtual storage name.\n" + + " authoritative_storage - Which storage to consider as the canonical copy of the repository.\n\n" + + " If -replicate-immediately is used, the command will attempt to replicate the repositories\n" + + " to the secondaries. Otherwise, replication jobs will be created and will be executed\n" + + " eventually by Praefect itself.\n") + fs.PrintDefaults() + } + return fs +} + +func (cmd trackRepositories) Exec(flags *flag.FlagSet, cfg config.Config) error { + switch { + case flags.NArg() > 0: + return unexpectedPositionalArgsError{Command: flags.Name()} + } + + ctx := correlation.ContextWithCorrelation(context.Background(), correlation.SafeRandomID()) + logger = cmd.logger.WithField("correlation_id", correlation.ExtractFromContext(ctx)) + + openDBCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + db, err := glsql.OpenDB(openDBCtx, cfg.DB) + if err != nil { + return fmt.Errorf("connect to database: %w", err) + } + defer func() { _ = db.Close() }() + store := datastore.NewPostgresRepositoryStore(db, cfg.StorageNames()) + + f, err := os.Open(cmd.inputPath) + if err != nil { + return fmt.Errorf("open input: %w", err) + } + defer f.Close() + + scanner := bufio.NewScanner(f) + + fmt.Fprintf(cmd.w, "Validating repository information in %q\n", cmd.inputPath) + + var requests []trackRepositoryRequest + var line int + var repoErrs []invalidRequest + pathLines := make(map[string][]int) + + // Read in and validate all requests from input file before executing. This prevents us from + // partially executing a file, which makes it difficult to tell which repos were actually + // tracked. + for scanner.Scan() { + line++ + + request := trackRepositoryRequest{} + badReq := invalidRequest{line: line} + + if err := json.Unmarshal(scanner.Bytes(), &request); err != nil { + badReq.errs = append(badReq.errs, err) + repoErrs = append(repoErrs, badReq) + + // Invalid request, nothing to validate. + continue + } + + if request.RelativePath == "" { + badReq.errs = append(badReq.errs, requiredParameterError(paramRelativePath)) + } + badReq.path = request.RelativePath + + if request.VirtualStorage == "" { + badReq.errs = append(badReq.errs, requiredParameterError(paramVirtualStorage)) + } + if request.AuthoritativeStorage == "" { + badReq.errs = append(badReq.errs, requiredParameterError(paramAuthoritativeStorage)) + } + if len(badReq.errs) > 0 { + repoErrs = append(repoErrs, badReq) + + // Incomplete request, no further validation possible. + continue + } + + // Repo paths are globally unique, any attempt to add the same path multiple virtual storages + // is invalid and must be rejected. + prevLines, exists := pathLines[request.RelativePath] + if exists { + badReq.errs = append(badReq.errs, &dupPathError{path: request.RelativePath}) + repoErrs = append(repoErrs, badReq) + + prevLines = append(prevLines, line) + pathLines[request.RelativePath] = prevLines + + // We've already checked this path, no need to run further checks. + continue + } + pathLines[request.RelativePath] = []int{line} + + repoInDB, err := store.RepositoryExists(ctx, request.VirtualStorage, request.RelativePath) + if err != nil { + // Bail out if we're having trouble contacting the DB, nothing is going to work if this fails. + return fmt.Errorf("checking database: %w", err) + } + if repoInDB { + badReq.errs = append(badReq.errs, fmt.Errorf("repository is already tracked by Praefect")) + repoErrs = append(repoErrs, badReq) + // Repo already in Praefect DB, we can skip it. + continue + } + + authoritativeRepoExists, err := request.authoritativeRepositoryExists(ctx, cfg, cmd.w, request.AuthoritativeStorage) + if err != nil { + badReq.errs = append(badReq.errs, fmt.Errorf("checking repository on disk: %w", err)) + } else if !authoritativeRepoExists { + badReq.errs = append(badReq.errs, fmt.Errorf("not a valid git repository")) + } + + if len(badReq.errs) > 0 { + repoErrs = append(repoErrs, badReq) + continue + } + requests = append(requests, request) + } + + if len(repoErrs) > 0 { + printInvalidRequests(cmd.w, repoErrs, pathLines, cmd.inputPath) + return fmt.Errorf("invalid entries found, aborting") + } + if len(requests) == 0 { + return fmt.Errorf("no repository information found in %q", cmd.inputPath) + } + + fmt.Fprintf(cmd.w, "All repository details are correctly formatted\n") + fmt.Fprintf(cmd.w, "Tracking %v repositories in Praefect DB...\n", line) + for _, request := range requests { + if err := request.execRequest(ctx, db, cfg, cmd.w, logger, cmd.replicateImmediately); err != nil { + return fmt.Errorf("tracking repository %q: %w", request.RelativePath, err) + } + } + + return nil +} + +func printInvalidRequests(w io.Writer, repoErrs []invalidRequest, pathLines map[string][]int, inputPath string) { + fmt.Fprintf(w, "Found %v invalid request(s) in %q:\n", len(repoErrs), inputPath) + + for _, l := range repoErrs { + fmt.Fprintf(w, " line %v, relative_path: %q\n", l.line, l.path) + for _, err := range l.errs { + if dup, ok := err.(*dupPathError); ok { + // The complete set of duplicate reqNums won't be known until input is + // fully processed, fetch them now. + err = &dupPathError{path: dup.path, reqNums: pathLines[dup.path]} + } + fmt.Fprintf(w, " %v\n", err) + } + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories_test.go new file mode 100644 index 0000000000..c644f88d2b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repositories_test.go @@ -0,0 +1,357 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestAddRepositories_FlagSet(t *testing.T) { + t.Parallel() + cmd := &trackRepositories{} + fs := cmd.FlagSet() + require.NoError(t, fs.Parse([]string{"--input-path", "/dev/stdin", "--replicate-immediately", "true"})) + require.Equal(t, "/dev/stdin", cmd.inputPath) + require.Equal(t, true, cmd.replicateImmediately) +} + +func TestAddRepositories_Exec_invalidInput(t *testing.T) { + t.Parallel() + g1Cfg := testcfg.Build(t, testcfg.WithStorages("gitaly-1")) + g2Cfg := testcfg.Build(t, testcfg.WithStorages("gitaly-2")) + + g1Srv := testserver.StartGitalyServer(t, g1Cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + g2Srv := testserver.StartGitalyServer(t, g2Cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + defer g2Srv.Shutdown() + defer g1Srv.Shutdown() + g1Addr := g1Srv.Address() + + db := testdb.New(t) + dbConf := testdb.GetConfig(t, db.Name) + + virtualStorageName := "praefect" + conf := config.Config{ + AllowLegacyElectors: true, + SocketPath: testhelper.GetTemporaryGitalySocketFileName(t), + VirtualStorages: []*config.VirtualStorage{ + { + Name: virtualStorageName, + Nodes: []*config.Node{ + {Storage: g1Cfg.Storages[0].Name, Address: g1Addr}, + {Storage: g2Cfg.Storages[0].Name, Address: g2Srv.Address()}, + }, + DefaultReplicationFactor: 2, + }, + }, + DB: dbConf, + Failover: config.Failover{ + Enabled: true, + ElectionStrategy: config.ElectionStrategyPerRepository, + }, + } + rs := datastore.NewPostgresRepositoryStore(db, nil) + ctx := testhelper.Context(t) + inputFile := "input_file" + + trackRepo := func(relativePath string) error { + repositoryID, err := rs.ReserveRepositoryID(ctx, virtualStorageName, relativePath) + if err != nil { + return err + } + return rs.CreateRepository( + ctx, + repositoryID, + virtualStorageName, + relativePath, + relativePath, + g1Cfg.Storages[0].Name, + nil, + nil, + false, + false, + ) + } + + invalidEntryErr := "invalid entries found, aborting" + + testCases := []struct { + input string + desc string + expectedOutput string + expectedError string + trackedPath string + }{ + { + input: "", + desc: "empty input", + expectedError: "no repository information found", + }, + { + input: "@hashed/01/23/01234567890123456789.git", + desc: "invalid JSON", + expectedOutput: "invalid character '@' looking for beginning of value", + expectedError: invalidEntryErr, + }, + { + input: `{"virtual_storage":"praefect","authoritative_storage":"gitaly-1"}`, + desc: "missing path", + expectedOutput: `"repository" is a required parameter`, + expectedError: invalidEntryErr, + }, + { + input: `{"virtual_storage":"foo","relative_path":"bar","authoritative_storage":"gitaly-1"}`, + desc: "invalid virtual storage", + expectedOutput: `virtual storage "foo" not found`, + expectedError: invalidEntryErr, + }, + { + input: `{"relative_path":"not_a_repo","virtual_storage":"praefect","authoritative_storage":"gitaly-1"}`, + desc: "repo does not exist", + expectedOutput: "not a valid git repository", + expectedError: invalidEntryErr, + }, + { + input: `{"virtual_storage":"praefect","relative_path":"duplicate","authoritative_storage":"gitaly-1"} +{"virtual_storage":"praefect","relative_path":"duplicate","authoritative_storage":"gitaly-1"}`, + desc: "duplicate path", + expectedOutput: "duplicate entries for relative_path", + expectedError: invalidEntryErr, + }, + { + input: `{"relative_path":"already_tracked","virtual_storage":"praefect","authoritative_storage":"gitaly-1"}`, + desc: "repo is already tracked", + expectedOutput: "repository is already tracked by Praefect", + expectedError: invalidEntryErr, + trackedPath: "already_tracked", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + nodeMgr, err := nodes.NewManager( + testhelper.NewDiscardingLogEntry(t), + conf, + db.DB, + nil, + promtest.NewMockHistogramVec(), + protoregistry.GitalyProtoPreregistered, + nil, + nil, + nil, + ) + require.NoError(t, err) + nodeMgr.Start(0, time.Hour) + defer nodeMgr.Stop() + + tempDir := testhelper.TempDir(t) + f, err := os.Create(filepath.Join(tempDir, inputFile)) + require.NoError(t, err) + _, err = f.Write([]byte(tc.input)) + require.NoError(t, err) + require.NoError(t, f.Close()) + + var stdout bytes.Buffer + + if tc.trackedPath != "" { + require.NoError(t, trackRepo(tc.trackedPath)) + } + + addReposCmd := &trackRepositories{ + inputPath: filepath.Join(tempDir, inputFile), + replicateImmediately: true, + logger: logger, + w: &stdout, + } + err = addReposCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf) + require.Error(t, err) + + if tc.expectedOutput != "" { + require.Contains(t, stdout.String(), tc.expectedOutput) + } + require.Contains(t, err.Error(), tc.expectedError) + }) + } +} + +func TestAddRepositories_Exec(t *testing.T) { + t.Parallel() + g1Cfg := testcfg.Build(t, testcfg.WithStorages("gitaly-1")) + g2Cfg := testcfg.Build(t, testcfg.WithStorages("gitaly-2")) + testcfg.BuildGitalyHooks(t, g2Cfg) + testcfg.BuildGitalySSH(t, g2Cfg) + + g1Srv := testserver.StartGitalyServer(t, g1Cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + g2Srv := testserver.StartGitalyServer(t, g2Cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + defer g2Srv.Shutdown() + defer g1Srv.Shutdown() + + g1Addr := g1Srv.Address() + + db := testdb.New(t) + dbConf := testdb.GetConfig(t, db.Name) + + virtualStorageName := "praefect" + conf := config.Config{ + AllowLegacyElectors: true, + SocketPath: testhelper.GetTemporaryGitalySocketFileName(t), + VirtualStorages: []*config.VirtualStorage{ + { + Name: virtualStorageName, + Nodes: []*config.Node{ + {Storage: g1Cfg.Storages[0].Name, Address: g1Addr}, + {Storage: g2Cfg.Storages[0].Name, Address: g2Srv.Address()}, + }, + DefaultReplicationFactor: 2, + }, + }, + DB: dbConf, + Failover: config.Failover{ + Enabled: true, + ElectionStrategy: config.ElectionStrategyPerRepository, + }, + } + + gitalyCC, err := client.Dial(g1Addr, nil) + require.NoError(t, err) + defer func() { require.NoError(t, gitalyCC.Close()) }() + ctx := testhelper.Context(t) + + gitaly1RepositoryClient := gitalypb.NewRepositoryServiceClient(gitalyCC) + + createRepoThroughGitaly1 := func(relativePath string) error { + _, err := gitaly1RepositoryClient.CreateRepository( + ctx, + &gitalypb.CreateRepositoryRequest{ + Repository: &gitalypb.Repository{ + StorageName: g1Cfg.Storages[0].Name, + RelativePath: relativePath, + }, + }) + return err + } + + authoritativeStorage := g1Cfg.Storages[0].Name + logger := testhelper.NewDiscardingLogger(t) + + t.Run("ok", func(t *testing.T) { + testCases := []struct { + relativePaths []string + desc string + replicateImmediately bool + expectedOutput string + }{ + { + relativePaths: []string{"path/to/test/repo1", "path/to/test/repo2"}, + desc: "immediate replication", + replicateImmediately: true, + expectedOutput: "Finished replicating repository to \"gitaly-2\".\n", + }, + { + relativePaths: []string{"path/to/test/repo3", "path/to/test/repo4"}, + desc: "no immediate replication", + replicateImmediately: false, + expectedOutput: "Added replication job to replicate repository to \"gitaly-2\".\n", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + nodeMgr, err := nodes.NewManager( + testhelper.NewDiscardingLogEntry(t), + conf, + db.DB, + nil, + promtest.NewMockHistogramVec(), + protoregistry.GitalyProtoPreregistered, + nil, + nil, + nil, + ) + require.NoError(t, err) + nodeMgr.Start(0, time.Hour) + defer nodeMgr.Stop() + + tempDir := testhelper.TempDir(t) + input, err := os.Create(filepath.Join(tempDir, "input")) + require.NoError(t, err) + + repoDS := datastore.NewPostgresRepositoryStore(db, conf.StorageNames()) + for _, path := range tc.relativePaths { + exists, err := repoDS.RepositoryExists(ctx, virtualStorageName, path) + require.NoError(t, err) + require.False(t, exists) + + // create the repo on Gitaly without Praefect knowing + require.NoError(t, createRepoThroughGitaly1(path)) + require.DirExists(t, filepath.Join(g1Cfg.Storages[0].Path, path)) + require.NoDirExists(t, filepath.Join(g2Cfg.Storages[0].Path, path)) + + // Write repo details to input file + repoEntry, err := json.Marshal(trackRepositoryRequest{RelativePath: path, VirtualStorage: virtualStorageName, AuthoritativeStorage: authoritativeStorage}) + require.NoError(t, err) + fmt.Fprintf(input, string(repoEntry)+"\n") + } + + var stdout bytes.Buffer + + addRepoCmd := &trackRepositories{ + inputPath: filepath.Join(tempDir, "input"), + replicateImmediately: tc.replicateImmediately, + logger: logger, + w: &stdout, + } + + require.NoError(t, addRepoCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) + assert.Contains(t, stdout.String(), tc.expectedOutput) + + as := datastore.NewAssignmentStore(db, conf.StorageNames()) + + for _, path := range tc.relativePaths { + repositoryID, err := repoDS.GetRepositoryID(ctx, virtualStorageName, path) + require.NoError(t, err) + + assignments, err := as.GetHostAssignments(ctx, virtualStorageName, repositoryID) + require.NoError(t, err) + require.Len(t, assignments, 2) + assert.Contains(t, assignments, g1Cfg.Storages[0].Name) + assert.Contains(t, assignments, g2Cfg.Storages[0].Name) + + exists, err := repoDS.RepositoryExists(ctx, virtualStorageName, path) + require.NoError(t, err) + assert.True(t, exists) + + if !tc.replicateImmediately { + queue := datastore.NewPostgresReplicationEventQueue(db) + events, err := queue.Dequeue(ctx, virtualStorageName, g2Cfg.Storages[0].Name, 1) + require.NoError(t, err) + assert.Len(t, events, 1) + assert.Equal(t, path, events[0].Job.RelativePath) + } else { + require.DirExists(t, filepath.Join(g2Cfg.Storages[0].Path, path)) + } + } + }) + } + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository.go index d86ba2497f..8fc4fd0a68 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository.go @@ -11,14 +11,14 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" ) @@ -36,6 +36,12 @@ type trackRepository struct { replicateImmediately bool } +type trackRepositoryRequest struct { + RelativePath string `json:"relative_path"` + VirtualStorage string `json:"virtual_storage"` + AuthoritativeStorage string `json:"authoritative_storage"` +} + var errAuthoritativeRepositoryNotExist = errors.New("authoritative repository does not exist") func newTrackRepository(logger logrus.FieldLogger, w io.Writer) *trackRepository { @@ -54,7 +60,7 @@ func (cmd *trackRepository) FlagSet() *flag.FlagSet { " It checks if the repository exists on disk on the authoritative storage,\n" + " and whether database records are absent from tracking the repository.\n" + " If -replicate-immediately is used, the command will attempt to replicate the repository to the secondaries.\n" + - " Otherwise, replication jobs will be created and will be excuted eventually by Praefect itself.\n") + " Otherwise, replication jobs will be created and will be executed eventually by Praefect itself.\n") fs.PrintDefaults() } return fs @@ -75,7 +81,6 @@ func (cmd trackRepository) Exec(flags *flag.FlagSet, cfg config.Config) error { } ctx := correlation.ContextWithCorrelation(context.Background(), correlation.SafeRandomID()) - logger := cmd.logger.WithField("correlation_id", correlation.ExtractFromContext(ctx)) openDBCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() @@ -85,16 +90,34 @@ func (cmd trackRepository) Exec(flags *flag.FlagSet, cfg config.Config) error { } defer func() { _ = db.Close() }() - return cmd.exec(ctx, logger, db, cfg) + return cmd.exec(ctx, db, cfg) } const trackRepoErrorPrefix = "attempting to track repository in praefect database" -func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, db *sql.DB, cfg config.Config) error { +func (cmd *trackRepository) exec(ctx context.Context, db *sql.DB, cfg config.Config) error { + logger := cmd.logger.WithField("correlation_id", correlation.ExtractFromContext(ctx)) + + req := trackRepositoryRequest{ + RelativePath: cmd.relativePath, + AuthoritativeStorage: cmd.authoritativeStorage, + VirtualStorage: cmd.virtualStorage, + } + + return req.execRequest(ctx, db, cfg, cmd.w, logger, cmd.replicateImmediately) +} + +func (req *trackRepositoryRequest) execRequest(ctx context.Context, + db *sql.DB, + cfg config.Config, + w io.Writer, + logger logrus.FieldLogger, + replicateImmediately bool, +) error { logger.WithFields(logrus.Fields{ - "virtual_storage": cmd.virtualStorage, - "relative_path": cmd.relativePath, - "authoritative_storage": cmd.authoritativeStorage, + "virtual_storage": req.VirtualStorage, + "relative_path": req.RelativePath, + "authoritative_storage": req.AuthoritativeStorage, }).Debug("track repository") var primary string @@ -102,12 +125,12 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, var variableReplicationFactorEnabled, savePrimary bool if cfg.Failover.ElectionStrategy == config.ElectionStrategyPerRepository { savePrimary = true - primary = cmd.authoritativeStorage + primary = req.AuthoritativeStorage for _, vs := range cfg.VirtualStorages { - if vs.Name == cmd.virtualStorage { + if vs.Name == req.VirtualStorage { for _, node := range vs.Nodes { - if node.Storage == cmd.authoritativeStorage { + if node.Storage == req.AuthoritativeStorage { continue } secondaries = append(secondaries, node.Storage) @@ -116,7 +139,7 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, } r := rand.New(rand.NewSource(time.Now().UnixNano())) - replicationFactor := cfg.DefaultReplicationFactors()[cmd.virtualStorage] + replicationFactor := cfg.DefaultReplicationFactors()[req.VirtualStorage] if replicationFactor > 0 { variableReplicationFactorEnabled = true @@ -129,7 +152,7 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, } } else { savePrimary = false - if err := db.QueryRowContext(ctx, `SELECT node_name FROM shard_primaries WHERE shard_name = $1 AND demoted = 'false'`, cmd.virtualStorage).Scan(&primary); err != nil { + if err := db.QueryRowContext(ctx, `SELECT node_name FROM shard_primaries WHERE shard_name = $1 AND demoted = 'false'`, req.VirtualStorage).Scan(&primary); err != nil { if errors.Is(err, sql.ErrNoRows) { return fmt.Errorf("%s: no primaries found", trackRepoErrorPrefix) } @@ -137,7 +160,7 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, } } - authoritativeRepoExists, err := cmd.authoritativeRepositoryExists(ctx, cfg, primary) + authoritativeRepoExists, err := req.authoritativeRepositoryExists(ctx, cfg, w, primary) if err != nil { return fmt.Errorf("%s: %w", trackRepoErrorPrefix, err) } @@ -162,7 +185,7 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, store := datastore.NewPostgresRepositoryStore(db, cfg.StorageNames()) queue := datastore.NewPostgresReplicationEventQueue(db) replMgr := praefect.NewReplMgr( - cmd.logger, + logger, cfg.StorageNames(), queue, store, @@ -170,9 +193,10 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, nodeSet, ) - repositoryID, err := cmd.trackRepository( + repositoryID, err := req.trackRepository( ctx, store, + w, primary, secondaries, savePrimary, @@ -182,24 +206,24 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, return fmt.Errorf("%s: %w", trackRepoErrorPrefix, err) } - fmt.Fprintln(cmd.w, "Finished adding new repository to be tracked in praefect database.") + fmt.Fprintln(w, "Finished adding new repository to be tracked in praefect database.") correlationID := correlation.SafeRandomID() - connections := nodeSet.Connections()[cmd.virtualStorage] + connections := nodeSet.Connections()[req.VirtualStorage] for _, secondary := range secondaries { event := datastore.ReplicationEvent{ Job: datastore.ReplicationJob{ RepositoryID: repositoryID, Change: datastore.UpdateRepo, - RelativePath: cmd.relativePath, - VirtualStorage: cmd.virtualStorage, + RelativePath: req.RelativePath, + VirtualStorage: req.VirtualStorage, SourceNodeStorage: primary, TargetNodeStorage: secondary, }, Meta: datastore.Params{metadatahandler.CorrelationIDKey: correlationID}, } - if cmd.replicateImmediately { + if replicateImmediately { conn, ok := connections[secondary] if !ok { return fmt.Errorf("%s: connection for %q not found", trackRepoErrorPrefix, secondary) @@ -209,31 +233,32 @@ func (cmd *trackRepository) exec(ctx context.Context, logger logrus.FieldLogger, return fmt.Errorf("%s: processing replication event %w", trackRepoErrorPrefix, err) } - fmt.Fprintf(cmd.w, "Finished replicating repository to %q.\n", secondary) + fmt.Fprintf(w, "Finished replicating repository to %q.\n", secondary) continue } if _, err := queue.Enqueue(ctx, event); err != nil { return fmt.Errorf("%s: %w", trackRepoErrorPrefix, err) } - fmt.Fprintf(cmd.w, "Added replication job to replicate repository to %q.\n", secondary) + fmt.Fprintf(w, "Added replication job to replicate repository to %q.\n", secondary) } return nil } -func (cmd *trackRepository) trackRepository( +func (req *trackRepositoryRequest) trackRepository( ctx context.Context, ds *datastore.PostgresRepositoryStore, + w io.Writer, primary string, secondaries []string, savePrimary bool, variableReplicationFactorEnabled bool, ) (int64, error) { - repositoryID, err := ds.ReserveRepositoryID(ctx, cmd.virtualStorage, cmd.relativePath) + repositoryID, err := ds.ReserveRepositoryID(ctx, req.VirtualStorage, req.RelativePath) if err != nil { if errors.Is(err, commonerr.ErrRepositoryAlreadyExists) { - cmd.logger.Print("repository is already tracked in praefect database") + fmt.Fprintf(w, "repository is already tracked in praefect database") return 0, nil } @@ -243,9 +268,9 @@ func (cmd *trackRepository) trackRepository( if err := ds.CreateRepository( ctx, repositoryID, - cmd.virtualStorage, - cmd.relativePath, - cmd.relativePath, + req.VirtualStorage, + req.RelativePath, + req.RelativePath, primary, nil, secondaries, @@ -275,28 +300,28 @@ func repositoryExists(ctx context.Context, repo *gitalypb.Repository, addr, toke return res.GetExists(), nil } -func (cmd *trackRepository) authoritativeRepositoryExists(ctx context.Context, cfg config.Config, nodeName string) (bool, error) { +func (req *trackRepositoryRequest) authoritativeRepositoryExists(ctx context.Context, cfg config.Config, w io.Writer, nodeName string) (bool, error) { for _, vs := range cfg.VirtualStorages { - if vs.Name != cmd.virtualStorage { + if vs.Name != req.VirtualStorage { continue } for _, node := range vs.Nodes { if node.Storage == nodeName { - logger.Debugf("check if repository %q exists on gitaly %q at %q", cmd.relativePath, node.Storage, node.Address) + logger.Debugf("check if repository %q exists on gitaly %q at %q", req.RelativePath, node.Storage, node.Address) repo := &gitalypb.Repository{ StorageName: node.Storage, - RelativePath: cmd.relativePath, + RelativePath: req.RelativePath, } exists, err := repositoryExists(ctx, repo, node.Address, node.Token) if err != nil { - logger.WithError(err).Warnf("checking if repository exists %q, %q", node.Storage, cmd.relativePath) + fmt.Fprintf(w, "checking if repository exists %q, %q", node.Storage, req.RelativePath) return false, nil } return exists, nil } } - return false, fmt.Errorf("node %q not found", cmd.authoritativeStorage) + return false, fmt.Errorf("node %q not found", req.AuthoritativeStorage) } - return false, fmt.Errorf("virtual storage %q not found", cmd.virtualStorage) + return false, fmt.Errorf("virtual storage %q not found", req.VirtualStorage) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository_test.go index 2e3c807bfe..4ef6e7fb27 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_track_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_track_repository_test.go @@ -1,27 +1,28 @@ +//go:build !gitaly_test_sha256 + package main import ( "bytes" "flag" - "io" "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestAddRepository_FlagSet(t *testing.T) { @@ -170,15 +171,9 @@ func TestAddRepository_Exec(t *testing.T) { defer nodeMgr.Stop() repoDS := datastore.NewPostgresRepositoryStore(db, conf.StorageNames()) - - rmRepoCmd := &removeRepository{ - logger: logger, - virtualStorage: virtualStorageName, - relativePath: tc.relativePath, - w: io.Discard, - apply: true, - } - require.NoError(t, rmRepoCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), conf)) + exists, err := repoDS.RepositoryExists(ctx, virtualStorageName, tc.relativePath) + require.NoError(t, err) + require.False(t, exists) // create the repo on Gitaly without Praefect knowing require.NoError(t, createRepoThroughGitaly1(tc.relativePath)) @@ -207,7 +202,7 @@ func TestAddRepository_Exec(t *testing.T) { assert.Contains(t, assignments, g1Cfg.Storages[0].Name) assert.Contains(t, assignments, g2Cfg.Storages[0].Name) - exists, err := repoDS.RepositoryExists(ctx, virtualStorageName, tc.relativePath) + exists, err = repoDS.RepositoryExists(ctx, virtualStorageName, tc.relativePath) require.NoError(t, err) assert.True(t, exists) assert.Contains(t, stdout.String(), tc.expectedOutput) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify.go index 3407314095..b52a08d7b4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify.go @@ -7,8 +7,8 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const verifyCmdName = "verify" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify_test.go index 107430c7cd..3731b82e98 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/cmd/praefect/subcmd_verify_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/cmd/praefect/subcmd_verify_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package main import ( @@ -7,11 +9,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestVerifySubcommand(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/config.praefect.toml.example b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/config.praefect.toml.example similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/config.praefect.toml.example rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/config.praefect.toml.example diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/config.toml.example b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/config.toml.example similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/config.toml.example rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/config.toml.example index ae1b54e1ab..9a4753e1e1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/config.toml.example +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/config.toml.example @@ -37,6 +37,14 @@ bin_dir = "/home/git/gitaly/_build/bin" # [git] # bin_path = "/usr/bin/git" # catfile_cache_size = 100 +# +# # Set this setting to `true` to start ignoring gitconfig files installed in +# # the system. This includes both system-level (e.g. '/etc/gitconffig') and +# # global-level (e.g. `$HOME/.gitconfig`) files. This setting will become the +# # default with v16.0. If you intend to override Git configuration you can do +# # so via `[[git.config]]`. The default value is `false`. +# ignore_gitconfig = false +# # [[git.config]] # key = fetch.fsckObjects # value = true diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/changes_size/Dangerfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/changes_size/Dangerfile new file mode 100644 index 0000000000..841b373f75 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/changes_size/Dangerfile @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +thresholds = helper.config.code_size_thresholds + +lines_changed = (git.added_files + git.modified_files).sum do |file| + next 0 if file.end_with?('.pb.go') || file.end_with?('_pb.rb') + + git.info_for_file(file)[:insertions] +end + +if lines_changed > thresholds[:high] + warn "This merge request is definitely too big (#{lines_changed} lines changed), please split it into multiple merge requests." +elsif lines_changed > thresholds[:medium] + warn "This merge request is quite big (#{lines_changed} lines changed), please consider splitting it into multiple merge requests." +end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/rules/labels/Dangerfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/labels/Dangerfile similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/rules/labels/Dangerfile rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/labels/Dangerfile index 6bebb86219..4067245efc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/rules/labels/Dangerfile +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/labels/Dangerfile @@ -17,4 +17,4 @@ def inherited_labels .select { |label| INHERITABLE_LABELS.include?(label) } end -helper.labels_to_add.concat(%w[devops::create] | inherited_labels) +helper.labels_to_add.concat(%w[devops::systems] | inherited_labels) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/rules/milestones/Dangerfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/milestones/Dangerfile similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/danger/rules/milestones/Dangerfile rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/danger/rules/milestones/Dangerfile diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/DESIGN.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/DESIGN.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/DESIGN.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/DESIGN.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/PROCESS.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/PROCESS.md similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/PROCESS.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/PROCESS.md index 4f401f7907..d893dbf3ba 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/PROCESS.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/PROCESS.md @@ -275,6 +275,65 @@ Then delete it if that's the data you're expecting: /chatops run feature delete gitaly_X +### Git Version Upgrades + +With the introduction of [bundled Git][bundled-git] we have gained the ability +to do feature-flag-based rollouts of new Git versions, and using feature flags +for these upgrades has since then become mandatory. + +In the past, upgrades of the Git distribution simply happened in-place, where we +just overwrote existing binaries with a new set of binaries. This has the +potential to cause problems during zero-downtime upgrades: an old Gitaly process +may be expecting a different Git version, or it may end up executing Git in an +environment where some executables are the old version, where some other have +already been replaced with the newer version. Naturally, this can lead to all +kinds of problems. + +With the new process we thus do the upgrade in three separate steps to ensure +that we have no such issues with zero-downtime upgrades: + +1. We roll out the new bundled Git binaries in parallel to the old bundled + Git binaries. The new version is guarded behind a feature flag at this + point in time. + +2. We roll out the feature flag and eventually remove it. + +3. We remove the old bundled Git binaries. + +Note that because we cannot remove the old Git binaries at the same time when we +add the new ones. We must ensure that both sets exist in parallel for at least +one release. + +[bundled-git]: git-execution-environments.md#bundled-git-recommended + +#### Detailed Process + +The following detailed steps need to be done to upgrade to a new Git version: + +1. Add the new bundled Git distribution to the `Makefile`. See + c0d05650be681c2accb4cec5aac74a6dd77a2fa6. + +2. Add a new bundled Git execution environment with a feature flag. See + b547b368c8f584e9aabe8eef9342f99440b0c248. Please note that execution + environments are ordered by decreasing priority: the first environment + whose feature flags are all turned on will be picked. You thus have to + add your new environment to the top. + +3. Roll out the feature flag by following our feature flag process. You may + decide to remove the feature flag before the feature flag is removed in + case it is a low-risk upgrade of the Git version (e.g. when you perform a + patch-release upgrade, only). + +4. Remove the feature flag. See 888e6233fd85691f0852ae6c4a3656da9bf3d8e4. + +5. Remove the execution environment of the old bundled Git version. See + af1a3fe7b536d22a6db9ba6591d222b23d01d83f. + +6. Remove the old set of bundled Git binaries from the `Makefile`. See + 9c700ea473d781eea50eab685d643d95e9c4ffee. Note that this must only happen + _after_ both old and new bundled Git binaries have been installed in + parallel in a release already. + ### Gitaly Releases Gitaly releases are tagged automatically by @@ -412,7 +471,7 @@ If a new [major module version update](https://golang.org/doc/modules/major-vers it can be changed by running `upgrade-module` `make` task with desired parameters: ```bash -make upgrade-module FROM_MODULE=v14 TO_MODULE=v15 +make upgrade-module FROM_MODULE=v15 TO_MODULE=v16 ``` It replaces old imports with the new version in the go source files, @@ -460,3 +519,19 @@ if you add patches to Gitaly's Makefile, you cannot assume that installations will always have these patches. As a result, all code which makes use of patched-in features must have fallback code to support the [minimum required Git version](../README.md#installation) + +### RPC deprecation process + +First create a deprecation issue at https://gitlab.com/gitlab-org/gitaly/issues +with the title `Deprecate RPC FooBar`. Use label `Deprecation`. Below is a +template for the issue description. + +``` +We are deprecating RPC FooBar because **REASONS**. + +- [ ] put a deprecation comment `// DEPRECATED: ` in ./proto **Merge Request LINK** +- [ ] find all client-side uses of RPC and list below +- [ ] update all client-side uses to no longer use RPC **ADD Merge Request LINKS** +- [ ] wait for a GitLab release in which the RPC is no longer occurring in client side code **LINK TO GITLAB-CE RELEASE TAG** +- [ ] delete the server side implementation of the old RPC in https://gitlab.com/gitlab-org/gitaly **Merge Request LINK** +``` diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/backpressure.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/backpressure.md similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/backpressure.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/backpressure.md index 8452d4fd99..71ae4fef09 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/backpressure.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/backpressure.md @@ -39,7 +39,7 @@ configuration can prevent an unbounded in-memory queue of requests: concurrency queue. When a request waits longer than this time, it returns an error to the client. - `max_queue_size` is the maximum size the concurrency queue can grow for a given - RPC for a repository. If a concurrency queue is at its maximum, subsequent requests + RPC. If a concurrency queue is at its maximum, subsequent requests return with an error. For example: diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/beginners_guide.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/beginners_guide.md similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/beginners_guide.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/beginners_guide.md index a610aa2dba..ab81e1c80d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/beginners_guide.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/beginners_guide.md @@ -228,6 +228,17 @@ called on `testing.T`. [require]: https://github.com/stretchr/testify/tree/master/require [assert]: https://github.com/stretchr/testify/tree/master/assert +##### Using Delve to debug a test + +The process to debug a test in your terminal using +[Delve](https://github.com/go-delve/delve) is almost the same as +[running a single test](#running-a-specific-test), just change the +target to `debug-test-go`: + +``` +TEST_PACKAGES=./internal/gitaly/service/repository TEST_OPTIONS="-count=1 -run=TestRepositoryExists" make debug-test-go +``` + ##### Useful snippets for creating a test ###### testhelper package diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/cgroups.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/cgroups.md new file mode 100644 index 0000000000..74603352af --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/cgroups.md @@ -0,0 +1,135 @@ +# Cgroups in Gitaly + +## High Level + +Gitaly can be configured to run its git processes inside of cgroups, which prevent +shelled-out processes from hogging too much CPU and memory. See [these docs](https://man7.org/linux/man-pages/man7/cgroups.7.html) for a full specification on cgroups. + +## Configuration + +### Top Level + +Here is the top level `[cgroups]` configuration: + +```toml +[cgroups] +mountpoint = "/sys/fs/cgroup" +hierarchy_root = "gitaly" +memory_bytes = 64424509440 # 60gb +cpu_shares = 1024 +``` + +**mountpoint** is the top level directory where cgroups will be created. +**hierarchy_root** is the parent cgroup under which Gitaly creates cgroups. +**memory_bytes** limits all processes created by Gitaly to a memory limit, +collectively. +**cpu_shares** limits all processes created by Gitaly to a cpu limit, collectively + +### Repository Groups + +Cgroups that have a repository-level isolation can also be defined: + +```toml +[cgroups.repositories] +count = 10000 +memory_bytes = 12884901888 # 12gb +cpu_shares = 512 +``` + +**count** is the number of cgroups to create. +**memory_bytes** limits [memory](#memory-limits) for processes within one cgroup. +This number cannot exceed the top level memory limit. +**cpu_shares** limits [cpu](#cpu-limits) for processes within one cgroup. This +number cannot exceed the top level cpu limit. + +These cgroups will be created when Gitaly starts up. A circular hashing algorithm +is used to assign repositories to cgroups. So when we reach the max number of +cgroups we set in `[cgroups.repositories]`, requests from subsequent repositories +will be assigned to an existing cgroup. + +## Memory Limits + +Each cgroup has a memory limit which in this example config, is 12gb. All +processes that are part of a cgroup are limited to 12gb of memory collectively. +This means that if there are 5 processes that collectively use up 10gb, and a +6th process is added to the cgroup and its memory slowly climbs beyond 2gb, the +OOM killer will target the process with the highest memory usage to be killed. + +This is an oversimplification of how the OOM killer works. A more detailed +picture can be found [here](https://blog.crunchydata.com/blog/deep-postgresql-thoughts-the-linux-assassin#:~:text=CGroup%20Level%20OOM%20Killer%20Mechanics&text=First%20of%20all%2C%20the%20OOM,%2Fcgroup%2Fmemory%2Fmemory.) +and [here](https://lwn.net/Kernel/Index/#OOM_killer). + +This provides baseline protection from processes running haywire, such as a +memory leak. However, this only provides limited protection because there are +some legitimate git processes that can take a huge amount of memory such as +`git-repack(1)`, or `git-upload-pack(1)`. For a large repository, these +operations can easily take 12gb of ram as seen in production systems. + +Hence, we also need finer grained controls to allow certain expensive git +operations to have their own cgroups. + +## CPU Limits + +Each cgroup has cpu limits as defined by a concept called cpu shares. By +definition, full usage of a machine's CPU is 1024 shares. Anything lower than +that will be a fraction of the total CPU resources a machine has access to. + +## Cgroup Hierarchy + +``` +/sys/fs/cgroup +| +|--memory +| |--gitaly +| |--gitaly- +| |--memory.limit_in_bytes +| |--repos-0 +| | |--memory.limit_in_bytes +| |--repos-1 +| | |--memory.limit_in_bytes +| |--repos-2 +| | |--memory.limit_in_bytes +| |--repos-3 +| | |--memory.limit_in_bytes +| |--repos-4 +| | |--memory.limit_in_bytes +| |--repos-5 +| | |--memory.limit_in_bytes +| |--repos-6 +| | |--memory.limit_in_bytes +| |--repos-7 +| | |--memory.limit_in_bytes +| |--repos-8 +| | |--memory.limit_in_bytes +| |--repos-9 +| | |--memory.limit_in_bytes +| |--repos-10 +| |--memory.limit_in_bytes +| +|-cpu +| |--gitaly +| |--gitaly- +| |--cpu.shares +| |--repos-0 +| | |--cpu.shares +| |--repos-1 +| | |--cpu.shares +| |--repos-2 +| | |--cpu.shares +| |--repos-3 +| | |--cpu.shares +| |--repos-4 +| | |--cpu.shares +| |--repos-5 +| | |--cpu.shares +| |--repos-6 +| | |--cpu.shares +| |--repos-7 +| | |--cpu.shares +| |--repos-8 +| | |--cpu.shares +| |--repos-9 +| | |--cpu.shares +| |--repos-10 +| |--cpu.shares +``` diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/logging.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/logging.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/logging.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/logging.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/praefect.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/praefect.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/configuration/praefect.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/configuration/praefect.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/dashboards.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/dashboards.md similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/dashboards.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/dashboards.md index 7e602f08e1..fa4aa5d470 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/dashboards.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/dashboards.md @@ -17,9 +17,9 @@ Many custom metrics were also added. ### Grafana -To display the prometheus metrics, GitLab leverages Grafana. Two instances are -available to view the dashboards. The dashboards can be found at: -[dashboards.gitlab.com](https://dashboards.gitlab.com). +To display the prometheus metrics, GitLab leverages Grafana. The instance is +available only for GitLab team members to view the dashboards. The dashboards can be found at: +[dashboards.gitlab.net](https://dashboards.gitlab.net). #### Editing Gitaly dashboards @@ -32,7 +32,7 @@ necessary. If you want to make a change across a tiled Grafana dashboard such as the [feature request rate -overview](https://performance.gitlab.net/dashboard/db/gitaly-features-overview), +overview](https://dashboards.gitlab.net/dashboard/db/gitaly-features-overview), then edit the first tile (top left). Its settings get applied to the other tiles as well. If you edit any tile other than the first your changes will be lost. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/delta_islands.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/delta_islands.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/delta_islands.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/delta_islands.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_diskcache.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_diskcache.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_diskcache.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_diskcache.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_ha.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_ha.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_ha.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_ha.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_pack_objects_cache.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_pack_objects_cache.md similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_pack_objects_cache.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_pack_objects_cache.md index a44a676792..fca4c9e462 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/design_pack_objects_cache.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/design_pack_objects_cache.md @@ -34,7 +34,7 @@ The whole pack-objects cache path depends on option. When upload-pack would run git pack-objects to create a packfile for a client, it will run `gitaly-hooks` binary instead. The arguments when calling `gitaly-hooks` includes `git pack-objects` at the beginning. This pattern is -similar to how Gitaly handles Git hooks during a push (such as `pre-preceive` +similar to how Gitaly handles Git hooks during a push (such as `pre-receive` and `post-receive`). ## Problem scope diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/git-execution-environments.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/git-execution-environments.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/git-execution-environments.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/git-execution-environments.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/gitaly-backup.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/gitaly-backup.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/gitaly-backup.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/gitaly-backup.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/hooks.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/hooks.md similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/hooks.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/hooks.md index e1afd7bdf9..821367ca5c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/hooks.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/hooks.md @@ -36,12 +36,31 @@ execute the hook logic inside of the Gitaly server process. It uses the injected information to connect to Gitaly and execute the respective RPC call. The execution path is: -1. Git locates the hook using `core.hooksPath`. If found, this is a symlink - which points to the `gitaly-hooks` executable. +1. Gitaly symlinks `pre-receive`, `update`, `post-receive`, and + `reference-transaction` hooks to the `gitaly-hooks` binary from a + subdirectory of Gitaly's runtime directory. +1. Git locates the hook using `core.hooksPath`. 1. `gitaly-hooks` connects to Gitaly and executes the corresponding RPC call in Gitaly, passing along any hook-specific information to the RPC. 1. Gitaly performs the hook-specific logic in the RPC handler. +## `gitaly-hooks` binary + +`gitaly-hooks` is a binary that is the single point of entry for git hooks +through gitaly. + +### Subcommands + +`gitaly-hooks` has the following subcommands: + +| subcommand | purpose | arguments | stdin | +|----------------|----------|-----------|--------| +| `pre-receive` | used as the git pre-receive hook none | `` SP `` SP `` LF | +| `update` | used as the git update hook | `` `` `` | none +| `post-receive` | used as the git post-receive hook | none | `` SP `` SP `` LF | +| `reference-transaction` | used as the git reference-transactionhook | `prepared|committed|aborted` | `` SP `` SP `` LF | +| `git` | used as the git pack-objects hook | `pack-objects` `[--stdout]` `[--shallow-file]` | `` | + ## Hook-specific logic The logic implemented in Gitaly's hook RPC handlers depends on which hook is diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/img/rugged-new-timings.png b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/img/rugged-new-timings.png similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/img/rugged-new-timings.png rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/img/rugged-new-timings.png diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/logging.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/logging.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/logging.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/logging.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/object_pools.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/object_pools.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/object_pools.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/object_pools.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/object_quarantine.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/object_quarantine.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/object_quarantine.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/object_quarantine.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/observability.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/observability.md similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/observability.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/observability.md index 44819d0630..cf5ddd9db1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/observability.md +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/observability.md @@ -9,7 +9,7 @@ necessary. If you want to make a change across a tiled Grafana dashboard such as the [feature request rate -overview](https://performance.gitlab.net/dashboard/db/gitaly-features-overview), +overview](https://dashboards.gitlab.net/d/000000198/gitaly-features-overview?orgId=1), then edit the first tile (top left). Its settings get applied to the other tiles as well. If you edit any tile other than the first your changes will be lost. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/protobuf.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/protobuf.md new file mode 100644 index 0000000000..4ed62296f5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/protobuf.md @@ -0,0 +1,386 @@ +# Protobuf specifications and client libraries for Gitaly + +Gitaly is part of GitLab. It is a [server +application](https://gitlab.com/gitlab-org/gitaly) that uses its own +gRPC protocol to communicate with its clients. This repository +contains the protocol definition and automatically generated wrapper +code for Go and Ruby. + +The `.proto` files define the remote procedure calls for interacting +with Gitaly. We keep auto-generated client libraries for Ruby and Go +in their respective subdirectories. The list of RPCs can be +[found here](https://gitlab-org.gitlab.io/gitaly-proto/). + +Run `make proto` from the root of the repository to regenerate the client +libraries after updating .proto files. + +See +[developers.google.com](https://developers.google.com/protocol-buffers/docs/proto3) +for documentation of the 'proto3' Protocol buffer specification +language. + +## gRPC/Protobuf concepts + +The core Protobuf concepts we use are rpc, service and message. We use +these to define the Gitaly **protocol**. + +- **rpc** a function that can be called from the client and that gets + executed on the server. Belongs to a service. Can have one of four + request/response signatures: message/message (example: get metadata for + commit xxx), message/stream (example: get contents of blob xxx), + stream/message (example: create new blob with contents xxx), + stream/stream (example: git SSH session). +- **service** a logical group of RPC's. +- **message** like a JSON object except it has pre-defined types. +- **stream** an unbounded sequence of messages. In the Ruby clients + this looks like an Enumerator. + +gRPC provides an implementation framework based on these Protobuf concepts. + +- A gRPC **server** implements one or more services behind a network + listener. Example: the Gitaly server application. +- The gRPC toolchain automatically generates **client libraries** that + handle serialization and connection management. Example: the Go + client package and Ruby gem in this repository. +- gRPC **clients** use the client libraries to make remote procedure + calls. These clients must decide what network address to reach their + gRPC servers on and handle connection reuse: it is possible to + spread different gRPC services over multiple connections to the same + gRPC server. +- Officially a gRPC connection is called a **channel**. In the Go gRPC + library these channels are called **client connections** because + 'channel' is already a concept in Go itself. In Ruby a gRPC channel + is an instance of GRPC::Core::Channel. We use the word 'connection' + in this document. The underlying transport of gRPC, HTTP/2, allows + multiple remote procedure calls to happen at the same time on a + single connection to a gRPC server. In principle, a multi-threaded + gRPC client needs only one connection to a gRPC server. + +## Gitaly RPC Server Architecture + +Gitaly consists of two different server applications which implement services: + +- Gitaly hosts all the logic required to access and modify Git repositories. + This is the place where actual repositories reside and where the Git commands + get executed. + +- Praefect is a transparent proxy that routes requests to one or more Gitaly + nodes. This server allows for load-balancing and high availability by keeping + multiple Gitaly nodes up-to-date with the same data. + +Gitaly clients either interact with Praefect or with a single Gitaly server. For +most of the part the client does not need to know which of both types of servers +it is currently interacting with: Praefect transparently proxies requests to +Gitaly servers so that it behaves the same as a standalone Gitaly server. + +Servers can be sharded for larger installations so that only a subset of data is +stored on each of the Gitaly servers. + +## Design + +### RPC definitions + +Each RPC `FooBar` has its own `FooBarRequest` and `FooBarResponse` message +types. Try to keep the structure of these messages as flat as possible. Only add +abstractions when they have a practical benefit. + +We never make backwards incompatible changes to an RPC that is already +implemented on either the client side or server side. Instead we just create a +new RPC call and start a deprecation procedure (see below) for the old one. + +### Comments + +Services, RPCs, messages and their fields declared in `.proto` files must have +comments. This documentation must be sufficient to let potential callers figure +out why this RPC exists and what the behaviour of an RPC is without looking up +its implementation. Special error cases should be documented. + +### Errors + +Gitaly uses [error codes](https://pkg.go.dev/google.golang.org/grpc/codes) to +indicate basic error classes. In case error codes are not sufficient for clients +to make specific error cases actionable, Gitaly uses the [rich error +model](https://www.grpc.io/docs/guides/error/#richer-error-model) provided by +gRPC. With this error model, Gitaly can embed Protobuf messages into returned +errors and thus provide exact information about error conditions to the client. +In case the RPC needs to use the rich error model, it should have its own +`FooBarError` message type. + +RPCs must return an error if the action failed. It is disallowed to return +specific error cases via the RPC's normal response. This is required so that +Praefect can correctly handle any such errors. + +### RPC concepts + +RPCs should not be focussed on a single usecase only, but instead they should be +implemented with the underlying Git concept in mind. If they directly map to the +way Git handles specific data instead of directly mapping to the usecase at +hand, then chances are high that the RPC will be reusable for other, yet-unknown +usecases. + +Common concepts that can be considered: + +- Accept revisions as documented in gitrevisions(5) instead of object IDs or + references. If possible, accept an array of revisions instead of a single + revision only so that callers can easily specify revision ranges without + requiring a separate RPC. Furthermore, accept pseudo-revisions like `--not` + and `--all`. +- Accept fully-qualified references instead of branch names. This avoids issues + with ambiguity and makes it possible to use RPCs for references which are not + branches. + +### RPC naming conventions + +Gitaly has RPCs that are resource based, for example when querying for a commit. +Another class of RPCs are operations, where the result might be empty or one of +the RPC error codes but the fact that the operation took place is of importance. + +For all RPCs, start the name with a verb, followed by an entity, and if required +followed by a further specification. For example: + +- ListCommits +- RepackRepositoryIncremental +- CreateRepositoryFromBundle + +For resource RPCs the verbs in use are limited to: + +- Get +- List +- Is +- Create +- Update +- Delete + +Get and List as verbs denote these operations have no side effects. These verbs +differ in terms of the expected number of results the query yields. Get queries +are limited to one result, and are expected to return one result to the client. +List queries have zero or more results, and generally will create a gRPC stream +for their results. + +When the `Is` verb is used, this RPC is expected to return a boolean, or an +error. For example: `IsRepositoryEmpty`. + +When an operation-based RPC is defined, the verb should map to the first verb in +the Git command it represents, e.g. `FetchRemote`. + +Note that large parts of the current Gitaly RPC interface do not abide fully to +these conventions. Newly defined RPCs should, though, so eventually the +interface converges to a common standard. + +### Common field names and types + +As a general principle, remember that Git does not enforce encodings on most +data inside repositories, so we can rarely assume data to be a Protobuf "string" +(which implies UTF-8). + +1. `bytes revision`: for fields that accept any of branch names / tag + names / commit ID's. Uses `bytes` to be encoding agnostic. +2. `string commit_id`: for fields that accept a commit ID. +3. `bytes ref`: for fields that accept a refname. +4. `bytes path`: for paths inside Git repositories, i.e., inside Git + `tree` objects. +5. `string relative_path`: for paths on disk on a Gitaly server, + created by "us" (GitLab the application) instead of the user, we + want to use UTF-8, or better, ASCII. + +### Stream patterns + +Protobuf suppports streaming RPCs which allow for multiple request or response +messages to be sent in a single RPC call. We use these whenever it is expected +that an RPC may be invoked with lots of input parameters or when it may generate +a lot of data. This is required by limitations in the gRPC framework where +messages should not typically be larger than 1MB. + +#### Stream response of many small items + +``` +rpc FooBar(FooBarRequest) returns (stream FooBarResponse); + +message FooBarResponse { + message Item { + // ... + } + repeated Item items = 1; +} +``` + +A typical example of an "Item" would be a commit. To avoid the penalty of +network IO for each Item we return, we batch them together. You can think of +this as a kind of buffered IO at the level of the Item messages. In Go, to ease +the bookkeeping you can use +[gitlab.com/gitlab-org/gitaly/internal/helper/chunker](https://godoc.org/gitlab.com/gitlab-org/gitaly/internal/helper/chunker). + +#### Single large item split over multiple messages + +``` +rpc FooBar(FooBarRequest) returns (stream FooBarResponse); + +message FooBarResponse { + message Header { + // ... + } + + oneof payload { + Header header = 1; + bytes data = 2; + } +} +``` + +A typical example of a large item would be the contents of a Git blob. The +header might contain the blob OID and the blob size. Only the first message in +the response stream has `header` set, all others have `data` but no `header`. + +In the particular case where you're sending back raw binary data from Go, you +can use +[gitlab.com/gitlab-org/gitaly/streamio](https://godoc.org/gitlab.com/gitlab-org/gitaly/streamio) +to turn your gRPC response stream into an `io.Writer`. + +> Note that a number of existing RPC's do not use this pattern exactly; +> they don't use `oneof`. In practice this creates ambiguity (does the +> first message contain non-empty `data`?) and encourages complex +> optimization in the server implementation (trying to squeeze data into +> the first response message). Using `oneof` avoids this ambiguity. + +#### Many large items split over multiple messages + +``` +rpc FooBar(FooBarRequest) returns (stream FooBarResponse); + +message FooBarResponse { + message Header { + // ... + } + + oneof payload { + Header header = 1; + bytes data = 2; + } +} +``` + +This looks the same as the "single large item" case above, except whenever a new +large item begins, we send a new message with a non-empty `header` field. + +#### Footers + +If the RPC requires it we can also send a footer using `oneof`. But by default, +we prefer headers. + +### RPC Annotations + +Gitaly Cluster needs to know about the nature of RPCs in order to decide how a +specific request needs to be routed: + +- Accessors may be routed to any one Gitaly node which has an up-to-date + repository to allow for load-balancing reads. These RPCs must not have any + side effects. +- Mutators will be routed to all Gitaly nodes which have an up-to-date + repository so that changes are performed on all nodes at once. Each node is + expected to cast transactional votes so that the actual data that is written + to disk is verified to be the same for all of them. +- Maintenance RPCs are not deemed mission critical. They are routed on a + best-effort basis to all online nodes which have a specific repository. + +To classify RPCs, each declaration must contain one of the following lines: + +- `option (op_type).op = ACCESSOR;` +- `option (op_type).op = MUTATOR;` +- `option (op_type).op = MAINTENANCE;` + +We use a custom `protoc` plugin to verify that all RPCs do in fact have such a +declaration. This plugin can be executed via `make lint-proto`. + +Additionally, all mutator RPCs require additional annotations to clearly +indicate what is being modified: + +- Server-scoped RPCs modify server-wide resources. +- Storage-scoped RPCs modify data in a specific storage. +- Repository-scoped RPCs modify data in a specific repository. + +To declare the scope, mutators must contain one of the following lines: + +- `option(op_type).scope = SERVER;` +- `option(op_type).scope = STORAGE;`: The associated request must have a field + tagged with `[(storage)=true]` that indicates the storage's name. +- `option(op_type).scope = REPOSITORY;`: This is the default scoped and thus + doesn't need to be explicitly declared. The associated request must have a + field tagged with `[(target_repository)=true]` that indcates the repository's + location. + +The target repository represents the location or address of the repository being +modified by the operation. This is needed by Praefect (Gitaly Cluster) in order +to properly schedule replications to keep repository replicas up to date. + +The target repository annotation marks where the target repository can be found +in the message. The annotation is added near `gitaly.Repository` field (e.g. +`Repository repository = 1 [(target_repository)=true];`). If annotated field +isn't `gitaly.Repository` type then it has to contain field annotated +`[(repository)=true]` with correct type. Having separate `repository` annotation +allows to have same field in child message annotated as both `target_repository` +and `additional_repository` depending on parent message. + +The additional repository is annotated similarly to target repository but +annotation is named `additional_repository`. + +See our examples of [valid](go/internal/cmd/protoc-gen-gitaly-lint/testdata/valid.proto) and +[invalid](go/internal/cmd/protoc-gen-gitaly-lint/invalid.proto) proto annotations. + +### Transactions and Atomicity + +With Gitaly Cluster, mutating RPCs will get routed to multiple Gitaly nodes at +once. Each node must then vote on the changes it intends to perform, and only if +quorum was reached on the change should it be persisted to disk. For this to +work correctly, all mutating RPCs need to follow a set of rules: + +- Every mutator needs to vote at least twice on the data it is about to write: a + first preparatory vote must happen before data is visible to the user so that + data can be discarded in case nodes disagree without any impact on the + repository itself. And a second committing vote must happen to let Praefect + know that changes have indeed been committed to disk. +- In the general case, the vote should be computed from all data that is to be + written. +- Changes should be atomic: either all changes are persisted to disk or none + are. +- The number of transactional votes should be kept at a minimum and should not + scale with the number of changes performed. Every vote incurs costs, which may + become prohibitively expensive in case a vote is executed per change. +- Mutators must return an error in case anything unexpected happens. This error + needs to be deterministic so that Praefect can assert that a failing RPC call + has failed in the same way across nodes. + +### Go Package + +All Protobuf files hosted in the Gitaly project must have their Go package +declared. This is done via the `go_package` option: + +`option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb";` + +This allows other protobuf files to locate and import the Go generated stubs. + +## Workflows + +### Generating Protobuf sources + +After you change or add a .proto file you need to re-generate the Go and Ruby +libraries before committing your change. + +```shell +# Re-generate Go and Ruby libraries +make proto +``` + +### Verifying Protobuf definitions + +Gitaly provides a `make lint-proto` target to verify that Protobuf definitions +conform to our coding style. Furthermore, Gitaly's CI verifies that sources +generated from the definitions are up-to-date by regenerating sources and then +running `no-proto-changes`. + +### Deprecating an RPC call + +See [PROCESS.md](PROCESS.md#rpc-deprecation-process). + +## Releasing Protobuf definitions + +See [PROCESS.md](PROCESS.md#publishing-the-ruby-gem). diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/reading_git_source.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/reading_git_source.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/reading_git_source.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/reading_git_source.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/praefect-queue-storage.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/praefect-queue-storage.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/praefect-queue-storage.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/praefect-queue-storage.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/snapshot-storage.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/snapshot-storage.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/snapshot-storage.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/snapshot-storage.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/template.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/template.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/rfcs/template.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/rfcs/template.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/ruby_endpoint.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/ruby_endpoint.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/ruby_endpoint.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/ruby_endpoint.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/serverside_git_usage.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/serverside_git_usage.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/serverside_git_usage.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/serverside_git_usage.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/sidechannel.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/sidechannel.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/sidechannel.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/sidechannel.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/sql_migrations.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/sql_migrations.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/sql_migrations.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/sql_migrations.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/test_repos.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/test_repos.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/test_repos.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/test_repos.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/virtual_storage.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/virtual_storage.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/doc/virtual_storage.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/doc/virtual_storage.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/gitaly.gemspec b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/gitaly.gemspec similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/gitaly.gemspec rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/gitaly.gemspec diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.mod b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.mod new file mode 100644 index 0000000000..b65bc03d2f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.mod @@ -0,0 +1,188 @@ +module gitlab.com/gitlab-org/gitaly/v15 + +go 1.17 + +// It is a temporary solution, please see https://gitlab.com/gitlab-org/gitaly/-/issues/4423 for details. +replace github.com/go-enry/go-license-detector/v4 => github.com/pavelmemory/go-license-detector/v4 v4.3.1-0.20220801101717-a7c9e28533cf + +require ( + github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 + github.com/beevik/ntp v0.3.0 + github.com/cloudflare/tableflip v1.2.3 + github.com/containerd/cgroups v1.0.4 + github.com/getsentry/sentry-go v0.13.0 + github.com/git-lfs/git-lfs/v3 v3.2.0 + github.com/go-enry/go-enry/v2 v2.8.2 + github.com/go-enry/go-license-detector/v4 v4.3.0 + github.com/golang-jwt/jwt/v4 v4.4.1 + github.com/google/go-cmp v0.5.8 + github.com/google/uuid v1.3.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/hashicorp/golang-lru v0.5.4 + github.com/hashicorp/yamux v0.1.1 + github.com/jackc/pgconn v1.13.0 + github.com/jackc/pgtype v1.12.0 + github.com/jackc/pgx/v4 v4.17.2 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/libgit2/git2go/v33 v33.0.9 + github.com/olekukonko/tablewriter v0.0.5 + github.com/opencontainers/runtime-spec v1.0.2 + github.com/opentracing/opentracing-go v1.2.0 + github.com/pelletier/go-toml/v2 v2.0.5 + github.com/prometheus/client_golang v1.12.2 + github.com/prometheus/client_model v0.2.0 + github.com/rubenv/sql-migrate v1.1.2 + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.0 + github.com/uber/jaeger-client-go v2.30.0+incompatible + gitlab.com/gitlab-org/labkit v1.16.0 + go.uber.org/goleak v1.1.12 + gocloud.dev v0.26.0 + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 + google.golang.org/grpc v1.49.0 + google.golang.org/protobuf v1.28.1 +) + +require ( + cloud.google.com/go v0.100.2 // indirect + cloud.google.com/go/compute v1.5.0 // indirect + cloud.google.com/go/iam v0.3.0 // indirect + cloud.google.com/go/monitoring v1.4.0 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/storage v1.21.0 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // indirect + github.com/Azure/azure-pipeline-go v0.2.3 // indirect + github.com/Azure/azure-storage-blob-go v0.14.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.22 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.17 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/DataDog/datadog-go v4.4.0+incompatible // indirect + github.com/DataDog/sketches-go v1.0.0 // indirect + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 // indirect + github.com/avast/retry-go v3.0.0+incompatible // indirect + github.com/aws/aws-sdk-go v1.43.31 // indirect + github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect + github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect + github.com/aws/smithy-go v1.11.2 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/client9/reopen v1.0.0 // indirect + github.com/cloudflare/circl v1.1.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db // indirect + github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1 // indirect + github.com/emirpasic/gods v1.12.0 // indirect + github.com/git-lfs/gitobj/v2 v2.1.0 // indirect + github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a // indirect + github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825 // indirect + github.com/git-lfs/wildmatch/v2 v2.0.1 // indirect + github.com/go-enry/go-oniguruma v1.2.1 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.1.0 // indirect + github.com/go-git/go-git/v5 v5.3.0 // indirect + github.com/go-gorp/gorp/v3 v3.0.2 // indirect + github.com/go-ole/go-ole v1.2.4 // indirect + github.com/godbus/dbus/v5 v5.0.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/wire v0.5.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jcmturner/goidentity/v6 v6.0.1 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jdkato/prose v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect + github.com/leonelquinteros/gotext v1.5.0 // indirect + github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect + github.com/lightstep/lightstep-tracer-go v0.25.0 // indirect + github.com/mattn/go-ieproxy v0.0.3 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb // indirect + github.com/oklog/ulid/v2 v2.0.2 // indirect + github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 // indirect + github.com/philhofer/fwd v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect + github.com/sergi/go-diff v1.1.0 // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/ssgelm/cookiejarparser v1.0.1 // indirect + github.com/tinylib/msgp v1.1.2 // indirect + github.com/tklauser/go-sysconf v0.3.4 // indirect + github.com/tklauser/numcpus v0.2.1 // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + github.com/xanzy/ssh-agent v0.3.0 // indirect + go.opencensus.io v0.23.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gonum.org/v1/gonum v0.8.2 // indirect + google.golang.org/api v0.74.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/neurosnap/sentences.v1 v1.0.6 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +exclude ( + // CVE-2020-28483 + github.com/gin-gonic/gin v1.4.0 + github.com/gin-gonic/gin v1.6.3 +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.sum b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.sum similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.sum rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.sum index cd5e2b4791..9979b97313 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/go.sum +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/go.sum @@ -1,9 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -21,103 +18,138 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.5.0/go.mod h1:c4nNYR1qdq7eaZ+jSc5fonrQN2k3M7sWATcYTiakjEo= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= +cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= +cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= +cloud.google.com/go/monitoring v1.4.0/go.mod h1:y6xnxfwI3hTFWOdkOaD7nfJVlwuC3/mS/5kvtT131p4= +cloud.google.com/go/profiler v0.1.0 h1:MG/rxKC1MztRfEWMGYKFISxyZak5hNh29f0A/z2tvWk= +cloud.google.com/go/profiler v0.1.0/go.mod h1:D7S7LV/zKbRWkOzYL1b5xytpqt8Ikd/v/yvf1/Tx2pQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.10.3/go.mod h1:FUcc28GpGxxACoklPsE1sCtbkY4Ix+ro7yvw+h82Jn4= +cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.15.0 h1:Ljj+ZXVEhCr/1+4ZhvtteN1ND7UUsNTlduGclLh8GO0= -cloud.google.com/go/storage v1.15.0/go.mod h1:mjjQMoxxyGH7Jr8K5qrx6N2O0AHsczI61sMNn03GIZI= +cloud.google.com/go/storage v1.21.0 h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14= +cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= +cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= +cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= +cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= +cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -contrib.go.opencensus.io/exporter/stackdriver v0.13.8 h1:lIFYmQsqejvlq+GobFUbC5F0prD5gvhP6r0gWLZRDq4= contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= +github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v54.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0 h1:lgWHvFh+UYBNVQLFHXkvul2f6yOPA9PIH82RTG2cSwc= -github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= -github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= -github.com/Azure/go-amqp v0.13.4/go.mod h1:wbpCKA8tR5MLgRyIu+bb+S6ECdIDdYJ0NlpFE9xsBPI= -github.com/Azure/go-amqp v0.13.7/go.mod h1:wbpCKA8tR5MLgRyIu+bb+S6ECdIDdYJ0NlpFE9xsBPI= +github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= +github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= +github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= -github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7 h1:8DQB8yl7aLQuP+nuR5e2RO6454OvFlSTXXaNHshc16s= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.17 h1:esOPl2dhcz9P3jqBSJ8tPGEj2EqzPPT6zfyuloiogKY= +github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9 h1:Y2CgdzitFDsdMwYMzf9LIZWrrTFysqbRc7b94XVVJ78= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9/go.mod h1:hg3/1yw0Bq87O3KvvnJoAh34/0zbP7SFizX/qN5JvjU= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= +github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= +github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= +github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= -github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 h1:NsReiLpErIPzRrnogAXYwSoU7txA977LjDGrbkewJbg= +github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= @@ -127,90 +159,128 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858 h1:OZQyEhf4BviydsRdmK4ryeJHotDLd7vL1X8+nnxXkfk= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/avast/retry-go v2.4.2+incompatible h1:+ZjCypQT/CyP0kyJO2EcU4d/ZEJWSbP8NENI578cPmA= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.38.35 h1:7AlAO0FC+8nFjxiGKEmq0QLpiA8/XFr6eIxgRTwkdTg= -github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= +github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA= +github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZMvr6MrSficMtjY2oS0WOORXTlxwU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= +github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw= +github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 h1:ir7iEq78s4txFGgwcLqD6q9IIPzTQNRJXulJd9h/zQo= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 h1:T4pFel53bkHjL2mMo+4DKE6r6AuoZnM0fg7k1/ratr4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 h1:I0dcwWitE752hVSMrsLCxqNQ+UdEp3nACx2bYNMQq+k= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 h1:BKjwCJPnANbkwQ8vzSbaZDKawwagDubrH/z/c0X+kbQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= +github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 h1:rMPtwA7zzkSQZhhz9U3/SoIDz/NZ7Q+iRn4EIO8rSyU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= +github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw= github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= -github.com/cloudflare/tableflip v0.0.0-20190329062924-8392f1641731/go.mod h1:erh4dYezoMVbIa52pi7i1Du7+cXOgqNuTamt10qvMoA= -github.com/cloudflare/tableflip v1.2.2 h1:WkhiowHlg0nZuH7Y2beLVIZDfxtSvKta1f22PEgUN7w= -github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= +github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99 h1:8aDph9eB64Upszigf7VXsoA8NVHNQMpbo8luXmT6DkM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.1 h1:7OO2CXWMYNDdaAzP51t4lCCZWwpQHmvPbm9sxWjm3So= -github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= @@ -221,69 +291,64 @@ github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKs github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dpotapov/go-spnego v0.0.0-20190506202455-c2c609116ad0 h1:Hhh7nu7CfFVlnBJqmDDUh+j1H5fqjLMzM4czZzNNJGM= -github.com/dpotapov/go-spnego v0.0.0-20190506202455-c2c609116ad0/go.mod h1:P4f4MSk7h52F2PK0lCapn5+fu47Uf8aRdxDSqgezxZE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dpotapov/go-spnego v0.0.0-20210315154721-298b63a54430/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db h1:3EIvol92cLWG5m13Me3/LfEtQqr23xzwZCxiWoT5gGE= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1 h1:/7G7q8SDJdrah5jDYqZI8pGFjSqiCzfSEO+NgqKCYX0= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/getsentry/raven-go v0.1.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/raven-go v0.1.2/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= -github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/git-lfs/git-lfs v1.5.1-0.20210304194248-2e1d981afbe3 h1:r78tkUTlPyh0tqILwkDBg0gqmRoqbaQ4b7jIgkWoWRk= -github.com/git-lfs/git-lfs v1.5.1-0.20210304194248-2e1d981afbe3/go.mod h1:8Xqs4mqL7o6xEnaXckIgELARTeK7RYtm3pBab7S79Js= -github.com/git-lfs/gitobj/v2 v2.0.1 h1:mUGOWP+fU36rs7TY7a5Lol9FuockOBjPFUW/lwOM7Mo= -github.com/git-lfs/gitobj/v2 v2.0.1/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18 h1:7Th0eBA4rT8WJNiM1vppjaIv9W5WJinhpbCJvRJxloI= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= -github.com/git-lfs/wildmatch v1.0.4 h1:Mj6LPnNZ6QSHLAAPDCH596pu6A/Z1xVm2Vk0+s3CtkY= -github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/git-lfs/git-lfs/v3 v3.2.0 h1:pQQ1GYjxGJE92TqlWASyTAvNig1vS8mDWdWcXgSP3GA= +github.com/git-lfs/git-lfs/v3 v3.2.0/go.mod h1:GZZO3jw2Yn3/1KFV4nRoXUzH+yPzGypIdTeQpkzxEvQ= +github.com/git-lfs/gitobj/v2 v2.1.0 h1:5BUDAMga0Sv9msMXolrn6xplkiG5RaVEkOir2HSznog= +github.com/git-lfs/gitobj/v2 v2.1.0/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a h1:6pskVZacdMUL93pCpMAYnMDLjH1yDFhssPYGe32sjdk= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825 h1:riQhgheTL7tMF4d5raz9t3+IzoR1i1wqxE1kZC6dY+U= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= +github.com/git-lfs/wildmatch/v2 v2.0.1 h1:Ds+aobrV5bK0wStILUOn9irllPyf9qrFETbKzwzoER8= +github.com/git-lfs/wildmatch/v2 v2.0.1/go.mod h1:EVqonpk9mXbREP3N8UkwoWdrF249uHpCUo5CPXY81gw= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-enry/go-license-detector/v4 v4.3.0 h1:OFlQAVNw5FlKUjX4OuW8JOabu8MQHjTKDb9pdeNYMUw= -github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= +github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR8RI= +github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= +github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -300,10 +365,11 @@ github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4= +github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -314,46 +380,43 @@ github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNI github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.1 h1:ZEgyRGgAm4ZAhAO45YXMs5Fp+bzGLESFewzAVBMKuTg= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1 h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= +github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -361,8 +424,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -381,7 +445,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -396,20 +459,27 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0 h1:B5kVOzJ1hBgnevTgIWhSTatQ3608yu/2NnU0Ta1d0kY= -github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2 h1:HCfx+dQzwN9XbGTHF8qJ+67WN8glL9FTWV5rraCJ/jU= -github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY= +github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2RiqK1NiwAmD0MrKeC9IIks= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -422,39 +492,44 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210125172800-10e9aeb4a998/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.3-0.20210213123510-be4c235f9d1c/go.mod h1:RXwzibsL7UhPcEmGyGvXKJ8kyJsOCOEaLgGce4igMFs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= +github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -464,8 +539,10 @@ github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -477,24 +554,23 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b h1:Jdu2tbAxkRouSILp2EbposIb8h4gO+2QuZEn3d9sKAc= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= @@ -509,8 +585,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8= -github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= +github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -527,89 +604,90 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.9.1 h1:MJc2s0MFS8C3ok1wQTdQxWuXQcB6+HwAm5x1CzW7mf0= -github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= +github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.14.1 h1:71oo1KAGI6mXhLiTMn6iDFcp3e7+zon/capWjl2OEFU= -github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= +github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= +github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdkato/prose v1.1.0 h1:LpvmDGwbKGTgdCH3a8VJL56sr7p/wOFPw/R4lM4PfFg= github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= -github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -619,62 +697,66 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.5.0 h1:ODY7LzLpZWWSJdAHnzhreOr6cwLXTAmc914FOauSkBM= +github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libgit2/git2go v0.0.0-20190104134018-ecaeb7a21d47 h1:HDt7WT3kpXSHq4mlOuLzgXH9LeOK1qlhyFdKIAzxxeM= -github.com/libgit2/git2go v0.0.0-20190104134018-ecaeb7a21d47/go.mod h1:4bKN42efkbNYMZlvDfxGDxzl066GhpvIircZDsm8Y+Y= -github.com/libgit2/git2go/v31 v31.4.12/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec= +github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9 h1:4ch2DJed6IhJO28BEohkUoGvxLsRzUjxljoNFJ6/O78= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0 h1:qGUbkzHP64NA9r+uIbCvf303IzHPr0M4JlkaDMxXqqk= -github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= +github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3 h1:YkaHmK1CzE5C4O7A3hv3TCbfNDPSCf0RKZFX+VhBeYk= +github.com/mattn/go-ieproxy v0.0.3/go.mod h1:6ZpRmhBaYuBX1U2za+9rC9iCGLsSp2tftelZne7CPko= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -685,35 +767,30 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb h1:bsjNADsjHq0gjU7KO7zwoX5k3HtFdf6TDzB3ncl5iUs= github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neurosnap/sentences v1.0.6 h1:iBVUivNtlwGkYsJblWV8GGVFmXzZzak907Ci8aA0VTE= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -723,90 +800,69 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= -github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= -github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pavelmemory/go-license-detector/v4 v4.3.1-0.20220801101717-a7c9e28533cf h1:0hsdCeyyCHec4CFciP7tlz2t7fc4XeS1kXF6DXPWFxQ= +github.com/pavelmemory/go-license-detector/v4 v4.3.1-0.20220801101717-a7c9e28533cf/go.mod h1:3cTg6OLuDbqzstQeL1OUysZZGudU9yLAE+NmURSwmic= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= +github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0 h1:LUa41nrWTQNGhzdsZ5lTnkwbNjj6rXTdazA1cSdjkOY= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237 h1:q6N3WgCVttyX9Fg3e4nrLohUXvAlTu44Ugc4m6qlezc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v1.1.2 h1:9M6oj4e//owVVHYrFISmY9LBRw6gzkCNmD9MV36tZeQ= +github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086 h1:mncRSDOqYCng7jOD+Y6+IivdRI6Kzv2BLWYkWkdQfu0= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= @@ -815,18 +871,16 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM= github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= -github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b h1:VI1u+o2KZPZ5AhuPpXY0JBdpQPnkTx6Dd5XJhK/9MYE= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -836,66 +890,66 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgelm/cookiejarparser v1.0.1 h1:cRdXauUbOTFzTPJFaeiWbHnQ+tRGlpKKzvIK9PUekE4= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible h1:6WVONolFJiB8Vx9bq4z9ddyV/SXSpfvvtb7Yl/TGHiE= -github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= @@ -907,36 +961,25 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= -gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= -gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= -gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= -gitlab.com/gitlab-org/labkit v1.5.0 h1:JUdSgNtAynKffx7eAqSjB76D5H2Y6aYOrn6WCoI6aEw= -gitlab.com/gitlab-org/labkit v1.5.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +gitlab.com/gitlab-org/labkit v1.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= +gitlab.com/gitlab-org/labkit v1.16.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -946,25 +989,30 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -gocloud.dev v0.23.0 h1:u/6F8slWwaZPgGpjpNp0jzH+1P/M2ri7qEP3lFgbqBE= -gocloud.dev v0.23.0/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.26.0 h1:4rM/SVL0lLs+rhC0Gmc+gt/82DBpb7nbpIZKXXnfMXg= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -972,26 +1020,28 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1010,7 +1060,6 @@ golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8H golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1021,8 +1070,9 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1033,18 +1083,16 @@ 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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1058,7 +1106,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1068,7 +1115,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1085,10 +1131,21 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98= -golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1101,9 +1158,17 @@ golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1114,16 +1179,15 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1134,33 +1198,28 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1177,25 +1236,49 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= -golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1203,20 +1286,19 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1237,12 +1319,10 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1257,6 +1337,7 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -1277,8 +1358,14 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1293,13 +1380,10 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1318,26 +1402,42 @@ google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= -google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= +google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7TH8= +google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1358,6 +1458,7 @@ google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1376,23 +1477,54 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de h1:9Ti5SG2U4cAcluryUo/sFay3TQKoxiFMfaT0pbizU7k= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1402,14 +1534,24 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1421,11 +1563,13 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/DataDog/dd-trace-go.v1 v1.7.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= -gopkg.in/DataDog/dd-trace-go.v1 v1.30.0 h1:yJJrDYzAlUsDPpAVBjv4VFnXKTbgvaJFTX0646xDPi4= -gopkg.in/DataDog/dd-trace-go.v1 v1.30.0/go.mod h1:SnKViq44dv/0gjl9RpkP0Y2G3BJSRkp6eYdCSu39iI8= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1433,38 +1577,22 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v2 v2.0.0 h1:6Bmcdaxb0dD3HyHbo/MtJ2Q1wXLDuZJFwXZmuZvM+zw= -gopkg.in/jcmturner/goidentity.v2 v2.0.0/go.mod h1:vCwK9HeXksMeUmQ4SxDd1tRz4LejrKh3KRVjQWhjvZI= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0 h1:RS1MYApX27Hx1Xw7NECs7XxGxxrm69/4OmaRuX9kwec= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= -gopkg.in/jcmturner/rpc.v0 v0.0.2 h1:wBTgrbL1qmLBUPsYVCqdJiI5aJgQhexmK+JkTHPUNJI= -gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6 h1:v7ElyP020iEZQONyLld3fHILHWOPs+ntzuQTNPkul8E= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1472,9 +1600,10 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1482,11 +1611,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_example_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_example_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_example_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_example_test.go index 63f4e5c5d1..32fec88797 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_example_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_example_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backchannel_test import ( @@ -6,9 +8,9 @@ import ( "net" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) @@ -121,7 +123,7 @@ func invokeWithMuxedClient(logger *logrus.Entry, address string) error { } func invokeWithNormalClient(address string) error { - return invokeWithOpts(address, grpc.WithInsecure()) + return invokeWithOpts(address, grpc.WithTransportCredentials(insecure.NewCredentials())) } func invokeWithOpts(address string, opts ...grpc.DialOption) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_test.go index 07fd44c8df..e8885629ad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/backchannel_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/backchannel_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backchannel import ( @@ -13,9 +15,9 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -92,7 +94,7 @@ func TestBackchannel_concurrentRequestsFromMultipleClients(t *testing.T) { defer wg.Done() <-start - client, err := grpc.Dial(ln.Addr().String(), grpc.WithInsecure()) + client, err := grpc.Dial(ln.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) if !assert.NoError(t, err) { return } @@ -272,7 +274,7 @@ func Benchmark(b *testing.B) { go srv.Serve(ln) ctx := testhelper.Context(b) - opts := []grpc.DialOption{grpc.WithBlock(), grpc.WithInsecure()} + opts := []grpc.DialOption{grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials())} if tc.multiplexed { clientHandshaker := NewClientHandshaker(newLogger(), func() Server { return grpc.NewServer() }) opts = []grpc.DialOption{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/client.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/client.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/client.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/client.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/registry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/registry.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/registry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/registry.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/server.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/server.go index b277b727ad..9e0f0537a1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backchannel/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backchannel/server.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/peer" ) @@ -114,12 +115,12 @@ func (s *ServerHandshaker) Handshake(conn net.Conn, authInfo credentials.AuthInf } // The address does not actually matter but we set it so clientConn.Target returns a meaningful value. - // WithInsecure is used as the multiplexer operates within a TLS session already if one is configured. + // Insecure credentials are used as the multiplexer operates within a TLS session already if one is configured. backchannelConn, err := grpc.Dial( "multiplexed/"+conn.RemoteAddr().String(), append( s.dialOpts, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return muxSession.Open() }), )..., ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup.go index f596b216d0..c228ba706d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup.go @@ -8,13 +8,13 @@ import ( "net/url" "strings" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "gocloud.dev/blob/azureblob" "gocloud.dev/blob/gcsblob" "gocloud.dev/blob/s3blob" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup_test.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup_test.go index d47221f6ac..d66fa6902f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/backup_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/backup_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -8,16 +10,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -34,15 +36,15 @@ func TestManager_Create(t *testing.T) { for _, tc := range []struct { desc string - setup func(t testing.TB) (*gitalypb.Repository, string) + setup func(tb testing.TB) (*gitalypb.Repository, string) createsBundle bool createsCustomHooks bool err error }{ { desc: "no hooks", - setup: func(t testing.TB) (*gitalypb.Repository, string) { - noHooksRepo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + setup: func(tb testing.TB) (*gitalypb.Repository, string) { + noHooksRepo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ RelativePath: "no-hooks", Seed: gittest.SeedGitLabTest, }) @@ -53,13 +55,13 @@ func TestManager_Create(t *testing.T) { }, { desc: "hooks", - setup: func(t testing.TB) (*gitalypb.Repository, string) { - hooksRepo, hooksRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + setup: func(tb testing.TB) (*gitalypb.Repository, string) { + hooksRepo, hooksRepoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ RelativePath: "hooks", Seed: gittest.SeedGitLabTest, }) - require.NoError(t, os.Mkdir(filepath.Join(hooksRepoPath, "custom_hooks"), os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(hooksRepoPath, "custom_hooks/pre-commit.sample"), []byte("Some hooks"), os.ModePerm)) + require.NoError(tb, os.Mkdir(filepath.Join(hooksRepoPath, "custom_hooks"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(hooksRepoPath, "custom_hooks/pre-commit.sample"), []byte("Some hooks"), os.ModePerm)) return hooksRepo, hooksRepoPath }, createsBundle: true, @@ -67,8 +69,8 @@ func TestManager_Create(t *testing.T) { }, { desc: "empty repo", - setup: func(t testing.TB) (*gitalypb.Repository, string) { - emptyRepo, repoPath := gittest.CreateRepository(ctx, t, cfg) + setup: func(tb testing.TB) (*gitalypb.Repository, string) { + emptyRepo, repoPath := gittest.CreateRepository(ctx, tb, cfg) return emptyRepo, repoPath }, createsBundle: false, @@ -77,8 +79,8 @@ func TestManager_Create(t *testing.T) { }, { desc: "nonexistent repo", - setup: func(t testing.TB) (*gitalypb.Repository, string) { - emptyRepo, repoPath := gittest.CreateRepository(ctx, t, cfg) + setup: func(tb testing.TB) (*gitalypb.Repository, string) { + emptyRepo, repoPath := gittest.CreateRepository(ctx, tb, cfg) nonexistentRepo := proto.Clone(emptyRepo).(*gitalypb.Repository) nonexistentRepo.RelativePath = "nonexistent" return nonexistentRepo, repoPath @@ -162,8 +164,8 @@ func TestManager_Create_incremental(t *testing.T) { }{ { desc: "no previous backup", - setup: func(t testing.TB, backupRoot string) (*gitalypb.Repository, string) { - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + setup: func(tb testing.TB, backupRoot string) (*gitalypb.Repository, string) { + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ RelativePath: "repo", Seed: gittest.SeedGitLabTest, }) @@ -173,8 +175,8 @@ func TestManager_Create_incremental(t *testing.T) { }, { desc: "previous backup, no updates", - setup: func(t testing.TB, backupRoot string) (*gitalypb.Repository, string) { - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + setup: func(tb testing.TB, backupRoot string) (*gitalypb.Repository, string) { + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ RelativePath: "repo", Seed: gittest.SeedGitLabTest, }) @@ -184,14 +186,14 @@ func TestManager_Create_incremental(t *testing.T) { bundlePath := filepath.Join(backupPath, "001.bundle") refsPath := filepath.Join(backupPath, "001.refs") - require.NoError(t, os.MkdirAll(backupPath, os.ModePerm)) - gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") + require.NoError(tb, os.MkdirAll(backupPath, os.ModePerm)) + gittest.Exec(tb, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") - refs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head") - require.NoError(t, os.WriteFile(refsPath, refs, os.ModePerm)) + refs := gittest.Exec(tb, cfg, "-C", repoPath, "show-ref", "--head") + require.NoError(tb, os.WriteFile(refsPath, refs, os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) return repo, repoPath }, @@ -199,8 +201,8 @@ func TestManager_Create_incremental(t *testing.T) { }, { desc: "previous backup, updates", - setup: func(t testing.TB, backupRoot string) (*gitalypb.Repository, string) { - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + setup: func(tb testing.TB, backupRoot string) (*gitalypb.Repository, string) { + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ RelativePath: "repo", Seed: gittest.SeedGitLabTest, }) @@ -210,16 +212,16 @@ func TestManager_Create_incremental(t *testing.T) { bundlePath := filepath.Join(backupPath, "001.bundle") refsPath := filepath.Join(backupPath, "001.refs") - require.NoError(t, os.MkdirAll(backupPath, os.ModePerm)) - gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") + require.NoError(tb, os.MkdirAll(backupPath, os.ModePerm)) + gittest.Exec(tb, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") - refs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head") - require.NoError(t, os.WriteFile(refsPath, refs, os.ModePerm)) + refs := gittest.Exec(tb, cfg, "-C", repoPath, "show-ref", "--head") + require.NoError(tb, os.WriteFile(refsPath, refs, os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master")) + gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch("master")) return repo, repoPath }, @@ -282,32 +284,36 @@ func testManagerRestore(t *testing.T, ctx context.Context) { repoClient := gitalypb.NewRepositoryServiceClient(cc) - createRepo := func(t testing.TB) *gitalypb.Repository { - t.Helper() + createRepo := func(tb testing.TB) *gitalypb.Repository { + tb.Helper() repo := &gitalypb.Repository{ StorageName: "default", - RelativePath: gittest.NewRepositoryName(t, false), + RelativePath: gittest.NewRepositoryName(tb, false), } _, err := repoClient.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{Repository: repo}) - require.NoError(t, err) + require.NoError(tb, err) // The repository might be created through Praefect and the tests reach into the repository directly // on the filesystem. To ensure the test accesses correct directory, we need to rewrite the relative // path if the repository creation went through Praefect. - repo.RelativePath = gittest.GetReplicaPath(ctx, t, cfg, repo) + repo.RelativePath = gittest.GetReplicaPath(ctx, tb, cfg, repo) return repo } + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + repoChecksum := gittest.ChecksumRepo(t, cfg, repoPath) + path := testhelper.TempDir(t) - testRepoChecksum := gittest.ChecksumTestRepo(t, cfg, "gitlab-test.git") for _, tc := range []struct { desc string locators []string - setup func(t testing.TB) (*gitalypb.Repository, *git.Checksum) + setup func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) alwaysCreate bool expectExists bool expectedPaths []string @@ -316,28 +322,28 @@ func testManagerRestore(t *testing.T, ctx context.Context) { { desc: "existing repo, without hooks", locators: []string{"legacy", "pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { - repo := createRepo(t) - require.NoError(t, os.MkdirAll(filepath.Join(path, repo.RelativePath), os.ModePerm)) + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { + repo := createRepo(tb) + require.NoError(tb, os.MkdirAll(filepath.Join(path, repo.RelativePath), os.ModePerm)) bundlePath := filepath.Join(path, repo.RelativePath+".bundle") - gittest.BundleTestRepo(t, cfg, "gitlab-test.git", bundlePath) + gittest.BundleRepo(tb, cfg, repoPath, bundlePath) - return repo, testRepoChecksum + return repo, repoChecksum }, expectExists: true, }, { desc: "existing repo, with hooks", locators: []string{"legacy", "pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { - repo := createRepo(t) + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { + repo := createRepo(tb) bundlePath := filepath.Join(path, repo.RelativePath+".bundle") customHooksPath := filepath.Join(path, repo.RelativePath, "custom_hooks.tar") - require.NoError(t, os.MkdirAll(filepath.Join(path, repo.RelativePath), os.ModePerm)) - gittest.BundleTestRepo(t, cfg, "gitlab-test.git", bundlePath) - testhelper.CopyFile(t, "../gitaly/service/repository/testdata/custom_hooks.tar", customHooksPath) + require.NoError(tb, os.MkdirAll(filepath.Join(path, repo.RelativePath), os.ModePerm)) + gittest.BundleRepo(tb, cfg, repoPath, bundlePath) + testhelper.CopyFile(tb, "../gitaly/service/repository/testdata/custom_hooks.tar", customHooksPath) - return repo, testRepoChecksum + return repo, repoChecksum }, expectedPaths: []string{ "custom_hooks/pre-commit.sample", @@ -349,8 +355,8 @@ func testManagerRestore(t *testing.T, ctx context.Context) { { desc: "missing bundle", locators: []string{"legacy", "pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { - repo := createRepo(t) + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { + repo := createRepo(tb) return repo, nil }, expectedErrAs: ErrSkipped, @@ -358,8 +364,8 @@ func testManagerRestore(t *testing.T, ctx context.Context) { { desc: "missing bundle, always create", locators: []string{"legacy", "pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { - repo := createRepo(t) + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { + repo := createRepo(tb) return repo, new(git.Checksum) }, alwaysCreate: true, @@ -368,80 +374,79 @@ func testManagerRestore(t *testing.T, ctx context.Context) { { desc: "nonexistent repo", locators: []string{"legacy", "pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { repo := &gitalypb.Repository{ StorageName: "default", - RelativePath: gittest.NewRepositoryName(t, false), + RelativePath: gittest.NewRepositoryName(tb, false), } - require.NoError(t, os.MkdirAll(filepath.Dir(filepath.Join(path, repo.RelativePath)), os.ModePerm)) + require.NoError(tb, os.MkdirAll(filepath.Dir(filepath.Join(path, repo.RelativePath)), os.ModePerm)) bundlePath := filepath.Join(path, repo.RelativePath+".bundle") - gittest.BundleTestRepo(t, cfg, "gitlab-test.git", bundlePath) + gittest.BundleRepo(tb, cfg, repoPath, bundlePath) - return repo, testRepoChecksum + return repo, repoChecksum }, expectExists: true, }, { desc: "single incremental", locators: []string{"pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { const backupID = "abc123" - repo := createRepo(t) + repo := createRepo(tb) repoBackupPath := filepath.Join(path, repo.RelativePath) backupPath := filepath.Join(repoBackupPath, backupID) - require.NoError(t, os.MkdirAll(backupPath, os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.MkdirAll(backupPath, os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) bundlePath := filepath.Join(backupPath, "001.bundle") - gittest.BundleTestRepo(t, cfg, "gitlab-test.git", bundlePath) + gittest.BundleRepo(tb, cfg, repoPath, bundlePath) - return repo, testRepoChecksum + return repo, repoChecksum }, expectExists: true, }, { desc: "many incrementals", locators: []string{"pointer"}, - setup: func(t testing.TB) (*gitalypb.Repository, *git.Checksum) { + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { const backupID = "abc123" - expected := createRepo(t) + expected := createRepo(tb) expectedRepoPath := filepath.Join(cfg.Storages[0].Path, expected.RelativePath) - repo := createRepo(t) + repo := createRepo(tb) repoBackupPath := filepath.Join(path, repo.RelativePath) backupPath := filepath.Join(repoBackupPath, backupID) - require.NoError(t, os.MkdirAll(backupPath, os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), os.ModePerm)) + require.NoError(tb, os.MkdirAll(backupPath, os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), os.ModePerm)) - root := gittest.WriteCommit(t, cfg, expectedRepoPath, + root := gittest.WriteCommit(tb, cfg, expectedRepoPath, gittest.WithBranch("master"), - gittest.WithParents(), ) - master1 := gittest.WriteCommit(t, cfg, expectedRepoPath, + master1 := gittest.WriteCommit(tb, cfg, expectedRepoPath, gittest.WithBranch("master"), gittest.WithParents(root), ) - other := gittest.WriteCommit(t, cfg, expectedRepoPath, + other := gittest.WriteCommit(tb, cfg, expectedRepoPath, gittest.WithBranch("other"), gittest.WithParents(root), ) - gittest.Exec(t, cfg, "-C", expectedRepoPath, "symbolic-ref", "HEAD", "refs/heads/master") + gittest.Exec(tb, cfg, "-C", expectedRepoPath, "symbolic-ref", "HEAD", "refs/heads/master") bundlePath1 := filepath.Join(backupPath, "001.bundle") - gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath1, + gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath1, "HEAD", "refs/heads/master", "refs/heads/other", ) - master2 := gittest.WriteCommit(t, cfg, expectedRepoPath, + master2 := gittest.WriteCommit(tb, cfg, expectedRepoPath, gittest.WithBranch("master"), gittest.WithParents(master1), ) bundlePath2 := filepath.Join(backupPath, "002.bundle") - gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath2, + gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath2, "HEAD", "^"+master1.String(), "^"+other.String(), @@ -598,8 +603,9 @@ func TestResolveSink(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { for k, v := range tc.envs { - testhelper.ModifyEnvironment(t, k, v) + t.Setenv(k, v) } + sink, err := ResolveSink(ctx, tc.path) if tc.errMsg != "" { require.EqualError(t, err, tc.errMsg) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/filesystem_sink.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/filesystem_sink.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/filesystem_sink.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/filesystem_sink.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/filesystem_sink_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/filesystem_sink_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/filesystem_sink_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/filesystem_sink_test.go index 5b0beabc38..5ec47c7598 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/filesystem_sink_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/filesystem_sink_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -9,7 +11,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestFilesystemSink_GetReader(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/lazy.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/lazy.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/lazy.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/lazy.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/lazy_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/lazy_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/lazy_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/lazy_test.go index 05cb037ea0..922dffefe2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/lazy_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/lazy_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -9,7 +11,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestLazyWrite_noData(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator.go index 61455149f4..1cedd5913d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator.go @@ -9,8 +9,8 @@ import ( "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // LegacyLocator locates backup paths for historic backups. This is the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator_test.go index e841dad5eb..0f2665c4e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/locator_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/locator_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -10,8 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestLegacyLocator(t *testing.T) { @@ -101,7 +103,7 @@ func TestPointerLocator(t *testing.T) { for _, tc := range []struct { desc string - setup func(t testing.TB, ctx context.Context, sink Sink) + setup func(tb testing.TB, ctx context.Context, sink Sink) expectedBackupID string expectedOffset int }{ @@ -113,9 +115,9 @@ func TestPointerLocator(t *testing.T) { desc: "with previous backup", expectedBackupID: "abc123", expectedOffset: 1, - setup: func(t testing.TB, ctx context.Context, sink Sink) { - require.NoError(t, sink.Write(ctx, filepath.Join(repo.RelativePath, "LATEST"), strings.NewReader("abc123"))) - require.NoError(t, sink.Write(ctx, filepath.Join(repo.RelativePath, "abc123", "LATEST"), strings.NewReader("001"))) + setup: func(tb testing.TB, ctx context.Context, sink Sink) { + require.NoError(tb, sink.Write(ctx, filepath.Join(repo.RelativePath, "LATEST"), strings.NewReader("abc123"))) + require.NoError(tb, sink.Write(ctx, filepath.Join(repo.RelativePath, "abc123", "LATEST"), strings.NewReader("001"))) }, }, } { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline.go index e0956713ec..357428574c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline.go @@ -8,8 +8,8 @@ import ( "sync" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // Strategy used to create/restore backups diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline_test.go index ba2f71113e..0bed08cc19 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/pipeline_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/pipeline_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -10,9 +12,9 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestLoggingPipeline(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink.go index 217fb322b9..ef484624c8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink.go @@ -6,9 +6,9 @@ import ( "io" "gocloud.dev/blob" - _ "gocloud.dev/blob/azureblob" // nolint:nolintlint,golint,gci - _ "gocloud.dev/blob/gcsblob" // nolint:nolintlint,golint,gci - _ "gocloud.dev/blob/s3blob" // nolint:nolintlint,golint,gci + _ "gocloud.dev/blob/azureblob" //nolint:nolintlint,golint,gci + _ "gocloud.dev/blob/gcsblob" //nolint:nolintlint,golint,gci + _ "gocloud.dev/blob/s3blob" //nolint:nolintlint,golint,gci "gocloud.dev/gcerrors" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink_test.go index c5535dacff..ff007b421f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/storage_service_sink_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/storage_service_sink_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package backup import ( @@ -7,7 +9,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" _ "gocloud.dev/blob/memblob" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/testhelper_test.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/testhelper_test.go index b900cb5d5d..2f724c44af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/backup/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/backup/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package backup import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/blackbox.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/blackbox.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/blackbox.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/blackbox.go index 82f2e707ca..38cfa8b6d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/blackbox.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/blackbox.go @@ -8,10 +8,10 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" "gitlab.com/gitlab-org/labkit/monitoring" ) @@ -138,7 +138,7 @@ func (b Blackbox) Run() error { } func (b Blackbox) runProbes() { - for ; ; time.Sleep(b.cfg.sleepDuration) { + for ; ; time.Sleep(b.cfg.sleepDuration.Duration()) { for _, probe := range b.cfg.Probes { entry := log.Default().WithFields(map[string]interface{}{ "probe": probe.Name, @@ -198,12 +198,12 @@ func (b Blackbox) push(probe Probe) error { commands := make([]stats.PushCommand, len(probe.Push.Commands)) for i, command := range probe.Push.Commands { - oldOID, err := git.NewObjectIDFromHex(command.OldOID) + oldOID, err := git.ObjectHashSHA1.FromHex(command.OldOID) if err != nil { return fmt.Errorf("invalid old object ID for probe %q: %w", probe.Name, err) } - newOID, err := git.NewObjectIDFromHex(command.NewOID) + newOID, err := git.ObjectHashSHA1.FromHex(command.NewOID) if err != nil { return fmt.Errorf("invalid new object ID for probe %q: %w", probe.Name, err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config.go index 46b59809e9..9ea3c33a96 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config.go @@ -5,8 +5,9 @@ import ( "net/url" "time" - "github.com/pelletier/go-toml" - logconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" + "github.com/pelletier/go-toml/v2" + logconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) // Config is the configuration for gitaly-blackbox. @@ -17,7 +18,7 @@ type Config struct { // Sleep is the number of seconds between probe runs. Sleep int `toml:"sleep"` // sleepDuration is the same as Sleep but converted to a proper duration. - sleepDuration time.Duration + sleepDuration duration.Duration // Logging configures logging. Logging logconfig.Config `toml:"logging"` // Probes defines endpoints to probe. At least one probe must be defined. @@ -92,7 +93,7 @@ func ParseConfig(raw string) (Config, error) { if config.Sleep == 0 { config.Sleep = 15 * 60 } - config.sleepDuration = time.Duration(config.Sleep) * time.Second + config.sleepDuration = duration.Duration(config.Sleep) * duration.Duration(time.Second) if len(config.Probes) == 0 { return Config{}, fmt.Errorf("must define at least one probe") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config_test.go index be11c89d5f..6be4c80cc7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/blackbox/config_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/blackbox/config_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blackbox import ( @@ -7,6 +9,7 @@ import ( "time" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) func TestConfigParseFailures(t *testing.T) { @@ -75,16 +78,16 @@ func TestConfigSleep(t *testing.T) { testCases := []struct { desc string in string - out time.Duration + out duration.Duration }{ { desc: "default sleep time", - out: 15 * time.Minute, + out: duration.Duration(15 * time.Minute), }, { desc: "1 second", in: "sleep = 1\n", - out: time.Second, + out: duration.Duration(time.Second), }, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap.go index 894139f235..23b39ff66f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap.go @@ -10,8 +10,8 @@ import ( "github.com/cloudflare/tableflip" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" "golang.org/x/sys/unix" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap_test.go index 9265e51945..c4e9f17d74 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/bootstrap_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/bootstrap_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package bootstrap import ( @@ -12,8 +14,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestBootstrap_unixListener(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/connectioncounter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/connectioncounter.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/connectioncounter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/connectioncounter.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter.go index be35d551ca..6f8d3cda90 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter.go @@ -9,7 +9,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter_test.go index 9e9198eac6..13511a67e7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter/starter_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter/starter_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package starter import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/testhelper_test.go index 514236bd79..54b19f9c7f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package bootstrap import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/cache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/cache.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/cache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/cache.go index 82ad0a8031..7c4b03a879 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/cache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/cache.go @@ -4,7 +4,7 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache.go index dffc38ca5f..192afde072 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache.go @@ -10,11 +10,11 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache_test.go index 761d448597..b33ad8648d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/diskcache_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/diskcache_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package cache import ( @@ -9,12 +11,12 @@ import ( promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestStreamDBNaiveKeyer(t *testing.T) { @@ -45,8 +47,17 @@ func TestStreamDBNaiveKeyer(t *testing.T) { cfg := testcfg.Build(t) - repo1, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - repo2, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + ctx := testhelper.Context(t) + ctx = testhelper.SetCtxGrpcMethod(ctx, "InfoRefsUploadPack") + + repo1, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) + repo2, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) locator := config.NewLocator(cfg) @@ -56,8 +67,6 @@ func TestStreamDBNaiveKeyer(t *testing.T) { req2 := &gitalypb.InfoRefsRequest{ Repository: repo2, } - ctx := testhelper.Context(t) - ctx = testhelper.SetCtxGrpcMethod(ctx, "InfoRefsUploadPack") t.Run("empty cache", func(t *testing.T) { cache := New(cfg, locator) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/keyer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/keyer.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/keyer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/keyer.go index 31e810d14f..b89b240db2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/keyer.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/keyer.go @@ -16,11 +16,11 @@ import ( "github.com/google/uuid" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" ) @@ -274,15 +274,18 @@ func compositeKeyHashHex(ctx context.Context, genID string, req proto.Message) ( h := sha256.New() - ffs := featureflag.AllFlags(ctx) - sort.Strings(ffs) + var flagsWithValue []string + for flag, enabled := range featureflag.FromContext(ctx) { + flagsWithValue = append(flagsWithValue, flag.FormatWithValue(enabled)) + } + sort.Strings(flagsWithValue) for _, i := range []string{ version.GetVersion(), method, genID, string(reqSum), - strings.Join(ffs, " "), + strings.Join(flagsWithValue, " "), } { _, err := h.Write(prefixLen(i)) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/testhelper_test.go index 687ad7d6eb..50e91da036 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package cache import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker.go index 00d990c175..6a0b065df2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker.go @@ -14,9 +14,9 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) func (c *DiskCache) logWalkErr(err error, path, msg string) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker_test.go index ca08001b46..dc4f55f39d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cache/walker_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cache/walker_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package cache import ( @@ -11,9 +13,9 @@ import ( promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestDiskCacheObjectWalker(t *testing.T) { @@ -135,10 +137,10 @@ func TestCleanWalkEmptyDirs(t *testing.T) { require.Equal(t, expect, actual) } -func findFiles(t testing.TB, path string) string { +func findFiles(tb testing.TB, path string) string { cmd := exec.Command("find", ".") cmd.Dir = path out, err := cmd.Output() - require.NoError(t, err) + require.NoError(tb, err) return string(out) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups.go new file mode 100644 index 0000000000..53c2a47d41 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups.go @@ -0,0 +1,60 @@ +package cgroups + +import ( + "path/filepath" + + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" +) + +// Manager supplies an interface for interacting with cgroups +type Manager interface { + // Setup creates cgroups and assigns configured limitations. + // It is expected to be called once at Gitaly startup from any + // instance of the Manager. + Setup() error + // AddCommand adds a Command to a cgroup. + AddCommand(*command.Command, repository.GitRepo) (string, error) + // Cleanup cleans up cgroups created in Setup. + // It is expected to be called once at Gitaly shutdown from any + // instance of the Manager. + Cleanup() error + Describe(ch chan<- *prometheus.Desc) + Collect(ch chan<- prometheus.Metric) +} + +// NewManager returns the appropriate Cgroups manager +func NewManager(cfg cgroups.Config, pid int) Manager { + if cfg.Repositories.Count > 0 { + return newV1Manager(cfg, pid) + } + + return &NoopManager{} +} + +// PruneOldCgroups prunes old cgroups for both the memory and cpu subsystems +func PruneOldCgroups(cfg cgroups.Config, logger log.FieldLogger) { + if cfg.HierarchyRoot == "" { + return + } + + if err := config.PruneOldGitalyProcessDirectories( + logger, + filepath.Join(cfg.Mountpoint, "memory", + cfg.HierarchyRoot), + ); err != nil { + logger.WithError(err).Error("failed to clean up memory cgroups") + } + + if err := config.PruneOldGitalyProcessDirectories( + logger, + filepath.Join(cfg.Mountpoint, "cpu", + cfg.HierarchyRoot), + ); err != nil { + logger.WithError(err).Error("failed to clean up cpu cgroups") + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups_linux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups_linux_test.go new file mode 100644 index 0000000000..a921bc7781 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/cgroups_linux_test.go @@ -0,0 +1,166 @@ +//go:build !gitaly_test_sha256 + +package cgroups + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func TestNewManager(t *testing.T) { + cfg := cgroups.Config{Repositories: cgroups.Repositories{Count: 10}} + + require.IsType(t, &CGroupV1Manager{}, &CGroupV1Manager{cfg: cfg}) + require.IsType(t, &NoopManager{}, NewManager(cgroups.Config{}, 1)) +} + +func TestPruneOldCgroups(t *testing.T) { + t.Parallel() + + testCases := []struct { + desc string + cfg cgroups.Config + expectedPruned bool + // setup returns a pid + setup func(*testing.T, cgroups.Config) int + }{ + { + desc: "process belongs to another user", + cfg: cgroups.Config{ + Mountpoint: testhelper.TempDir(t), + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 10 * 1024 * 1024, + CPUShares: 1024, + }, + }, + setup: func(t *testing.T, cfg cgroups.Config) int { + pid := 1 + cgroupManager := NewManager(cfg, pid) + require.NoError(t, cgroupManager.Setup()) + + return pid + }, + expectedPruned: true, + }, + { + desc: "no hierarchy root", + cfg: cgroups.Config{ + Mountpoint: testhelper.TempDir(t), + HierarchyRoot: "", + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 10 * 1024 * 1024, + CPUShares: 1024, + }, + }, + setup: func(t *testing.T, cfg cgroups.Config) int { + pid := 1 + cgroupManager := NewManager(cfg, pid) + require.NoError(t, cgroupManager.Setup()) + + return 1 + }, + expectedPruned: false, + }, + { + desc: "pid of finished process", + cfg: cgroups.Config{ + Mountpoint: testhelper.TempDir(t), + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 10 * 1024 * 1024, + CPUShares: 1024, + }, + }, + setup: func(t *testing.T, cfg cgroups.Config) int { + cmd := exec.Command("ls") + require.NoError(t, cmd.Run()) + pid := cmd.Process.Pid + + cgroupManager := NewManager(cfg, pid) + require.NoError(t, cgroupManager.Setup()) + + return pid + }, + expectedPruned: true, + }, + { + desc: "pid of running process", + cfg: cgroups.Config{ + Mountpoint: testhelper.TempDir(t), + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 10 * 1024 * 1024, + CPUShares: 1024, + }, + }, + setup: func(t *testing.T, cfg cgroups.Config) int { + pid := os.Getpid() + + cgroupManager := NewManager(cfg, pid) + require.NoError(t, cgroupManager.Setup()) + + return pid + }, + expectedPruned: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + memoryRoot := filepath.Join( + tc.cfg.Mountpoint, + "memory", + tc.cfg.HierarchyRoot, + ) + cpuRoot := filepath.Join( + tc.cfg.Mountpoint, + "cpu", + tc.cfg.HierarchyRoot, + ) + + require.NoError(t, os.MkdirAll(cpuRoot, os.ModePerm)) + require.NoError(t, os.MkdirAll(memoryRoot, os.ModePerm)) + + pid := tc.setup(t, tc.cfg) + + logger, hook := test.NewNullLogger() + PruneOldCgroups(tc.cfg, logger) + + // create cgroups directories with a different pid + oldGitalyProcessMemoryDir := filepath.Join( + memoryRoot, + fmt.Sprintf("gitaly-%d", pid), + ) + oldGitalyProcesssCPUDir := filepath.Join( + cpuRoot, + fmt.Sprintf("gitaly-%d", pid), + ) + + if tc.expectedPruned { + require.NoDirExists(t, oldGitalyProcessMemoryDir) + require.NoDirExists(t, oldGitalyProcesssCPUDir) + } else { + require.DirExists(t, oldGitalyProcessMemoryDir) + require.DirExists(t, oldGitalyProcesssCPUDir) + require.Len(t, hook.Entries, 0) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/mock_linux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/mock_linux_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/mock_linux_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/mock_linux_test.go index 4ee705fed2..fe57beec18 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/mock_linux_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/mock_linux_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + /* Adapted from https://github.com/containerd/cgroups/blob/f1d9380fd3c028194db9582825512fdf3f39ab2a/mock_test.go @@ -27,7 +29,7 @@ import ( "github.com/containerd/cgroups" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) type mockCgroup struct { @@ -103,8 +105,8 @@ func (m *mockCgroup) setupMockCgroupFiles( require.NoError(t, os.WriteFile(controlFilePath, []byte(content), 0o644)) } - for shard := uint(0); shard < manager.cfg.Count; shard++ { - shardPath := filepath.Join(cgroupPath, fmt.Sprintf("shard-%d", shard)) + for shard := uint(0); shard < manager.cfg.Repositories.Count; shard++ { + shardPath := filepath.Join(cgroupPath, fmt.Sprintf("repos-%d", shard)) require.NoError(t, os.MkdirAll(shardPath, 0o755)) for filename, content := range contentByFilename { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/noop.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/noop.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/noop.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/noop.go index 57f5529021..4dfc491d4e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/noop.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/noop.go @@ -2,23 +2,24 @@ package cgroups import ( "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // NoopManager is a cgroups manager that does nothing type NoopManager struct{} -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (cg *NoopManager) Setup() error { return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. -func (cg *NoopManager) AddCommand(cmd *command.Command) error { - return nil +//nolint: stylecheck // This is unintentionally missing documentation. +func (cg *NoopManager) AddCommand(cmd *command.Command, repo repository.GitRepo) (string, error) { + return "", nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (cg *NoopManager) Cleanup() error { return nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1.go index e39c391a34..eb19db7990 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/cgroups/v1.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1.go @@ -1,13 +1,12 @@ //go:build !linux -// +build !linux package cgroups import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" ) // For systems other than Linux, we return a noop manager if cgroups was enabled. -func newV1Manager(cfg cgroups.Config) *NoopManager { +func newV1Manager(cfg cgroups.Config, pid int) *NoopManager { return &NoopManager{} } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux.go new file mode 100644 index 0000000000..819abbbe8a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux.go @@ -0,0 +1,234 @@ +package cgroups + +import ( + "fmt" + "hash/crc32" + "path/filepath" + "strings" + + "github.com/containerd/cgroups" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/prometheus/client_golang/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + cgroupscfg "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" +) + +// CGroupV1Manager is the manager for cgroups v1 +type CGroupV1Manager struct { + cfg cgroupscfg.Config + hierarchy func() ([]cgroups.Subsystem, error) + memoryReclaimAttemptsTotal, cpuUsage *prometheus.GaugeVec + procs *prometheus.GaugeVec + pid int +} + +func newV1Manager(cfg cgroupscfg.Config, pid int) *CGroupV1Manager { + return &CGroupV1Manager{ + cfg: cfg, + pid: pid, + hierarchy: func() ([]cgroups.Subsystem, error) { + return defaultSubsystems(cfg.Mountpoint) + }, + memoryReclaimAttemptsTotal: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "gitaly_cgroup_memory_reclaim_attempts_total", + Help: "Number of memory usage hits limits", + }, + []string{"path"}, + ), + cpuUsage: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "gitaly_cgroup_cpu_usage_total", + Help: "CPU Usage of Cgroup", + }, + []string{"path", "type"}, + ), + procs: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "gitaly_cgroup_procs_total", + Help: "Total number of procs", + }, + []string{"path", "subsystem"}, + ), + } +} + +//nolint: stylecheck // This is unintentionally missing documentation. +func (cg *CGroupV1Manager) Setup() error { + var parentResources specs.LinuxResources + + if cg.cfg.CPUShares > 0 { + parentResources.CPU = &specs.LinuxCPU{Shares: &cg.cfg.CPUShares} + } + + if cg.cfg.MemoryBytes > 0 { + parentResources.Memory = &specs.LinuxMemory{Limit: &cg.cfg.MemoryBytes} + } + + if _, err := cgroups.New( + cg.hierarchy, + cgroups.StaticPath(cg.currentProcessCgroup()), + &parentResources, + ); err != nil { + return fmt.Errorf("failed creating parent cgroup: %w", err) + } + + var reposResources specs.LinuxResources + + if cg.cfg.Repositories.CPUShares > 0 { + reposResources.CPU = &specs.LinuxCPU{Shares: &cg.cfg.Repositories.CPUShares} + } + + if cg.cfg.Repositories.MemoryBytes > 0 { + reposResources.Memory = &specs.LinuxMemory{Limit: &cg.cfg.Repositories.MemoryBytes} + } + + for i := 0; i < int(cg.cfg.Repositories.Count); i++ { + if _, err := cgroups.New( + cg.hierarchy, + cgroups.StaticPath(cg.repoPath(i)), + &reposResources, + ); err != nil { + return fmt.Errorf("failed creating repository cgroup: %w", err) + } + } + + return nil +} + +// AddCommand adds the given command to one of the CGroup's buckets. The bucket used for the command +// is determined by hashing the repository storage and path. No error is returned if the command has already +// exited. +func (cg *CGroupV1Manager) AddCommand( + cmd *command.Command, + repo repository.GitRepo, +) (string, error) { + var key string + if repo == nil { + key = strings.Join(cmd.Args(), "/") + } else { + key = repo.GetStorageName() + "/" + repo.GetRelativePath() + } + + checksum := crc32.ChecksumIEEE( + []byte(key), + ) + + groupID := uint(checksum) % cg.cfg.Repositories.Count + cgroupPath := cg.repoPath(int(groupID)) + + return cgroupPath, cg.addToCgroup(cmd.Pid(), cgroupPath) +} + +func (cg *CGroupV1Manager) addToCgroup(pid int, cgroupPath string) error { + control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(cgroupPath)) + if err != nil { + return fmt.Errorf("failed loading %s cgroup: %w", cgroupPath, err) + } + + if err := control.Add(cgroups.Process{Pid: pid}); err != nil { + // Command could finish so quickly before we can add it to a cgroup, so + // we don't consider it an error. + if strings.Contains(err.Error(), "no such process") { + return nil + } + return fmt.Errorf("failed adding process to cgroup: %w", err) + } + + return nil +} + +// Collect collects metrics from the cgroups controller +func (cg *CGroupV1Manager) Collect(ch chan<- prometheus.Metric) { + if !cg.cfg.MetricsEnabled { + return + } + + for i := 0; i < int(cg.cfg.Repositories.Count); i++ { + repoPath := cg.repoPath(i) + logger := log.Default().WithField("cgroup_path", repoPath) + control, err := cgroups.Load( + cg.hierarchy, + cgroups.StaticPath(repoPath), + ) + if err != nil { + logger.WithError(err).Warn("unable to load cgroup controller") + return + } + + if metrics, err := control.Stat(); err != nil { + logger.WithError(err).Warn("unable to get cgroup stats") + } else { + memoryMetric := cg.memoryReclaimAttemptsTotal.WithLabelValues(repoPath) + memoryMetric.Set(float64(metrics.Memory.Usage.Failcnt)) + ch <- memoryMetric + + cpuUserMetric := cg.cpuUsage.WithLabelValues(repoPath, "user") + cpuUserMetric.Set(float64(metrics.CPU.Usage.User)) + ch <- cpuUserMetric + + cpuKernelMetric := cg.cpuUsage.WithLabelValues(repoPath, "kernel") + cpuKernelMetric.Set(float64(metrics.CPU.Usage.Kernel)) + ch <- cpuKernelMetric + } + + if subsystems, err := cg.hierarchy(); err != nil { + logger.WithError(err).Warn("unable to get cgroup hierarchy") + } else { + for _, subsystem := range subsystems { + processes, err := control.Processes(subsystem.Name(), true) + if err != nil { + logger.WithField("subsystem", subsystem.Name()). + WithError(err). + Warn("unable to get process list") + continue + } + + procsMetric := cg.procs.WithLabelValues(repoPath, string(subsystem.Name())) + procsMetric.Set(float64(len(processes))) + ch <- procsMetric + } + } + } +} + +// Describe describes the cgroup metrics that Collect provides +func (cg *CGroupV1Manager) Describe(ch chan<- *prometheus.Desc) { + prometheus.DescribeByCollect(cg, ch) +} + +//nolint: stylecheck // This is unintentionally missing documentation. +func (cg *CGroupV1Manager) Cleanup() error { + processCgroupPath := cg.currentProcessCgroup() + + control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(processCgroupPath)) + if err != nil { + return fmt.Errorf("failed loading cgroup %s: %w", processCgroupPath, err) + } + + if err := control.Delete(); err != nil { + return fmt.Errorf("failed cleaning up cgroup %s: %w", processCgroupPath, err) + } + + return nil +} + +func (cg *CGroupV1Manager) repoPath(groupID int) string { + return filepath.Join(cg.currentProcessCgroup(), fmt.Sprintf("repos-%d", groupID)) +} + +func (cg *CGroupV1Manager) currentProcessCgroup() string { + return config.GetGitalyProcessTempDir(cg.cfg.HierarchyRoot, cg.pid) +} + +func defaultSubsystems(root string) ([]cgroups.Subsystem, error) { + subsystems := []cgroups.Subsystem{ + cgroups.NewMemory(root, cgroups.OptionalSwap()), + cgroups.NewCpu(root), + } + + return subsystems, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux_test.go new file mode 100644 index 0000000000..ad19884e78 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/cgroups/v1_linux_test.go @@ -0,0 +1,250 @@ +//go:build !gitaly_test_sha256 + +package cgroups + +import ( + "bytes" + "fmt" + "hash/crc32" + "os" + "path/filepath" + "strconv" + "strings" + "testing" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func defaultCgroupsConfig() cgroups.Config { + return cgroups.Config{ + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 3, + MemoryBytes: 1024000, + CPUShares: 256, + }, + } +} + +func TestSetup(t *testing.T) { + mock := newMock(t) + + pid := 1 + v1Manager := &CGroupV1Manager{ + cfg: defaultCgroupsConfig(), + hierarchy: mock.hierarchy, + pid: pid, + } + require.NoError(t, v1Manager.Setup()) + + for i := 0; i < 3; i++ { + memoryPath := filepath.Join( + mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", i), "memory.limit_in_bytes", + ) + memoryContent := readCgroupFile(t, memoryPath) + + require.Equal(t, string(memoryContent), "1024000") + + cpuPath := filepath.Join( + mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", i), "cpu.shares", + ) + cpuContent := readCgroupFile(t, cpuPath) + + require.Equal(t, string(cpuContent), "256") + } +} + +func TestAddCommand(t *testing.T) { + mock := newMock(t) + + repo := &gitalypb.Repository{ + StorageName: "default", + RelativePath: "path/to/repo.git", + } + + config := defaultCgroupsConfig() + config.Repositories.Count = 10 + config.Repositories.MemoryBytes = 1024 + config.Repositories.CPUShares = 16 + + pid := 1 + v1Manager1 := &CGroupV1Manager{ + cfg: config, + hierarchy: mock.hierarchy, + pid: pid, + } + require.NoError(t, v1Manager1.Setup()) + ctx := testhelper.Context(t) + + cmd2, err := command.New(ctx, []string{"ls", "-hal", "."}) + require.NoError(t, err) + require.NoError(t, cmd2.Wait()) + + v1Manager2 := &CGroupV1Manager{ + cfg: config, + hierarchy: mock.hierarchy, + pid: pid, + } + + t.Run("without a repository", func(t *testing.T) { + _, err := v1Manager2.AddCommand(cmd2, nil) + require.NoError(t, err) + + checksum := crc32.ChecksumIEEE([]byte(strings.Join(cmd2.Args(), "/"))) + groupID := uint(checksum) % config.Repositories.Count + + for _, s := range mock.subsystems { + path := filepath.Join(mock.root, string(s.Name()), "gitaly", + fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", groupID), "cgroup.procs") + content := readCgroupFile(t, path) + + cmdPid, err := strconv.Atoi(string(content)) + require.NoError(t, err) + + require.Equal(t, cmd2.Pid(), cmdPid) + } + }) + + t.Run("with a repository", func(t *testing.T) { + _, err := v1Manager2.AddCommand(cmd2, repo) + require.NoError(t, err) + + checksum := crc32.ChecksumIEEE([]byte(strings.Join([]string{ + "default", + "path/to/repo.git", + }, "/"))) + groupID := uint(checksum) % config.Repositories.Count + + for _, s := range mock.subsystems { + path := filepath.Join(mock.root, string(s.Name()), "gitaly", + fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", groupID), "cgroup.procs") + content := readCgroupFile(t, path) + + cmdPid, err := strconv.Atoi(string(content)) + require.NoError(t, err) + + require.Equal(t, cmd2.Pid(), cmdPid) + } + }) +} + +func TestCleanup(t *testing.T) { + mock := newMock(t) + + pid := 1 + v1Manager := &CGroupV1Manager{ + cfg: defaultCgroupsConfig(), + hierarchy: mock.hierarchy, + pid: pid, + } + require.NoError(t, v1Manager.Setup()) + require.NoError(t, v1Manager.Cleanup()) + + for i := 0; i < 3; i++ { + memoryPath := filepath.Join(mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", i)) + cpuPath := filepath.Join(mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", pid), fmt.Sprintf("repos-%d", i)) + + require.NoDirExists(t, memoryPath) + require.NoDirExists(t, cpuPath) + } +} + +func TestMetrics(t *testing.T) { + t.Parallel() + + mock := newMock(t) + repo := &gitalypb.Repository{ + StorageName: "default", + RelativePath: "path/to/repo.git", + } + + config := defaultCgroupsConfig() + config.Repositories.Count = 1 + config.Repositories.MemoryBytes = 1048576 + config.Repositories.CPUShares = 16 + + v1Manager1 := newV1Manager(config, 1) + v1Manager1.hierarchy = mock.hierarchy + + mock.setupMockCgroupFiles(t, v1Manager1, 2) + + require.NoError(t, v1Manager1.Setup()) + + ctx := testhelper.Context(t) + logger, hook := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + cmd, err := command.New(ctx, []string{"ls", "-hal", "."}, command.WithCgroup(v1Manager1, repo)) + require.NoError(t, err) + gitCmd1, err := command.New(ctx, []string{"ls", "-hal", "."}, command.WithCgroup(v1Manager1, repo)) + require.NoError(t, err) + gitCmd2, err := command.New(ctx, []string{"ls", "-hal", "."}, command.WithCgroup(v1Manager1, repo)) + require.NoError(t, err) + defer func() { + require.NoError(t, gitCmd2.Wait()) + }() + + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + require.NoError(t, gitCmd1.Wait()) + + repoCgroupPath := filepath.Join(v1Manager1.currentProcessCgroup(), "repos-0") + + expected := bytes.NewBufferString(fmt.Sprintf(`# HELP gitaly_cgroup_cpu_usage_total CPU Usage of Cgroup +# TYPE gitaly_cgroup_cpu_usage_total gauge +gitaly_cgroup_cpu_usage_total{path="%s",type="kernel"} 0 +gitaly_cgroup_cpu_usage_total{path="%s",type="user"} 0 +# HELP gitaly_cgroup_memory_reclaim_attempts_total Number of memory usage hits limits +# TYPE gitaly_cgroup_memory_reclaim_attempts_total gauge +gitaly_cgroup_memory_reclaim_attempts_total{path="%s"} 2 +# HELP gitaly_cgroup_procs_total Total number of procs +# TYPE gitaly_cgroup_procs_total gauge +gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 +gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 +`, repoCgroupPath, repoCgroupPath, repoCgroupPath, repoCgroupPath, repoCgroupPath)) + + for _, metricsEnabled := range []bool{true, false} { + t.Run(fmt.Sprintf("metrics enabled: %v", metricsEnabled), func(t *testing.T) { + v1Manager1.cfg.MetricsEnabled = metricsEnabled + + if metricsEnabled { + assert.NoError(t, testutil.CollectAndCompare( + v1Manager1, + expected)) + } else { + assert.NoError(t, testutil.CollectAndCompare( + v1Manager1, + bytes.NewBufferString(""))) + } + + logEntry := hook.LastEntry() + assert.Contains( + t, + logEntry.Data["command.cgroup_path"], + repoCgroupPath, + "log field includes a cgroup path that is a subdirectory of the current process' cgroup path", + ) + }) + } +} + +func readCgroupFile(t *testing.T, path string) []byte { + t.Helper() + + // The cgroups package defaults to permission 0 as it expects the file to be existing (the kernel creates the file) + // and its testing override the permission private variable to something sensible, hence we have to chmod ourselves + // so we can read the file. + require.NoError(t, os.Chmod(path, 0o666)) + + return testhelper.MustReadFile(t, path) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command.go index 85178d9958..2881cf86f4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/command.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command.go @@ -19,115 +19,104 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command/commandcounter" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/command/commandcounter" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/labkit/tracing" ) -func init() { - // Prevent the environment from affecting git calls by ignoring the configuration files. - // - // This should be done always but we have to wait until 15.0 due to backwards compatibility - // concerns. To fix tests ahead to 15.0, we ignore the global configuration when the package - // has been built under tests. `go test` uses a `.test` suffix on the test binaries. We use - // that to check whether to ignore the globals or not. - // - // See https://gitlab.com/gitlab-org/gitaly/-/issues/3617. - if strings.HasSuffix(os.Args[0], ".test") { - GitEnv = append(GitEnv, "GIT_CONFIG_GLOBAL=/dev/null", "GIT_CONFIG_SYSTEM=/dev/null") - } -} - var ( cpuSecondsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_cpu_seconds_total", Help: "Sum of CPU time spent by shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd", "mode"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "mode", "git_version"}, ) realSecondsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_real_seconds_total", Help: "Sum of real time spent by shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "git_version"}, ) minorPageFaultsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_minor_page_faults_total", Help: "Sum of minor page faults performed while shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "git_version"}, ) majorPageFaultsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_major_page_faults_total", Help: "Sum of major page faults performed while shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "git_version"}, ) signalsReceivedTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_signals_received_total", Help: "Sum of signals received while shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "git_version"}, ) contextSwitchesTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_command_context_switches_total", Help: "Sum of context switches performed while shelling out", }, - []string{"grpc_service", "grpc_method", "cmd", "subcmd", "ctxswitchtype"}, + []string{"grpc_service", "grpc_method", "cmd", "subcmd", "ctxswitchtype", "git_version"}, ) + spawnTokenAcquiringSeconds = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "gitaly_command_spawn_token_acquiring_seconds_total", + Help: "Sum of time spent waiting for a spawn token", + }, + []string{"grpc_service", "grpc_method", "cmd", "git_version"}, + ) + + // exportedEnvVars contains a list of environment variables + // that are always exported to child processes on spawn + exportedEnvVars = []string{ + "HOME", + "PATH", + "LD_LIBRARY_PATH", + "TZ", + + // Export git tracing variables for easier debugging + "GIT_TRACE", + "GIT_TRACE_PACK_ACCESS", + "GIT_TRACE_PACKET", + "GIT_TRACE_PERFORMANCE", + "GIT_TRACE_SETUP", + + // GIT_EXEC_PATH tells Git where to find its binaries. This must be exported + // especially in the case where we use bundled Git executables given that we cannot + // rely on a complete Git installation in that case. + "GIT_EXEC_PATH", + + // Git HTTP proxy settings: + // https://git-scm.com/docs/git-config#git-config-httpproxy + "all_proxy", + "http_proxy", + "HTTP_PROXY", + "https_proxy", + "HTTPS_PROXY", + // libcurl settings: https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html + "no_proxy", + "NO_PROXY", + + // We must export this variable to child processes or otherwise we end up in + // an inconsistent state, where the parent process has all feature flags + // force-enabled while the child is using the usual defaults. + featureflag.EnableAllFeatureFlagsEnvVar, + } + + // envInjector is responsible for injecting environment variables required for tracing into + // the child process. + envInjector = tracing.NewEnvInjector() ) -// GitEnv contains the ENV variables for git commands -var GitEnv = []string{ - // Force english locale for consistency on the output messages - "LANG=en_US.UTF-8", - - // - // PLEASE NOTE: the init of this package adds rules to ignore global git configuration in - // tests. This should really be done always but we can't do this before 15.0 due to backwards - // compatibility concerns. See https://gitlab.com/gitlab-org/gitaly/-/issues/3617. - // -} - -// exportedEnvVars contains a list of environment variables -// that are always exported to child processes on spawn -var exportedEnvVars = []string{ - "HOME", - "PATH", - "LD_LIBRARY_PATH", - "TZ", - - // Export git tracing variables for easier debugging - "GIT_TRACE", - "GIT_TRACE_PACK_ACCESS", - "GIT_TRACE_PACKET", - "GIT_TRACE_PERFORMANCE", - "GIT_TRACE_SETUP", - - // GIT_EXEC_PATH tells Git where to find its binaries. This must be exported especially in - // the case where we use bundled Git executables given that we cannot rely on a complete Git - // installation in that case. - "GIT_EXEC_PATH", - - // Git HTTP proxy settings: https://git-scm.com/docs/git-config#git-config-httpproxy - "all_proxy", - "http_proxy", - "HTTP_PROXY", - "https_proxy", - "HTTPS_PROXY", - // libcurl settings: https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html - "no_proxy", - "NO_PROXY", -} - -var envInjector = tracing.NewEnvInjector() - const ( // maxStderrBytes is at most how many bytes will be written to stderr maxStderrBytes = 10000 // 10kb @@ -147,29 +136,184 @@ type Command struct { context context.Context startTime time.Time - waitError error - waitOnce sync.Once + waitError error + waitOnce sync.Once + processExitedCh chan struct{} + + finalizer func(*Command) span opentracing.Span metricsCmd string metricsSubCmd string cgroupPath string + cmdGitVersion string } -type stdinSentinel struct{} +// New creates a Command from the given executable name and arguments On success, the Command +// contains a running subprocess. When ctx is canceled the embedded process will be terminated and +// reaped automatically. +func New(ctx context.Context, nameAndArgs []string, opts ...Option) (*Command, error) { + if ctx.Done() == nil { + panic(contextWithoutDonePanic("command spawned with context without Done() channel")) + } -func (stdinSentinel) Read([]byte) (int, error) { - return 0, errors.New("stdin sentinel should not be read from") + if len(nameAndArgs) == 0 { + panic("command spawned without name") + } + + if err := checkNullArgv(nameAndArgs); err != nil { + return nil, err + } + + var cfg config + for _, opt := range opts { + opt(&cfg) + } + + span, ctx := opentracing.StartSpanFromContext( + ctx, + nameAndArgs[0], + opentracing.Tag{Key: "args", Value: strings.Join(nameAndArgs[1:], " ")}, + ) + + spawnStartTime := time.Now() + putToken, err := getSpawnToken(ctx) + if err != nil { + return nil, err + } + service, method := methodFromContext(ctx) + cmdName := path.Base(nameAndArgs[0]) + spawnTokenAcquiringSeconds. + WithLabelValues(service, method, cmdName, cfg.gitVersion). + Add(getSpawnTokenAcquiringSeconds(spawnStartTime)) + + defer putToken() + + logPid := -1 + defer func() { + ctxlogrus.Extract(ctx).WithFields(logrus.Fields{ + "pid": logPid, + "path": nameAndArgs[0], + "args": nameAndArgs[1:], + }).Debug("spawn") + }() + + cmd := exec.Command(nameAndArgs[0], nameAndArgs[1:]...) + + command := &Command{ + cmd: cmd, + startTime: time.Now(), + context: ctx, + span: span, + finalizer: cfg.finalizer, + metricsCmd: cfg.commandName, + metricsSubCmd: cfg.subcommandName, + cmdGitVersion: cfg.gitVersion, + processExitedCh: make(chan struct{}), + } + + cmd.Dir = cfg.dir + + // Export allowed environment variables as set in the Gitaly process. + cmd.Env = AllowedEnvironment(os.Environ()) + // Append environment variables explicitly requested by the caller. + cmd.Env = append(cmd.Env, cfg.environment...) + // And finally inject environment variables required for tracing into the command. + cmd.Env = envInjector(ctx, cmd.Env) + + // Start the command in its own process group (nice for signalling) + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + + // Three possible values for stdin: + // * nil - Go implicitly uses /dev/null + // * stdinSentinel - configure with cmd.StdinPipe(), allowing Write() to work + // * Another io.Reader - becomes cmd.Stdin. Write() will not work + if _, ok := cfg.stdin.(stdinSentinel); ok { + pipe, err := cmd.StdinPipe() + if err != nil { + return nil, fmt.Errorf("creating stdin pipe: %w", err) + } + + command.writer = pipe + } else if cfg.stdin != nil { + cmd.Stdin = cfg.stdin + } + + if cfg.stdout != nil { + // We don't assign a reader if an stdout override was passed. We assume + // output is going to be directly handled by the caller. + cmd.Stdout = cfg.stdout + } else { + pipe, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("creating stdout pipe: %w", err) + } + + command.reader = pipe + } + + if cfg.stderr != nil { + cmd.Stderr = cfg.stderr + } else { + command.stderrBuffer, err = newStderrBuffer(maxStderrBytes, maxStderrLineLength, []byte("\n")) + if err != nil { + return nil, fmt.Errorf("creating stderr buffer: %w", err) + } + + cmd.Stderr = command.stderrBuffer + } + + if err := cmd.Start(); err != nil { + return nil, fmt.Errorf("starting process %v: %w", cmd.Args, err) + } + + inFlightCommandGauge.Inc() + commandcounter.Increment() + + // The goroutine below is responsible for terminating and reaping the process when ctx is + // canceled. While we must ensure that it does run when `cmd.Start()` was successful, it + // must not run before have fully set up the command. Otherwise, we may end up with racy + // access patterns when the context gets terminated early. + // + // We thus defer spawning the Goroutine. + defer func() { + go func() { + select { + case <-ctx.Done(): + // If the context has been cancelled and we didn't explicitly reap + // the child process then we need to manually kill it and release + // all associated resources. + if cmd.Process.Pid > 0 { + //nolint:errcheck // TODO: do we want to report errors? + // Send SIGTERM to the process group of cmd + syscall.Kill(-cmd.Process.Pid, syscall.SIGTERM) + } + + // We do not care for any potential error code, but just want to + // make sure that the subprocess gets properly killed and processed. + _ = command.Wait() + case <-command.processExitedCh: + // Otherwise, if the process has exited via a call to `wait()` + // already then there is nothing we need to do. + } + }() + }() + + if featureflag.RunCommandsInCGroup.IsEnabled(ctx) && cfg.cgroupsManager != nil { + cgroupPath, err := cfg.cgroupsManager.AddCommand(command, cfg.cgroupsRepo) + if err != nil { + return nil, err + } + + command.cgroupPath = cgroupPath + } + + logPid = cmd.Process.Pid + + return command, nil } -// SetupStdin instructs New() to configure the stdin pipe of the command it is -// creating. This allows you call Write() on the command as if it is an ordinary -// io.Writer, sending data directly to the stdin of the process. -// -// You should not call Read() on this value - it is strictly for configuration! -var SetupStdin io.Reader = stdinSentinel{} - // Read calls Read() on the stdout pipe of the command. func (c *Command) Read(p []byte) (int, error) { if c.reader == nil { @@ -198,159 +342,10 @@ func (c *Command) Wait() error { return c.waitError } -// SetCgroupPath sets the cgroup path for logging -func (c *Command) SetCgroupPath(path string) { - c.cgroupPath = path -} - -// SetMetricsCmd overrides the "cmd" label used in metrics -func (c *Command) SetMetricsCmd(metricsCmd string) { - c.metricsCmd = metricsCmd -} - -// SetMetricsSubCmd sets the "subcmd" label used in metrics -func (c *Command) SetMetricsSubCmd(metricsSubCmd string) { - c.metricsSubCmd = metricsSubCmd -} - -type contextWithoutDonePanic string - -// New creates a Command from an exec.Cmd. On success, the Command -// contains a running subprocess. When ctx is canceled the embedded -// process will be terminated and reaped automatically. -// -// If stdin is specified as SetupStdin, you will be able to write to the stdin -// of the subprocess by calling Write() on the returned Command. -func New(ctx context.Context, cmd *exec.Cmd, stdin io.Reader, stdout, stderr io.Writer, env ...string) (*Command, error) { - if ctx.Done() == nil { - panic(contextWithoutDonePanic("command spawned with context without Done() channel")) - } - - if err := checkNullArgv(cmd); err != nil { - return nil, err - } - - span, ctx := opentracing.StartSpanFromContext( - ctx, - cmd.Path, - opentracing.Tag{Key: "args", Value: strings.Join(cmd.Args, " ")}, - ) - - putToken, err := getSpawnToken(ctx) - if err != nil { - return nil, err - } - defer putToken() - - logPid := -1 - defer func() { - ctxlogrus.Extract(ctx).WithFields(logrus.Fields{ - "pid": logPid, - "path": cmd.Path, - "args": cmd.Args, - }).Debug("spawn") - }() - - command := &Command{ - cmd: cmd, - startTime: time.Now(), - context: ctx, - span: span, - } - - // Explicitly set the environment for the command - env = append(env, "GIT_TERMINAL_PROMPT=0") - - // Export env vars - cmd.Env = append(AllowedEnvironment(os.Environ()), env...) - cmd.Env = envInjector(ctx, cmd.Env) - - // Start the command in its own process group (nice for signalling) - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} - - // Three possible values for stdin: - // * nil - Go implicitly uses /dev/null - // * SetupStdin - configure with cmd.StdinPipe(), allowing Write() to work - // * Another io.Reader - becomes cmd.Stdin. Write() will not work - if stdin == SetupStdin { - pipe, err := cmd.StdinPipe() - if err != nil { - return nil, fmt.Errorf("GitCommand: stdin: %v", err) - } - command.writer = pipe - } else if stdin != nil { - cmd.Stdin = stdin - } - - if stdout != nil { - // We don't assign a reader if an stdout override was passed. We assume - // output is going to be directly handled by the caller. - cmd.Stdout = stdout - } else { - pipe, err := cmd.StdoutPipe() - if err != nil { - return nil, fmt.Errorf("GitCommand: stdout: %v", err) - } - command.reader = pipe - } - - if stderr != nil { - cmd.Stderr = stderr - } else { - command.stderrBuffer, err = newStderrBuffer(maxStderrBytes, maxStderrLineLength, []byte("\n")) - if err != nil { - return nil, fmt.Errorf("GitCommand: failed to create stderr buffer: %v", err) - } - cmd.Stderr = command.stderrBuffer - } - - if err := cmd.Start(); err != nil { - return nil, fmt.Errorf("GitCommand: start %v: %v", cmd.Args, err) - } - inFlightCommandGauge.Inc() - - // The goroutine below is responsible for terminating and reaping the - // process when ctx is canceled. - commandcounter.Increment() - go func() { - <-ctx.Done() - - if process := cmd.Process; process != nil && process.Pid > 0 { - //nolint:errcheck // TODO: do we want to report errors? - // Send SIGTERM to the process group of cmd - syscall.Kill(-process.Pid, syscall.SIGTERM) - } - - // We do not care for any potential erorr code, but just want to make sure that the - // subprocess gets properly killed and processed. - _ = command.Wait() - }() - - logPid = cmd.Process.Pid - - return command, nil -} - -// AllowedEnvironment filters the given slice of environment variables and -// returns all variables which are allowed per the variables defined above. -// This is useful for constructing a base environment in which a command can be -// run. -func AllowedEnvironment(envs []string) []string { - var filtered []string - - for _, env := range envs { - for _, exportedEnv := range exportedEnvVars { - if strings.HasPrefix(env, exportedEnv+"=") { - filtered = append(filtered, env) - } - } - } - - return filtered -} - // This function should never be called directly, use Wait(). func (c *Command) wait() { + defer close(c.processExitedCh) + if c.writer != nil { // Prevent the command from blocking on waiting for stdin to be closed c.writer.Close() @@ -375,21 +370,10 @@ func (c *Command) wait() { // counter again. So we instead do it here to accelerate the process, even though it's less // idiomatic. commandcounter.Decrement() -} -// ExitStatus will return the exit-code from an error returned by Wait(). -func ExitStatus(err error) (int, bool) { - exitError, ok := err.(*exec.ExitError) - if !ok { - return 0, false + if c.finalizer != nil { + c.finalizer(c) } - - waitStatus, ok := exitError.Sys().(syscall.WaitStatus) - if !ok { - return 0, false - } - - return waitStatus.ExitStatus(), true } func (c *Command) logProcessComplete() { @@ -454,22 +438,20 @@ func (c *Command) logProcessComplete() { } } - if featureflag.CommandStatsMetrics.IsEnabled(ctx) { - service, method := methodFromContext(ctx) - cmdName := path.Base(c.cmd.Path) - if c.metricsCmd != "" { - cmdName = c.metricsCmd - } - cpuSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "system").Add(systemTime.Seconds()) - cpuSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "user").Add(userTime.Seconds()) - realSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd).Add(realTime.Seconds()) - if ok { - minorPageFaultsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd).Add(float64(rusage.Minflt)) - majorPageFaultsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd).Add(float64(rusage.Majflt)) - signalsReceivedTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd).Add(float64(rusage.Nsignals)) - contextSwitchesTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "voluntary").Add(float64(rusage.Nvcsw)) - contextSwitchesTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "nonvoluntary").Add(float64(rusage.Nivcsw)) - } + service, method := methodFromContext(ctx) + cmdName := path.Base(c.cmd.Path) + if c.metricsCmd != "" { + cmdName = c.metricsCmd + } + cpuSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "system", c.cmdGitVersion).Add(systemTime.Seconds()) + cpuSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "user", c.cmdGitVersion).Add(userTime.Seconds()) + realSecondsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, c.cmdGitVersion).Add(realTime.Seconds()) + if ok { + minorPageFaultsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, c.cmdGitVersion).Add(float64(rusage.Minflt)) + majorPageFaultsTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, c.cmdGitVersion).Add(float64(rusage.Majflt)) + signalsReceivedTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, c.cmdGitVersion).Add(float64(rusage.Nsignals)) + contextSwitchesTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "voluntary", c.cmdGitVersion).Add(float64(rusage.Nvcsw)) + contextSwitchesTotal.WithLabelValues(service, method, cmdName, c.metricsSubCmd, "nonvoluntary", c.cmdGitVersion).Add(float64(rusage.Nivcsw)) } c.span.LogKV( @@ -491,6 +473,66 @@ func (c *Command) logProcessComplete() { c.span.Finish() } +// Args is an accessor for the command arguments +func (c *Command) Args() []string { + return c.cmd.Args +} + +// Env is an accessor for the environment variables +func (c *Command) Env() []string { + return c.cmd.Env +} + +// Pid is an accessor for the pid +func (c *Command) Pid() int { + return c.cmd.Process.Pid +} + +type contextWithoutDonePanic string + +var getSpawnTokenAcquiringSeconds = func(t time.Time) float64 { + return time.Since(t).Seconds() +} + +type stdinSentinel struct{} + +func (stdinSentinel) Read([]byte) (int, error) { + return 0, errors.New("stdin sentinel should not be read from") +} + +// AllowedEnvironment filters the given slice of environment variables and +// returns all variables which are allowed per the variables defined above. +// This is useful for constructing a base environment in which a command can be +// run. +func AllowedEnvironment(envs []string) []string { + var filtered []string + + for _, env := range envs { + for _, exportedEnv := range exportedEnvVars { + if strings.HasPrefix(env, exportedEnv+"=") { + filtered = append(filtered, env) + } + } + } + + return filtered +} + +// ExitStatus will return the exit-code from an error returned by Wait(). +func ExitStatus(err error) (int, bool) { + exitError, ok := err.(*exec.ExitError) + if !ok { + return 0, false + } + + waitStatus, ok := exitError.Sys().(syscall.WaitStatus) + if !ok { + return 0, false + } + + return waitStatus.ExitStatus(), true +} + func methodFromContext(ctx context.Context) (service string, method string) { tags := grpcmwtags.Extract(ctx) ctxValue := tags.Values()["grpc.request.fullMethod"] @@ -511,12 +553,11 @@ func methodFromContext(ctx context.Context) (service string, method string) { return "", "" } -// Command arguments will be passed to the exec syscall as -// null-terminated C strings. That means the arguments themselves may not -// contain a null byte. The go stdlib checks for null bytes but it +// Command arguments will be passed to the exec syscall as null-terminated C strings. That means the +// arguments themselves may not contain a null byte. The go stdlib checks for null bytes but it // returns a cryptic error. This function returns a more explicit error. -func checkNullArgv(cmd *exec.Cmd) error { - for _, arg := range cmd.Args { +func checkNullArgv(args []string) error { + for _, arg := range args { if strings.IndexByte(arg, 0) > -1 { // Use %q so that the null byte gets printed as \x00 return fmt.Errorf("detected null byte in command argument %q", arg) @@ -525,18 +566,3 @@ func checkNullArgv(cmd *exec.Cmd) error { return nil } - -// Args is an accessor for the command arguments -func (c *Command) Args() []string { - return c.cmd.Args -} - -// Env is an accessor for the environment variables -func (c *Command) Env() []string { - return c.cmd.Env -} - -// Pid is an accessor for the pid -func (c *Command) Pid() int { - return c.cmd.Process.Pid -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command_test.go new file mode 100644 index 0000000000..e10dadd4ea --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/command_test.go @@ -0,0 +1,514 @@ +//go:build !gitaly_test_sha256 + +package command + +import ( + "bytes" + "context" + "fmt" + "io" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestNew_environment(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + extraVar := "FOOBAR=123456" + + var buf bytes.Buffer + cmd, err := New(ctx, []string{"/usr/bin/env"}, WithStdout(&buf), WithEnvironment([]string{extraVar})) + + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + + require.Contains(t, strings.Split(buf.String(), "\n"), extraVar) +} + +func TestNew_exportedEnvironment(t *testing.T) { + ctx := testhelper.Context(t) + + for _, tc := range []struct { + key string + value string + }{ + { + key: "HOME", + value: "/home/git", + }, + { + key: "PATH", + value: "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin", + }, + { + key: "LD_LIBRARY_PATH", + value: "/path/to/your/lib", + }, + { + key: "TZ", + value: "foobar", + }, + { + key: "GIT_TRACE", + value: "true", + }, + { + key: "GIT_TRACE_PACK_ACCESS", + value: "true", + }, + { + key: "GIT_TRACE_PACKET", + value: "true", + }, + { + key: "GIT_TRACE_PERFORMANCE", + value: "true", + }, + { + key: "GIT_TRACE_SETUP", + value: "true", + }, + { + key: "all_proxy", + value: "http://localhost:4000", + }, + { + key: "http_proxy", + value: "http://localhost:5000", + }, + { + key: "HTTP_PROXY", + value: "http://localhost:6000", + }, + { + key: "https_proxy", + value: "https://localhost:5000", + }, + { + key: "HTTPS_PROXY", + value: "https://localhost:6000", + }, + { + key: "no_proxy", + value: "https://excluded:5000", + }, + { + key: "NO_PROXY", + value: "https://excluded:5000", + }, + } { + t.Run(tc.key, func(t *testing.T) { + if tc.key == "LD_LIBRARY_PATH" && runtime.GOOS == "darwin" { + t.Skip("System Integrity Protection prevents using dynamic linker (dyld) environment variables on macOS. https://apple.co/2XDH4iC") + } + + t.Setenv(tc.key, tc.value) + + var buf bytes.Buffer + cmd, err := New(ctx, []string{"/usr/bin/env"}, WithStdout(&buf)) + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + + expectedEnv := fmt.Sprintf("%s=%s", tc.key, tc.value) + require.Contains(t, strings.Split(buf.String(), "\n"), expectedEnv) + }) + } +} + +func TestNew_unexportedEnv(t *testing.T) { + ctx := testhelper.Context(t) + + unexportedEnvKey, unexportedEnvVal := "GITALY_UNEXPORTED_ENV", "foobar" + t.Setenv(unexportedEnvKey, unexportedEnvVal) + + var buf bytes.Buffer + cmd, err := New(ctx, []string{"/usr/bin/env"}, WithStdout(&buf)) + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + + require.NotContains(t, strings.Split(buf.String(), "\n"), fmt.Sprintf("%s=%s", unexportedEnvKey, unexportedEnvVal)) +} + +func TestNew_rejectContextWithoutDone(t *testing.T) { + t.Parallel() + + require.PanicsWithValue(t, contextWithoutDonePanic("command spawned with context without Done() channel"), func() { + _, err := New(testhelper.ContextWithoutCancel(), []string{"true"}) + require.NoError(t, err) + }) +} + +func TestNew_spawnTimeout(t *testing.T) { + ctx := testhelper.Context(t) + + defer func(ch chan struct{}, t time.Duration) { + spawnTokens = ch + spawnConfig.Timeout = t + }(spawnTokens, spawnConfig.Timeout) + + // This unbuffered channel will behave like a full/blocked buffered channel. + spawnTokens = make(chan struct{}) + // Speed up the test by lowering the timeout + spawnTimeout := 200 * time.Millisecond + spawnConfig.Timeout = spawnTimeout + + tick := time.After(spawnTimeout / 2) + + errCh := make(chan error) + go func() { + _, err := New(ctx, []string{"true"}) + errCh <- err + }() + + select { + case <-errCh: + require.FailNow(t, "expected spawning to be delayed") + case <-tick: + // This is the happy case: we expect spawning of the command to be delayed by up to + // 200ms until it finally times out. + } + + // And after some time we expect that spawning of the command fails due to the configured + // timeout. + require.Equal(t, fmt.Errorf("process spawn timed out after 200ms"), <-errCh) +} + +func TestCommand_Wait_contextCancellationKillsCommand(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + cmd, err := New(ctx, []string{"sleep", "1h"}) + require.NoError(t, err) + + // Cancel the command early. + cancel() + + err = cmd.Wait() + require.Error(t, err) + s, ok := ExitStatus(err) + require.True(t, ok) + require.Equal(t, -1, s) +} + +func TestNew_setupStdin(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + stdin := "Test value" + + var buf bytes.Buffer + cmd, err := New(ctx, []string{"cat"}, WithSetupStdin(), WithStdout(&buf)) + require.NoError(t, err) + + _, err = fmt.Fprintf(cmd, "%s", stdin) + require.NoError(t, err) + + require.NoError(t, cmd.Wait()) + require.Equal(t, stdin, buf.String()) +} + +func TestCommand_read(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cmd, err := New(ctx, []string{"echo", "test value"}) + require.NoError(t, err) + + output, err := io.ReadAll(cmd) + require.NoError(t, err) + require.Equal(t, "test value\n", string(output)) + + require.NoError(t, cmd.Wait()) +} + +func TestNew_nulByteInArgument(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cmd, err := New(ctx, []string{"sh", "-c", "hello\x00world"}) + require.Equal(t, fmt.Errorf("detected null byte in command argument %q", "hello\x00world"), err) + require.Nil(t, cmd) +} + +func TestNew_missingBinary(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cmd, err := New(ctx, []string{"command-non-existent"}) + require.EqualError(t, err, "starting process [command-non-existent]: exec: \"command-non-existent\": executable file not found in $PATH") + require.Nil(t, cmd) +} + +func TestCommand_stderrLogging(t *testing.T) { + t.Parallel() + + binaryPath := testhelper.WriteExecutable(t, filepath.Join(testhelper.TempDir(t), "script"), []byte(`#!/bin/bash + for i in {1..5} + do + echo 'hello world' 1>&2 + done + exit 1 + `)) + + logger, hook := test.NewNullLogger() + ctx := testhelper.Context(t) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + var stdout bytes.Buffer + cmd, err := New(ctx, []string{binaryPath}, WithStdout(&stdout)) + require.NoError(t, err) + + require.EqualError(t, cmd.Wait(), "exit status 1") + require.Empty(t, stdout.Bytes()) + require.Equal(t, strings.Repeat("hello world\n", 5), hook.LastEntry().Message) +} + +func TestCommand_stderrLoggingTruncation(t *testing.T) { + t.Parallel() + + binaryPath := testhelper.WriteExecutable(t, filepath.Join(testhelper.TempDir(t), "script"), []byte(`#!/bin/bash + for i in {1..1000} + do + printf '%06d zzzzzzzzzz\n' $i >&2 + done + exit 1 + `)) + + logger, hook := test.NewNullLogger() + ctx := testhelper.Context(t) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + var stdout bytes.Buffer + cmd, err := New(ctx, []string{binaryPath}, WithStdout(&stdout)) + require.NoError(t, err) + + require.Error(t, cmd.Wait()) + require.Empty(t, stdout.Bytes()) + require.Len(t, hook.LastEntry().Message, maxStderrBytes) +} + +func TestCommand_stderrLoggingWithNulBytes(t *testing.T) { + t.Parallel() + + binaryPath := testhelper.WriteExecutable(t, filepath.Join(testhelper.TempDir(t), "script"), []byte(`#!/bin/bash + dd if=/dev/zero bs=1000 count=1000 status=none >&2 + exit 1 + `)) + + logger, hook := test.NewNullLogger() + ctx := testhelper.Context(t) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + var stdout bytes.Buffer + cmd, err := New(ctx, []string{binaryPath}, WithStdout(&stdout)) + require.NoError(t, err) + + require.Error(t, cmd.Wait()) + require.Empty(t, stdout.Bytes()) + require.Equal(t, strings.Repeat("\x00", maxStderrLineLength), hook.LastEntry().Message) +} + +func TestCommand_stderrLoggingLongLine(t *testing.T) { + t.Parallel() + + binaryPath := testhelper.WriteExecutable(t, filepath.Join(testhelper.TempDir(t), "script"), []byte(`#!/bin/bash + printf 'a%.0s' {1..8192} >&2 + printf '\n' >&2 + printf 'b%.0s' {1..8192} >&2 + exit 1 + `)) + + logger, hook := test.NewNullLogger() + ctx := testhelper.Context(t) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + var stdout bytes.Buffer + cmd, err := New(ctx, []string{binaryPath}, WithStdout(&stdout)) + require.NoError(t, err) + + require.Error(t, cmd.Wait()) + require.Empty(t, stdout.Bytes()) + require.Equal(t, + strings.Join([]string{ + strings.Repeat("a", maxStderrLineLength), + strings.Repeat("b", maxStderrLineLength), + }, "\n"), + hook.LastEntry().Message, + ) +} + +func TestCommand_stderrLoggingMaxBytes(t *testing.T) { + t.Parallel() + + binaryPath := testhelper.WriteExecutable(t, filepath.Join(testhelper.TempDir(t), "script"), []byte(`#!/bin/bash + # This script is used to test that a command writes at most maxBytes to stderr. It + # simulates the edge case where the logwriter has already written MaxStderrBytes-1 + # (9999) bytes + + # This edge case happens when 9999 bytes are written. To simulate this, + # stderr_max_bytes_edge_case has 4 lines of the following format: + # + # line1: 3333 bytes long + # line2: 3331 bytes + # line3: 3331 bytes + # line4: 1 byte + # + # The first 3 lines sum up to 9999 bytes written, since we write a 2-byte escaped + # "\n" for each \n we see. The 4th line can be any data. + + printf 'a%.0s' {1..3333} >&2 + printf '\n' >&2 + printf 'a%.0s' {1..3331} >&2 + printf '\n' >&2 + printf 'a%.0s' {1..3331} >&2 + printf '\na\n' >&2 + exit 1 + `)) + + logger, hook := test.NewNullLogger() + ctx := testhelper.Context(t) + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(logger)) + + var stdout bytes.Buffer + cmd, err := New(ctx, []string{binaryPath}, WithStdout(&stdout)) + require.NoError(t, err) + require.Error(t, cmd.Wait()) + + require.Empty(t, stdout.Bytes()) + require.Len(t, hook.LastEntry().Message, maxStderrBytes) +} + +type mockCgroupManager string + +func (m mockCgroupManager) AddCommand(*Command, repository.GitRepo) (string, error) { + return string(m), nil +} + +func TestCommand_logMessage(t *testing.T) { + t.Parallel() + + logger, hook := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + ctx := ctxlogrus.ToContext(testhelper.Context(t), logrus.NewEntry(logger)) + + cmd, err := New(ctx, []string{"echo", "hello world"}, + WithCgroup(mockCgroupManager("/sys/fs/cgroup/1"), nil), + ) + require.NoError(t, err) + + require.NoError(t, cmd.Wait()) + logEntry := hook.LastEntry() + assert.Equal(t, cmd.Pid(), logEntry.Data["pid"]) + assert.Equal(t, []string{"echo", "hello world"}, logEntry.Data["args"]) + assert.Equal(t, 0, logEntry.Data["command.exitCode"]) + assert.Equal(t, "/sys/fs/cgroup/1", logEntry.Data["command.cgroup_path"]) +} + +func TestNew_commandSpawnTokenMetrics(t *testing.T) { + defer func(old func(time.Time) float64) { + getSpawnTokenAcquiringSeconds = old + }(getSpawnTokenAcquiringSeconds) + + getSpawnTokenAcquiringSeconds = func(t time.Time) float64 { + return 1 + } + + spawnTokenAcquiringSeconds.Reset() + + ctx := testhelper.Context(t) + + tags := grpcmwtags.NewTags() + tags.Set("grpc.request.fullMethod", "/test.Service/TestRPC") + ctx = grpcmwtags.SetInContext(ctx, tags) + + cmd, err := New(ctx, []string{"echo", "goodbye, cruel world."}) + + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + + expectedMetrics := `# HELP gitaly_command_spawn_token_acquiring_seconds_total Sum of time spent waiting for a spawn token +# TYPE gitaly_command_spawn_token_acquiring_seconds_total counter +gitaly_command_spawn_token_acquiring_seconds_total{cmd="echo",git_version="",grpc_method="TestRPC",grpc_service="test.Service"} 1 +` + require.NoError( + t, + testutil.CollectAndCompare( + spawnTokenAcquiringSeconds, + bytes.NewBufferString(expectedMetrics), + ), + ) +} + +func TestCommand_withFinalizer(t *testing.T) { + t.Parallel() + + t.Run("context cancellation runs finalizer", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + finalizerCh := make(chan struct{}) + _, err := New(ctx, []string{"echo"}, WithFinalizer(func(*Command) { + close(finalizerCh) + })) + require.NoError(t, err) + + cancel() + + <-finalizerCh + }) + + t.Run("Wait runs finalizer", func(t *testing.T) { + ctx := testhelper.Context(t) + + finalizerCh := make(chan struct{}) + cmd, err := New(ctx, []string{"echo"}, WithFinalizer(func(*Command) { + close(finalizerCh) + })) + require.NoError(t, err) + + require.NoError(t, cmd.Wait()) + + <-finalizerCh + }) + + t.Run("process exit does not run finalizer", func(t *testing.T) { + ctx := testhelper.Context(t) + + finalizerCh := make(chan struct{}) + _, err := New(ctx, []string{"echo"}, WithFinalizer(func(*Command) { + close(finalizerCh) + })) + require.NoError(t, err) + + select { + case <-finalizerCh: + // Command finalizers should only be running when we have either explicitly + // called `Wait()` on the command, or when the context has been cancelled. + // Otherwise we may run into the case where finalizers have already been ran + // on the exited process even though we may still be busy handling the + // output of that command, which may result in weird races. + require.FailNow(t, "finalizer should not have been ran") + case <-time.After(50 * time.Millisecond): + } + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/commandcounter/counter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/commandcounter/counter.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/commandcounter/counter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/commandcounter/counter.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/metrics.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/metrics.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/metrics.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/metrics.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/option.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/option.go new file mode 100644 index 0000000000..cca8e62f1b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/option.go @@ -0,0 +1,110 @@ +package command + +import ( + "io" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" +) + +type config struct { + stdin io.Reader + stdout io.Writer + stderr io.Writer + dir string + environment []string + + finalizer func(*Command) + + commandName string + subcommandName string + gitVersion string + + cgroupsManager CgroupsManager + cgroupsRepo repository.GitRepo +} + +// Option is an option that can be passed to `New()` for controlling how the command is being +// created. +type Option func(cfg *config) + +// WithStdin sets up the command to read from the given reader. +func WithStdin(stdin io.Reader) Option { + return func(cfg *config) { + cfg.stdin = stdin + } +} + +// WithSetupStdin instructs New() to configure the stdin pipe of the command it is creating. This +// allows you call Write() on the command as if it is an ordinary io.Writer, sending data directly +// to the stdin of the process. +func WithSetupStdin() Option { + return func(cfg *config) { + cfg.stdin = stdinSentinel{} + } +} + +// WithStdout sets up the command to write standard output to the given writer. +func WithStdout(stdout io.Writer) Option { + return func(cfg *config) { + cfg.stdout = stdout + } +} + +// WithStderr sets up the command to write standard error to the given writer. +func WithStderr(stderr io.Writer) Option { + return func(cfg *config) { + cfg.stderr = stderr + } +} + +// WithDir will set up the command to be ran in the specific directory. +func WithDir(dir string) Option { + return func(cfg *config) { + cfg.dir = dir + } +} + +// WithEnvironment sets up environment variables that shall be set for the command. +func WithEnvironment(environment []string) Option { + return func(cfg *config) { + cfg.environment = environment + } +} + +// WithCommandName overrides the "cmd" and "subcmd" label used in metrics. +func WithCommandName(commandName, subcommandName string) Option { + return func(cfg *config) { + cfg.commandName = commandName + cfg.subcommandName = subcommandName + } +} + +// WithCommandGitVersion overrides the "git_version" label used in metrics. +func WithCommandGitVersion(gitCmdVersion string) Option { + return func(cfg *config) { + cfg.gitVersion = gitCmdVersion + } +} + +// CgroupsManager is a subset of the `cgroups.Manager` interface. We need to replicate it here to +// avoid a cyclic dependency between both packages. +type CgroupsManager interface { + AddCommand(*Command, repository.GitRepo) (string, error) +} + +// WithCgroup adds the spawned command to a Cgroup. The bucket used will be derived from the +// command's arguments and/or from the repository. +func WithCgroup(cgroupsManager CgroupsManager, repo repository.GitRepo) Option { + return func(cfg *config) { + cfg.cgroupsManager = cgroupsManager + cfg.cgroupsRepo = repo + } +} + +// WithFinalizer sets up the finalizer to be run when the command is being wrapped up. It will be +// called after `Wait()` has returned. +func WithFinalizer(finalizer func(*Command)) Option { + return func(cfg *config) { + cfg.finalizer = finalizer + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/spawntoken.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/spawntoken.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/spawntoken.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/spawntoken.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats.go index 5fbb7f3b3b..6e1be4eb4e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats.go @@ -9,13 +9,13 @@ import ( type requestStatsKey struct{} -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type Stats struct { registry map[string]int sync.Mutex } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (stats *Stats) RecordSum(key string, value int) { stats.Lock() defer stats.Unlock() @@ -27,7 +27,7 @@ func (stats *Stats) RecordSum(key string, value int) { stats.registry[key] = value } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (stats *Stats) RecordMax(key string, value int) { stats.Lock() defer stats.Unlock() @@ -41,7 +41,7 @@ func (stats *Stats) RecordMax(key string, value int) { stats.registry[key] = value } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (stats *Stats) Fields() logrus.Fields { stats.Lock() defer stats.Unlock() @@ -53,13 +53,13 @@ func (stats *Stats) Fields() logrus.Fields { return f } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func StatsFromContext(ctx context.Context) *Stats { stats, _ := ctx.Value(requestStatsKey{}).(*Stats) return stats } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func InitContextStats(ctx context.Context) context.Context { return context.WithValue(ctx, requestStatsKey{}, &Stats{ registry: make(map[string]int), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats_test.go index e7e7b99361..3218cfbf42 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stats_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stats_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package command import ( @@ -5,7 +7,7 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestStatsFromContext_BackgroundContext(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stderrbuffer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stderrbuffer.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stderrbuffer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stderrbuffer.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stderrbuffer_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stderrbuffer_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stderrbuffer_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stderrbuffer_test.go index 49da19cc34..07bbf95e48 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/command/stderrbuffer_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/stderrbuffer_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package command import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/testhelper_test.go new file mode 100644 index 0000000000..12904aee06 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/command/testhelper_test.go @@ -0,0 +1,13 @@ +//go:build !gitaly_test_sha256 + +package command + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry.go index 83eb007f54..1d3176eb45 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry.go @@ -12,7 +12,7 @@ import ( "time" sentry "github.com/getsentry/sentry-go" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) // Try will wrap the provided function with a panic recovery. If a panic occurs, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry_test.go index dcb6831617..a43293d1d5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/retry_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/retry_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package dontpanic_test import ( @@ -5,7 +7,7 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" ) func TestTry(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/testhelper_test.go index dd438042be..bbcf91f747 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package dontpanic import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/errors/errors.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/errors/errors.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/errors/errors.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/errors/errors.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/alternates/alternates.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/alternates/alternates.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/alternates/alternates.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/alternates/alternates.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/bitmap.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/bitmap.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/bitmap.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/bitmap.go index 0b1c9cc158..d95e6e8805 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/bitmap.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/bitmap.go @@ -10,8 +10,8 @@ import ( grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" ) var badBitmapRequestCount = promauto.NewCounterVec( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache.go index e86248feb8..3fb00a5883 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache.go @@ -9,11 +9,11 @@ import ( "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "gitlab.com/gitlab-org/labkit/correlation" ) @@ -34,10 +34,10 @@ const ( type Cache interface { // ObjectReader either creates a new object reader or returns a cached one for the given // repository. - ObjectReader(context.Context, git.RepositoryExecutor) (ObjectReader, error) + ObjectReader(context.Context, git.RepositoryExecutor) (ObjectReader, func(), error) // ObjectInfoReader either creates a new object info reader or returns a cached one for the // given repository. - ObjectInfoReader(context.Context, git.RepositoryExecutor) (ObjectInfoReader, error) + ObjectInfoReader(context.Context, git.RepositoryExecutor) (ObjectInfoReader, func(), error) // Evict evicts all cached processes from the cache. Evict() } @@ -67,11 +67,6 @@ type ProcessCache struct { totalCatfileProcesses prometheus.Counter catfileLookupCounter *prometheus.CounterVec catfileCacheMembers *prometheus.GaugeVec - - // cachedProcessDone is a condition that gets signalled whenever a process is being - // considered to be returned to the cache. This field is optional and must only be used in - // tests. - cachedProcessDone *sync.Cond } // NewCache creates a new catfile process cache. @@ -175,37 +170,37 @@ func (c *ProcessCache) Stop() { } // ObjectReader creates a new ObjectReader process for the given repository. -func (c *ProcessCache) ObjectReader(ctx context.Context, repo git.RepositoryExecutor) (ObjectReader, error) { - cacheable, err := c.getOrCreateProcess(ctx, repo, &c.objectReaders, func(ctx context.Context) (cacheable, error) { +func (c *ProcessCache) ObjectReader(ctx context.Context, repo git.RepositoryExecutor) (ObjectReader, func(), error) { + cacheable, cancel, err := c.getOrCreateProcess(ctx, repo, &c.objectReaders, func(ctx context.Context) (cacheable, error) { return newObjectReader(ctx, repo, c.catfileLookupCounter) - }) + }, "catfile.ObjectReader") if err != nil { - return nil, err + return nil, nil, err } objectReader, ok := cacheable.(ObjectReader) if !ok { - return nil, fmt.Errorf("expected object reader, got %T", cacheable) + return nil, nil, fmt.Errorf("expected object reader, got %T", cacheable) } - return objectReader, nil + return objectReader, cancel, nil } // ObjectInfoReader creates a new ObjectInfoReader process for the given repository. -func (c *ProcessCache) ObjectInfoReader(ctx context.Context, repo git.RepositoryExecutor) (ObjectInfoReader, error) { - cacheable, err := c.getOrCreateProcess(ctx, repo, &c.objectInfoReaders, func(ctx context.Context) (cacheable, error) { +func (c *ProcessCache) ObjectInfoReader(ctx context.Context, repo git.RepositoryExecutor) (ObjectInfoReader, func(), error) { + cacheable, cancel, err := c.getOrCreateProcess(ctx, repo, &c.objectInfoReaders, func(ctx context.Context) (cacheable, error) { return newObjectInfoReader(ctx, repo, c.catfileLookupCounter) - }) + }, "catfile.ObjectInfoReader") if err != nil { - return nil, err + return nil, nil, err } objectInfoReader, ok := cacheable.(ObjectInfoReader) if !ok { - return nil, fmt.Errorf("expected object info reader, got %T", cacheable) + return nil, nil, fmt.Errorf("expected object info reader, got %T", cacheable) } - return objectInfoReader, nil + return objectInfoReader, cancel, nil } func (c *ProcessCache) getOrCreateProcess( @@ -213,75 +208,92 @@ func (c *ProcessCache) getOrCreateProcess( repo repository.GitRepo, processes *processes, create func(context.Context) (cacheable, error), -) (_ cacheable, returnedErr error) { - requestDone := ctx.Done() - if requestDone == nil { - panic("empty ctx.Done() in catfile.Batch.New()") - } - + spanName string, +) (_ cacheable, _ func(), returnedErr error) { defer c.reportCacheMembers() - var cancel func() cacheKey, isCacheable := newCacheKey(metadata.GetValue(ctx, SessionIDField), repo) if isCacheable { - // We only try to look up cached batch processes in case it is cacheable, which - // requires a session ID. This is mostly done such that git-cat-file(1) processes - // from one user cannot interfer with those from another user. The main intent is to - // disallow trivial denial of service attacks against other users in case it is - // possible to poison the cache with broken git-cat-file(1) processes. + // We only try to look up cached processes in case it is cacheable, which requires a + // session ID. This is mostly done such that git-cat-file(1) processes from one user + // cannot interfere with those from another user. The main intent is to disallow + // trivial denial of service attacks against other users in case it is possible to + // poison the cache with broken git-cat-file(1) processes. if entry, ok := processes.Checkout(cacheKey); ok { - go c.returnWhenDone(requestDone, processes, cacheKey, entry.value, entry.cancel) c.catfileCacheCounter.WithLabelValues("hit").Inc() - return entry.value, nil + return entry.value, func() { + c.returnToCache(processes, cacheKey, entry.value, entry.cancel) + }, nil } c.catfileCacheCounter.WithLabelValues("miss").Inc() // We have not found any cached process, so we need to create a new one. In this // case, we need to detach the process from the current context such that it does - // not get killed when the current context is done. Note that while we explicitly - // `close()` processes in case this function fails, we must have a cancellable - // context or otherwise our `command` package will panic. - ctx, cancel = context.WithCancel(context.Background()) - defer func() { - if returnedErr != nil { - cancel() - } - }() - + // not get killed when the parent context is cancelled. + // + // Note that we explicitly retain feature flags here, which means that cached + // processes may retain flags for some time which have been changed meanwhile. While + // not ideal, it feels better compared to just ignoring feature flags altogether. + // The latter would mean that we cannot use flags in the catfile code, but more + // importantly we also wouldn't be able to use feature-flagged Git version upgrades + // for catfile processes. + ctx = helper.SuppressCancellation(ctx) // We have to decorrelate the process from the current context given that it // may potentially be reused across different RPC calls. ctx = correlation.ContextWithCorrelation(ctx, "") ctx = opentracing.ContextWithSpan(ctx, nil) } - batch, err := create(ctx) + span, ctx := opentracing.StartSpanFromContext(ctx, spanName) + + // Create a new cancellable process context such that we can kill it on demand. If it's a + // cached process, then it will only be killed when the cache evicts the entry because we + // detached the background further up. If it's an uncached value, we either kill it manually + // or via the RPC context's cancellation function. + ctx, cancelProcessContext := context.WithCancel(ctx) + defer func() { + if returnedErr != nil { + cancelProcessContext() + } + }() + + process, err := create(ctx) if err != nil { - return nil, err + return nil, nil, err } defer func() { - // If we somehow fail after creating a new Batch process, then we want to kill - // spawned processes right away. + // If we somehow fail after creating a new process, then we want to kill spawned + // processes right away. if returnedErr != nil { - batch.close() + process.close() } }() c.totalCatfileProcesses.Inc() c.currentCatfileProcesses.Inc() - go func() { - <-ctx.Done() - c.currentCatfileProcesses.Dec() - }() + // Note that we must make sure that `cancel` and `closeProcess` are two different variables. + // Otherwise if we passed `cancel` to `returnToCache` and then set `cancel` itself to the + // function that calls it we would accidentally call ourselves and end up with a segfault. + closeProcess := func() { + cancelProcessContext() + process.close() + span.Finish() + c.currentCatfileProcesses.Dec() + } + + cancel := closeProcess if isCacheable { // If the process is cacheable, then we want to put the process into the cache when // the current outer context is done. - go c.returnWhenDone(requestDone, processes, cacheKey, batch, cancel) + cancel = func() { + c.returnToCache(processes, cacheKey, process, closeProcess) + } } - return batch, nil + return process, cancel, nil } func (c *ProcessCache) reportCacheMembers() { @@ -295,16 +307,9 @@ func (c *ProcessCache) Evict() { c.objectInfoReaders.Evict() } -func (c *ProcessCache) returnWhenDone(done <-chan struct{}, p *processes, cacheKey key, value cacheable, cancel func()) { - <-done - +func (c *ProcessCache) returnToCache(p *processes, cacheKey key, value cacheable, cancel func()) { defer func() { c.reportCacheMembers() - if c.cachedProcessDone != nil { - c.cachedProcessDone.L.Lock() - defer c.cachedProcessDone.L.Unlock() - c.cachedProcessDone.Broadcast() - } }() if value == nil || value.isClosed() { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache_test.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache_test.go index b90124ec8a..89bbec75ad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/cache_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/cache_test.go @@ -5,25 +5,30 @@ import ( "errors" "io" "os" - "sync" "testing" "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" ) func TestProcesses_add(t *testing.T) { + ctx := testhelper.Context(t) + const maxLen = 3 p := &processes{maxLen: maxLen} - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) key0 := mustCreateKey(t, "0", repo) value0, cancel := mustCreateCacheable(t, cfg, repo) @@ -53,9 +58,14 @@ func TestProcesses_add(t *testing.T) { } func TestProcesses_addTwice(t *testing.T) { + ctx := testhelper.Context(t) + p := &processes{maxLen: 10} - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) key0 := mustCreateKey(t, "0", repo) value0, cancel := mustCreateCacheable(t, cfg, repo) @@ -80,9 +90,14 @@ func TestProcesses_addTwice(t *testing.T) { } func TestProcesses_Checkout(t *testing.T) { + ctx := testhelper.Context(t) + p := &processes{maxLen: 10} - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) key0 := mustCreateKey(t, "0", repo) value0, cancel := mustCreateCacheable(t, cfg, repo) @@ -107,9 +122,14 @@ func TestProcesses_Checkout(t *testing.T) { } func TestProcesses_EnforceTTL(t *testing.T) { + ctx := testhelper.Context(t) + p := &processes{maxLen: 10} - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) cutoff := time.Now() @@ -149,12 +169,17 @@ func TestProcesses_EnforceTTL(t *testing.T) { } func TestCache_autoExpiry(t *testing.T) { + ctx := testhelper.Context(t) + monitorTicker := helper.NewManualTicker() c := newCache(time.Hour, 10, monitorTicker) defer c.Stop() - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) // Add a process that has expired already. key0 := mustCreateKey(t, "0", repo) @@ -178,67 +203,46 @@ func TestCache_autoExpiry(t *testing.T) { } func TestCache_ObjectReader(t *testing.T) { - cfg, repo, _ := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + repoExecutor := newRepoExecutor(t, cfg, repo) cache := newCache(time.Hour, 10, helper.NewManualTicker()) defer cache.Stop() - cache.cachedProcessDone = sync.NewCond(&sync.Mutex{}) - - t.Run("uncancellable", func(t *testing.T) { - ctx := testhelper.ContextWithoutCancel() - - require.PanicsWithValue(t, "empty ctx.Done() in catfile.Batch.New()", func() { - _, _ = cache.ObjectReader(ctx, repoExecutor) - }) - }) t.Run("uncacheable", func(t *testing.T) { - ctx, cancel := context.WithCancel(testhelper.Context(t)) - // The context doesn't carry a session ID and is thus uncacheable. // The process should never get returned to the cache and must be // killed on context cancellation. - reader, err := cache.ObjectReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectReader(ctx, repoExecutor) require.NoError(t, err) - objectReaderImpl, ok := reader.(*objectReader) - require.True(t, ok, "expected object reader") - cancel() - // We're cheating a bit here to avoid creating a racy test by reaching into the - // process and trying to read from its stdout. If the cancel did kill the process as - // expected, then the stdout should be closed and we'll get an EOF. - output, err := io.ReadAll(objectReaderImpl.queue.stdout) - if err != nil { - require.True(t, errors.Is(err, os.ErrClosed)) - } else { - require.NoError(t, err) - } - require.Empty(t, output) - require.True(t, reader.isClosed()) require.Empty(t, keys(t, &cache.objectReaders)) }) t.Run("cacheable", func(t *testing.T) { defer cache.Evict() - ctx, cancel := context.WithCancel(testhelper.Context(t)) - ctx = correlation.ContextWithCorrelation(ctx, "1") + + ctx := correlation.ContextWithCorrelation(ctx, "1") ctx = testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(SessionIDField, "1"), ) - reader, err := cache.ObjectReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectReader(ctx, repoExecutor) require.NoError(t, err) // Cancel the context such that the process will be considered for return to the // cache and wait for the cache to collect it. - cache.cachedProcessDone.L.Lock() cancel() - defer cache.cachedProcessDone.L.Unlock() - cache.cachedProcessDone.Wait() keys := keys(t, &cache.objectReaders) require.Equal(t, []key{{ @@ -248,31 +252,27 @@ func TestCache_ObjectReader(t *testing.T) { }}, keys) // Assert that we can still read from the cached process. - _, err = reader.Object(ctx, "refs/heads/master") + _, err = reader.Object(ctx, "refs/heads/main") require.NoError(t, err) }) t.Run("dirty process does not get cached", func(t *testing.T) { defer cache.Evict() - ctx, cancel := context.WithCancel(testhelper.Context(t)) - ctx = testhelper.MergeIncomingMetadata(ctx, + + ctx := testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(SessionIDField, "1"), ) - reader, err := cache.ObjectReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectReader(ctx, repoExecutor) require.NoError(t, err) // While we request object data, we do not consume it at all. The reader is thus // dirty and cannot be reused and shouldn't be returned to the cache. - object, err := reader.Object(ctx, "refs/heads/master") + object, err := reader.Object(ctx, "refs/heads/main") require.NoError(t, err) - // Cancel the context such that the process will be considered for return to the - // cache and wait for the cache to collect it. - cache.cachedProcessDone.L.Lock() + // Cancel the process such that it will be considered for return to the cache. cancel() - defer cache.cachedProcessDone.L.Unlock() - cache.cachedProcessDone.Wait() require.Empty(t, keys(t, &cache.objectReaders)) @@ -283,91 +283,65 @@ func TestCache_ObjectReader(t *testing.T) { t.Run("closed process does not get cached", func(t *testing.T) { defer cache.Evict() - ctx, cancel := context.WithCancel(testhelper.Context(t)) - ctx = testhelper.MergeIncomingMetadata(ctx, + + ctx := testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(SessionIDField, "1"), ) - reader, err := cache.ObjectReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectReader(ctx, repoExecutor) require.NoError(t, err) // Closed processes naturally cannot be reused anymore and thus shouldn't ever get // cached. reader.close() - // Cancel the context such that the process will be considered for return to the - // cache and wait for the cache to collect it. - cache.cachedProcessDone.L.Lock() + // Cancel the process such that it will be considered for return to the cache. cancel() - defer cache.cachedProcessDone.L.Unlock() - cache.cachedProcessDone.Wait() require.Empty(t, keys(t, &cache.objectReaders)) }) } func TestCache_ObjectInfoReader(t *testing.T) { - cfg, repo, _ := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + repoExecutor := newRepoExecutor(t, cfg, repo) cache := newCache(time.Hour, 10, helper.NewManualTicker()) defer cache.Stop() - cache.cachedProcessDone = sync.NewCond(&sync.Mutex{}) - - t.Run("uncancellable", func(t *testing.T) { - ctx := testhelper.ContextWithoutCancel() - - require.PanicsWithValue(t, "empty ctx.Done() in catfile.Batch.New()", func() { - _, _ = cache.ObjectInfoReader(ctx, repoExecutor) - }) - }) t.Run("uncacheable", func(t *testing.T) { - ctx, cancel := context.WithCancel(testhelper.Context(t)) - // The context doesn't carry a session ID and is thus uncacheable. // The process should never get returned to the cache and must be // killed on context cancellation. - reader, err := cache.ObjectInfoReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectInfoReader(ctx, repoExecutor) require.NoError(t, err) - objectInfoReaderImpl, ok := reader.(*objectInfoReader) - require.True(t, ok, "expected object reader") - cancel() - // We're cheating a bit here to avoid creating a racy test by reaching into the - // process and trying to read from its stdout. If the cancel did kill the process as - // expected, then the stdout should be closed and we'll get an EOF. - output, err := io.ReadAll(objectInfoReaderImpl.queue.stdout) - if err != nil { - require.True(t, errors.Is(err, os.ErrClosed)) - } else { - require.NoError(t, err) - } - require.Empty(t, output) - require.True(t, reader.isClosed()) require.Empty(t, keys(t, &cache.objectInfoReaders)) }) t.Run("cacheable", func(t *testing.T) { defer cache.Evict() - ctx, cancel := context.WithCancel(testhelper.Context(t)) - ctx = correlation.ContextWithCorrelation(ctx, "1") + + ctx := correlation.ContextWithCorrelation(ctx, "1") ctx = testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(SessionIDField, "1"), ) - reader, err := cache.ObjectInfoReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectInfoReader(ctx, repoExecutor) require.NoError(t, err) - // Cancel the context such that the process will be considered for return to the - // cache and wait for the cache to collect it. - cache.cachedProcessDone.L.Lock() + // Cancel the process such it will be considered for return to the cache. cancel() - defer cache.cachedProcessDone.L.Unlock() - cache.cachedProcessDone.Wait() keys := keys(t, &cache.objectInfoReaders) require.Equal(t, []key{{ @@ -377,30 +351,26 @@ func TestCache_ObjectInfoReader(t *testing.T) { }}, keys) // Assert that we can still read from the cached process. - _, err = reader.Info(ctx, "refs/heads/master") + _, err = reader.Info(ctx, "refs/heads/main") require.NoError(t, err) }) t.Run("closed process does not get cached", func(t *testing.T) { defer cache.Evict() - ctx, cancel := context.WithCancel(testhelper.Context(t)) - ctx = testhelper.MergeIncomingMetadata(ctx, + + ctx := testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(SessionIDField, "1"), ) - reader, err := cache.ObjectInfoReader(ctx, repoExecutor) + reader, cancel, err := cache.ObjectInfoReader(ctx, repoExecutor) require.NoError(t, err) // Closed processes naturally cannot be reused anymore and thus shouldn't ever get // cached. reader.close() - // Cancel the context such that the process will be considered for return to the - // cache and wait for the cache to collect it. - cache.cachedProcessDone.L.Lock() + // Cancel the process such that it will be considered for return to the cache. cancel() - defer cache.cachedProcessDone.L.Unlock() - cache.cachedProcessDone.Wait() require.Empty(t, keys(t, &cache.objectInfoReaders)) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit.go index a586a70085..93799e3dc6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit.go @@ -7,10 +7,10 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // GetCommit looks up a commit by revision using an existing Batch instance. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit_test.go new file mode 100644 index 0000000000..81fceccecf --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/commit_test.go @@ -0,0 +1,94 @@ +package catfile + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/metadata" +) + +func TestGetCommit(t *testing.T) { + ctx := testhelper.Context(t) + ctx = metadata.NewIncomingContext(ctx, metadata.MD{}) + + cfg, objectReader, _, repoPath := setupObjectReader(t, ctx) + + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("data")) + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "file", Mode: "100644", OID: blobID}, + }) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("commit message\n\ncommit body"), gittest.WithTree(treeID)) + + for _, tc := range []struct { + desc string + revision string + expectedErr error + expectedCommit *gitalypb.GitCommit + }{ + { + desc: "commit", + revision: commitID.String(), + expectedCommit: &gitalypb.GitCommit{ + Id: commitID.String(), + TreeId: treeID.String(), + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, + Body: []byte("commit message\n\ncommit body"), + BodySize: 27, + Subject: []byte("commit message"), + }, + }, + { + desc: "not existing commit", + revision: "not existing revision", + expectedErr: NotFoundError{errors.New("object not found")}, + }, + { + desc: "blob sha", + revision: blobID.String(), + expectedErr: NotFoundError{errors.New("object not found")}, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + commit, err := GetCommit(ctx, objectReader, git.Revision(tc.revision)) + require.Equal(t, tc.expectedErr, err) + testhelper.ProtoEqual(t, tc.expectedCommit, commit) + }) + } +} + +func TestGetCommitWithTrailers(t *testing.T) { + ctx := testhelper.Context(t) + ctx = metadata.NewIncomingContext(ctx, metadata.MD{}) + + cfg, objectReader, repo, repoPath := setupObjectReader(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage( + "some header\n"+ + "\n"+ + "Commit message.\n"+ + "\n"+ + "Signed-off-by: John Doe \n"+ + "Signed-off-by: Jane Doe \n", + )) + + commit, err := GetCommitWithTrailers(ctx, gittest.NewCommandFactory(t, cfg), repo, objectReader, commitID.Revision()) + + require.NoError(t, err) + + require.Equal(t, commit.Trailers, []*gitalypb.CommitTrailer{ + { + Key: []byte("Signed-off-by"), + Value: []byte("John Doe "), + }, + { + Key: []byte("Signed-off-by"), + Value: []byte("Jane Doe "), + }, + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader.go index 300459e818..595f6d52e6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader.go @@ -8,10 +8,9 @@ import ( "strings" "sync/atomic" - "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // ObjectInfo represents a header returned by `git cat-file --batch` @@ -50,8 +49,9 @@ func IsNotFound(err error) bool { return ok } -// ParseObjectInfo reads from a reader and parses the data into an ObjectInfo struct -func ParseObjectInfo(stdout *bufio.Reader) (*ObjectInfo, error) { +// ParseObjectInfo reads from a reader and parses the data into an ObjectInfo struct with the given +// object hash. +func ParseObjectInfo(objectHash git.ObjectHash, stdout *bufio.Reader) (*ObjectInfo, error) { restart: infoLine, err := stdout.ReadString('\n') if err != nil { @@ -76,7 +76,7 @@ restart: return nil, fmt.Errorf("invalid info line: %q", infoLine) } - oid, err := git.NewObjectIDFromHex(info[0]) + oid, err := objectHash.FromHex(info[0]) if err != nil { return nil, fmt.Errorf("parse object ID: %w", err) } @@ -126,7 +126,8 @@ type ObjectInfoQueue interface { // long-lived `git cat-file --batch-check` process such that we do not have to spawn a separate // process per object info we're about to read. type objectInfoReader struct { - cmd *command.Command + cmd *command.Command + objectHash git.ObjectHash counter *prometheus.CounterVec @@ -139,8 +140,6 @@ func newObjectInfoReader( repo git.RepositoryExecutor, counter *prometheus.CounterVec, ) (*objectInfoReader, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "catfile.ObjectInfoReader") - batchCmd, err := repo.Exec(ctx, git.SubCmd{ Name: "cat-file", @@ -149,26 +148,27 @@ func newObjectInfoReader( git.Flag{Name: "--buffer"}, }, }, - git.WithStdin(command.SetupStdin), + git.WithSetupStdin(), ) if err != nil { return nil, err } + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return nil, fmt.Errorf("detecting object hash: %w", err) + } + objectInfoReader := &objectInfoReader{ - cmd: batchCmd, - counter: counter, + cmd: batchCmd, + objectHash: objectHash, + counter: counter, queue: requestQueue{ - stdout: bufio.NewReader(batchCmd), - stdin: bufio.NewWriter(batchCmd), + objectHash: objectHash, + stdout: bufio.NewReader(batchCmd), + stdin: bufio.NewWriter(batchCmd), }, } - go func() { - <-ctx.Done() - // This is crucial to prevent leaking file descriptors. - objectInfoReader.close() - span.Finish() - }() return objectInfoReader, nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_fuzz.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_fuzz.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_fuzz.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_fuzz.go index 130abb4e7d..a21b7bee53 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_fuzz.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_fuzz.go @@ -1,15 +1,16 @@ //go:build gofuzz -// +build gofuzz package catfile import ( "bufio" "bytes" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) func Fuzz(data []byte) int { reader := bufio.NewReader(bytes.NewReader(data)) - ParseObjectInfo(reader) + ParseObjectInfo(git.ObjectHashSHA1, reader) return 0 } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_test.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_test.go index 3a9e44776c..25d784bb7a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_info_reader_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_info_reader_test.go @@ -4,93 +4,132 @@ import ( "bufio" "errors" "fmt" + "io" "os" + "strconv" "strings" "testing" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) -func TestParseObjectInfoSuccess(t *testing.T) { - testCases := []struct { - desc string - input string - output *ObjectInfo - notFound bool +func TestParseObjectInfo_success(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + desc string + input string + expectedErr error + expectedObjectInfo *ObjectInfo }{ { desc: "existing object", - input: "7c9373883988204e5a9f72c4a5119cbcefc83627 commit 222\n", - output: &ObjectInfo{ - Oid: "7c9373883988204e5a9f72c4a5119cbcefc83627", + input: fmt.Sprintf("%s commit 222\n", gittest.DefaultObjectHash.EmptyTreeOID), + expectedObjectInfo: &ObjectInfo{ + Oid: gittest.DefaultObjectHash.EmptyTreeOID, Type: "commit", Size: 222, }, }, { - desc: "non existing object", - input: "bla missing\n", - notFound: true, + desc: "non existing object", + input: "bla missing\n", + expectedErr: NotFoundError{fmt.Errorf("object not found")}, }, - } - - for _, tc := range testCases { + } { t.Run(tc.desc, func(t *testing.T) { reader := bufio.NewReader(strings.NewReader(tc.input)) - output, err := ParseObjectInfo(reader) - if tc.notFound { - require.True(t, IsNotFound(err), "expect NotFoundError") - return - } - require.NoError(t, err) - require.Equal(t, tc.output, output) + objectInfo, err := ParseObjectInfo(gittest.DefaultObjectHash, reader) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedObjectInfo, objectInfo) }) } } -func TestParseObjectInfoErrors(t *testing.T) { - testCases := []struct { - desc string - input string - }{ - {desc: "missing newline", input: "7c9373883988204e5a9f72c4a5119cbcefc83627 commit 222"}, - {desc: "too few words", input: "7c9373883988204e5a9f72c4a5119cbcefc83627 commit\n"}, - {desc: "too many words", input: "7c9373883988204e5a9f72c4a5119cbcefc83627 commit 222 bla\n"}, - {desc: "parse object size", input: "7c9373883988204e5a9f72c4a5119cbcefc83627 commit bla\n"}, - } +func TestParseObjectInfo_errors(t *testing.T) { + t.Parallel() - for _, tc := range testCases { + oid := gittest.DefaultObjectHash.EmptyTreeOID + + for _, tc := range []struct { + desc string + input string + expectedErr error + }{ + { + desc: "missing newline", + input: fmt.Sprintf("%s commit 222", oid), + expectedErr: fmt.Errorf("read info line: %w", io.EOF), + }, + { + desc: "too few words", + input: fmt.Sprintf("%s commit\n", oid), + expectedErr: fmt.Errorf("invalid info line: %q", oid+" commit"), + }, + { + desc: "too many words", + input: fmt.Sprintf("%s commit 222 bla\n", oid), + expectedErr: fmt.Errorf("invalid info line: %q", oid+" commit 222 bla"), + }, + { + desc: "invalid object hash", + input: "7c9373883988204e5a9f72c4 commit 222 bla\n", + expectedErr: fmt.Errorf("invalid info line: %q", "7c9373883988204e5a9f72c4 commit 222 bla"), + }, + { + desc: "parse object size", + input: fmt.Sprintf("%s commit bla\n", oid), + expectedErr: fmt.Errorf("parse object size: %w", &strconv.NumError{ + Func: "ParseInt", + Num: "bla", + Err: strconv.ErrSyntax, + }), + }, + } { t.Run(tc.desc, func(t *testing.T) { reader := bufio.NewReader(strings.NewReader(tc.input)) - _, err := ParseObjectInfo(reader) - require.Error(t, err) + _, err := ParseObjectInfo(gittest.DefaultObjectHash, reader) + require.Equal(t, tc.expectedErr, err) }) } } func TestObjectInfoReader(t *testing.T) { - ctx := testhelper.Context(t) + t.Parallel() - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + commitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch("main"), + gittest.WithMessage("commit message"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "README", Mode: "100644", Content: "something"}), + ) + gittest.WriteTag(t, cfg, repoPath, "v1.1.1", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", + }) oiByRevision := make(map[string]*ObjectInfo) for _, revision := range []string{ - "refs/heads/master", - "refs/heads/master^{tree}", - "refs/heads/master:README", + "refs/heads/main", + "refs/heads/main^{tree}", + "refs/heads/main:README", "refs/tags/v1.1.1", } { revParseOutput := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", revision) - objectID, err := git.NewObjectIDFromHex(text.ChompBytes(revParseOutput)) + objectID, err := gittest.DefaultObjectHash.FromHex(text.ChompBytes(revParseOutput)) require.NoError(t, err) objectType := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "cat-file", "-t", revision)) @@ -111,23 +150,23 @@ func TestObjectInfoReader(t *testing.T) { }{ { desc: "commit by ref", - revision: "refs/heads/master", - expectedInfo: oiByRevision["refs/heads/master"], + revision: "refs/heads/main", + expectedInfo: oiByRevision["refs/heads/main"], }, { desc: "commit by ID", - revision: oiByRevision["refs/heads/master"].Oid.Revision(), - expectedInfo: oiByRevision["refs/heads/master"], + revision: oiByRevision["refs/heads/main"].Oid.Revision(), + expectedInfo: oiByRevision["refs/heads/main"], }, { desc: "tree", - revision: oiByRevision["refs/heads/master^{tree}"].Oid.Revision(), - expectedInfo: oiByRevision["refs/heads/master^{tree}"], + revision: oiByRevision["refs/heads/main^{tree}"].Oid.Revision(), + expectedInfo: oiByRevision["refs/heads/main^{tree}"], }, { desc: "blob", - revision: oiByRevision["refs/heads/master:README"].Oid.Revision(), - expectedInfo: oiByRevision["refs/heads/master:README"], + revision: oiByRevision["refs/heads/main:README"].Oid.Revision(), + expectedInfo: oiByRevision["refs/heads/main:README"], }, { desc: "tag", @@ -160,7 +199,7 @@ func TestObjectInfoReader(t *testing.T) { // Verify that we do another request no matter whether the previous call // succeeded or failed. - _, err = reader.Info(ctx, "refs/heads/master") + _, err = reader.Info(ctx, "refs/heads/main") require.NoError(t, err) require.Equal(t, float64(expectedRequests+1), testutil.ToFloat64(counter.WithLabelValues("info"))) @@ -169,9 +208,13 @@ func TestObjectInfoReader(t *testing.T) { } func TestObjectInfoReader_queue(t *testing.T) { - ctx := testhelper.Context(t) + t.Parallel() - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) blobOID := gittest.WriteBlob(t, cfg, repoPath, []byte("foobar")) blobInfo := ObjectInfo{ @@ -184,7 +227,12 @@ func TestObjectInfoReader_queue(t *testing.T) { commitInfo := ObjectInfo{ Oid: commitOID, Type: "commit", - Size: 225, + Size: func() int64 { + if gittest.ObjectHashIsSHA256() { + return 201 + } + return 177 + }(), } t.Run("read single info", func(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader.go index 7020adcbea..243e708653 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader.go @@ -5,13 +5,11 @@ import ( "context" "fmt" "io" - "os" "sync/atomic" - "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // ObjectReader is a reader for Git objects. @@ -61,8 +59,6 @@ func newObjectReader( repo git.RepositoryExecutor, counter *prometheus.CounterVec, ) (*objectReader, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "catfile.ObjectReader") - batchCmd, err := repo.Exec(ctx, git.SubCmd{ Name: "cat-file", @@ -71,26 +67,27 @@ func newObjectReader( git.Flag{Name: "--buffer"}, }, }, - git.WithStdin(command.SetupStdin), + git.WithSetupStdin(), ) if err != nil { return nil, err } + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return nil, fmt.Errorf("detecting object hash: %w", err) + } + objectReader := &objectReader{ cmd: batchCmd, counter: counter, queue: requestQueue{ + objectHash: objectHash, isObjectQueue: true, stdout: bufio.NewReader(batchCmd), stdin: bufio.NewWriter(batchCmd), }, } - go func() { - <-ctx.Done() - objectReader.close() - span.Finish() - }() return objectReader, nil } @@ -155,68 +152,21 @@ func (o *objectReader) ObjectQueue(ctx context.Context) (ObjectQueue, func(), er // Object represents data returned by `git cat-file --batch` type Object struct { - // bytesRemaining tracks the number of bytes which are left to be read. While this duplicates the - // information tracked in dataReader.N, this cannot be helped given that we need to make - // access to this information atomic so there's no race between updating it and checking the - // process for dirtiness. While we could use locking instead of atomics, we'd have to lock - // during the whole read duration -- and thus it'd become impossible to check for dirtiness - // at the same time. - // - // We list the atomic fields first to ensure they are 64-bit and 32-bit aligned: - // https://pkg.go.dev/sync/atomic#pkg-note-BUG - bytesRemaining int64 - - // closed determines whether the object is closed for reading. - closed int32 - // ObjectInfo represents main information about object ObjectInfo // dataReader is reader which has all the object data. - dataReader io.LimitedReader -} - -// isDirty determines whether the object is still dirty, that is whether there are still unconsumed -// bytes. -func (o *Object) isDirty() bool { - return atomic.LoadInt64(&o.bytesRemaining) != 0 -} - -func (o *Object) isClosed() bool { - return atomic.LoadInt32(&o.closed) == 1 -} - -func (o *Object) close() { - atomic.StoreInt32(&o.closed, 1) + dataReader io.Reader } func (o *Object) Read(p []byte) (int, error) { - if o.isClosed() { - return 0, os.ErrClosed - } - - n, err := o.dataReader.Read(p) - if atomic.AddInt64(&o.bytesRemaining, int64(-n)) < 0 { - return n, fmt.Errorf("bytes remaining became negative while reading object") - } - - return n, err + return o.dataReader.Read(p) } // WriteTo implements the io.WriterTo interface. It defers the write to the embedded object reader // via `io.Copy()`, which in turn will use `WriteTo()` or `ReadFrom()` in case these interfaces are // implemented by the respective reader or writer. func (o *Object) WriteTo(w io.Writer) (int64, error) { - if o.isClosed() { - return 0, os.ErrClosed - } - - // While the `io.LimitedReader` does not support WriteTo, `io.Copy()` will make use of - // `ReadFrom()` in case the writer implements it. - n, err := io.Copy(w, &o.dataReader) - if atomic.AddInt64(&o.bytesRemaining, -n) < 0 { - return n, fmt.Errorf("bytes remaining became negative while reading object") - } - - return n, err + // `io.Copy()` will make use of `ReadFrom()` in case the writer implements it. + return io.Copy(w, o.dataReader) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader_test.go index 9686a0c158..83b3a46d00 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/object_reader_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/object_reader_test.go @@ -10,27 +10,37 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestObjectReader_reader(t *testing.T) { ctx := testhelper.Context(t) - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) - commitID, err := git.NewObjectIDFromHex(text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/master"))) - require.NoError(t, err) - commitContents := gittest.Exec(t, cfg, "-C", repoPath, "cat-file", "-p", "refs/heads/master") + commitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch("main"), + gittest.WithMessage("commit message"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "README", Mode: "100644", Content: "something"}), + ) + gittest.WriteTag(t, cfg, repoPath, "v1.1.1", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", + }) + + commitContents := gittest.Exec(t, cfg, "-C", repoPath, "cat-file", "-p", commitID.String()) t.Run("read existing object by ref", func(t *testing.T) { reader, err := newObjectReader(ctx, newRepoExecutor(t, cfg, repoProto), nil) require.NoError(t, err) - object, err := reader.Object(ctx, "refs/heads/master") + object, err := reader.Object(ctx, "refs/heads/main") require.NoError(t, err) data, err := io.ReadAll(object) @@ -47,8 +57,7 @@ func TestObjectReader_reader(t *testing.T) { data, err := io.ReadAll(object) require.NoError(t, err) - - require.Contains(t, string(data), "Merge branch 'cherry-pick-ce369011' into 'master'\n") + require.Equal(t, data, commitContents) }) t.Run("read missing ref", func(t *testing.T) { @@ -102,9 +111,9 @@ func TestObjectReader_reader(t *testing.T) { require.NoError(t, err) for objectType, revision := range map[string]git.Revision{ - "commit": "refs/heads/master", - "tree": "refs/heads/master^{tree}", - "blob": "refs/heads/master:README", + "commit": "refs/heads/main", + "tree": "refs/heads/main^{tree}", + "blob": "refs/heads/main:README", "tag": "refs/tags/v1.1.1", } { require.Equal(t, float64(0), testutil.ToFloat64(counter.WithLabelValues(objectType))) @@ -123,7 +132,10 @@ func TestObjectReader_reader(t *testing.T) { func TestObjectReader_queue(t *testing.T) { ctx := testhelper.Context(t) - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) foobarBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("foobar")) barfooBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("barfoo")) @@ -411,7 +423,6 @@ func TestObjectReader_queue(t *testing.T) { require.True(t, reader.isClosed()) require.True(t, queue.isClosed()) - require.True(t, object.isClosed()) _, err = io.ReadAll(object) require.Equal(t, os.ErrClosed, err) @@ -419,9 +430,13 @@ func TestObjectReader_queue(t *testing.T) { } func TestObjectReader_replaceRefs(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + originalOID := gittest.WriteBlob(t, cfg, repoPath, []byte("original")) replacedOID := gittest.WriteBlob(t, cfg, repoPath, []byte("replaced")) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser.go index 41e8e50297..239ce1ea24 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser.go @@ -7,10 +7,11 @@ import ( "io" "strconv" "strings" + "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -124,6 +125,11 @@ func (p *parser) ParseCommit(object git.Object) (*gitalypb.GitCommit, error) { const maxUnixCommitDate = 1 << 53 +// fallbackTimeValue is the value returned in case there is a parse error. It's the maximum +// time value possible in golang. See +// https://gitlab.com/gitlab-org/gitaly/issues/556#note_40289573 +var fallbackTimeValue = time.Unix(1<<63-62135596801, 999999999) + func parseCommitAuthor(line string) *gitalypb.CommitAuthor { author := &gitalypb.CommitAuthor{} @@ -149,7 +155,7 @@ func parseCommitAuthor(line string) *gitalypb.CommitAuthor { sec, err := strconv.ParseInt(secSplit[0], 10, 64) if err != nil || sec > maxUnixCommitDate || sec < 0 { - sec = git.FallbackTimeValue.Unix() + sec = fallbackTimeValue.Unix() } author.Date = ×tamppb.Timestamp{Seconds: sec} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser_test.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser_test.go index 25338156f6..59afbb1278 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/parser_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/parser_test.go @@ -2,20 +2,24 @@ package catfile import ( "bytes" + "fmt" "strings" "testing" "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) func TestParser_ParseCommit(t *testing.T) { + t.Parallel() + info := &ObjectInfo{ - Oid: "a984dfa4dee018c6d5f5f57ffec0d0e22763df16", + Oid: gittest.DefaultObjectHash.EmptyTreeOID, Type: "commit", } @@ -26,7 +30,7 @@ func TestParser_ParseCommit(t *testing.T) { // Once a repository contains a pathological object it can be hard to get // rid of it. Because of this I think it's nicer to ignore such objects // than to throw hard errors. - testCases := []struct { + for _, tc := range []struct { desc string in string out *gitalypb.GitCommit @@ -117,9 +121,7 @@ fF3T79iV8paT4/OfX8Ygg= }, }, }, - } - - for _, tc := range testCases { + } { t.Run(tc.desc, func(t *testing.T) { info.Size = int64(len(tc.in)) out, err := NewParser().ParseCommit(newStaticObject(tc.in, "commit", info.Oid)) @@ -130,6 +132,8 @@ fF3T79iV8paT4/OfX8Ygg= } func TestParseCommitAuthor(t *testing.T) { + t.Parallel() + for _, tc := range []struct { desc string author string @@ -175,6 +179,10 @@ func TestParseCommitAuthor(t *testing.T) { } func TestParser_ParseTag(t *testing.T) { + t.Parallel() + + oid := gittest.DefaultObjectHash.EmptyTreeOID.String() + for _, tc := range []struct { desc string oid git.ObjectID @@ -184,7 +192,7 @@ func TestParser_ParseTag(t *testing.T) { }{ { desc: "tag without a message", - contents: "object c92faf3e0a557270141be67f206d7cdb99bfc3a2\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200", + contents: fmt.Sprintf("object %s\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200", oid), oid: "1234", expectedTag: &gitalypb.Tag{ Id: "1234", @@ -199,13 +207,13 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, { desc: "tag with message", - contents: "object c92faf3e0a557270141be67f206d7cdb99bfc3a2\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nmessage", + contents: fmt.Sprintf("object %s\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nmessage", oid), oid: "1234", expectedTag: &gitalypb.Tag{ Id: "1234", @@ -222,14 +230,14 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, { desc: "tag with empty message", oid: "1234", - contents: "object c92faf3e0a557270141be67f206d7cdb99bfc3a2\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\n", + contents: fmt.Sprintf("object %s\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\n", oid), expectedTag: &gitalypb.Tag{ Id: "1234", Name: []byte("v2.6.16.28"), @@ -244,14 +252,14 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, { desc: "tag with message with empty line", oid: "1234", - contents: "object c92faf3e0a557270141be67f206d7cdb99bfc3a2\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nHello world\n\nThis is a message", + contents: fmt.Sprintf("object %s\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nHello world\n\nThis is a message", oid), expectedTag: &gitalypb.Tag{ Id: "1234", Name: []byte("v2.6.16.28"), @@ -267,13 +275,13 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, { desc: "tag with message with empty line and right side new line", - contents: "object c92faf3e0a557270141be67f206d7cdb99bfc3a2\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nHello world\n\nThis is a message\n\n", + contents: fmt.Sprintf("object %s\ntype commit\ntag v2.6.16.28\ntagger Adrian Bunk 1156539089 +0200\n\nHello world\n\nThis is a message\n\n", oid), oid: "1234", expectedTag: &gitalypb.Tag{ Id: "1234", @@ -290,13 +298,13 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, { desc: "tag with missing date and body", - contents: "object 422081655f743e03b01ee29a2eaf26aab0ee7eda\ntype commit\ntag syslinux-3.11-pre6\ntagger hpa \n", + contents: fmt.Sprintf("object %s\ntype commit\ntag syslinux-3.11-pre6\ntagger hpa \n", oid), oid: "1234", expectedTag: &gitalypb.Tag{ Id: "1234", @@ -307,14 +315,14 @@ func TestParser_ParseTag(t *testing.T) { }, }, expectedTagged: taggedObject{ - objectID: "422081655f743e03b01ee29a2eaf26aab0ee7eda", + objectID: oid, objectType: "commit", }, }, { desc: "tag signed with SSH", oid: "1234", - contents: `object c92faf3e0a557270141be67f206d7cdb99bfc3a2 + contents: fmt.Sprintf(`object %s type commit tag v2.6.16.28 tagger Adrian Bunk 1156539089 +0200 @@ -325,7 +333,7 @@ U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgtc+Qk8jhMwVZk/jFEFCM16LNQb 30q5kK30bbetfjyTMAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQLSyv010gOFwIs9QTtDvlfIEWiAw2iQL/T9usGcxHXn/W5l0cOFCd7O+WaMDg0t0nW fF3T79iV8paT4/OfX8Ygg= ------END SSH SIGNATURE-----`, +-----END SSH SIGNATURE-----`, oid), expectedTag: &gitalypb.Tag{ Id: "1234", Name: []byte("v2.6.16.28"), @@ -348,7 +356,7 @@ fF3T79iV8paT4/OfX8Ygg= SignatureType: gitalypb.SignatureType_SSH, }, expectedTagged: taggedObject{ - objectID: "c92faf3e0a557270141be67f206d7cdb99bfc3a2", + objectID: oid, objectType: "commit", }, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/request_queue.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/request_queue.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue.go index 5b99d1e9e1..232d731b1c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/request_queue.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue.go @@ -5,10 +5,9 @@ import ( "fmt" "io" "os" - "sync" "sync/atomic" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) const ( @@ -22,6 +21,10 @@ const ( ) type requestQueue struct { + // objectHash is the object hash used by the repository the request queue has been + // spawned for. + objectHash git.ObjectHash + // outstandingRequests is the number of requests which have been queued up. Gets incremented // on request, and decremented when starting to read an object (not when that object has // been fully consumed). @@ -33,6 +36,9 @@ type requestQueue struct { // closed indicates whether the queue is closed for additional requests. closed int32 + // isReadingObject indicates whether there is a read in progress. + isReadingObject int32 + // isObjectQueue is set to `true` when this is a request queue which can be used for reading // objects. If set to `false`, then this can only be used to read object info. isObjectQueue bool @@ -40,10 +46,6 @@ type requestQueue struct { stdout *bufio.Reader stdin *bufio.Writer - // currentObject is the currently read object. - currentObject *Object - currentObjectLock sync.Mutex - // trace is the current tracing span. trace *trace } @@ -51,13 +53,8 @@ type requestQueue struct { // isDirty returns true either if there are outstanding requests for objects or if the current // object hasn't yet been fully consumed. func (q *requestQueue) isDirty() bool { - q.currentObjectLock.Lock() - defer q.currentObjectLock.Unlock() - - // We must check for the current object first: we cannot queue another object due to the - // object lock, but we may queue another request while checking for dirtiness. - if q.currentObject != nil { - return q.currentObject.isDirty() + if atomic.LoadInt32(&q.isReadingObject) != 0 { + return true } if atomic.LoadInt64(&q.outstandingRequests) != 0 { @@ -72,14 +69,7 @@ func (q *requestQueue) isClosed() bool { } func (q *requestQueue) close() { - if atomic.CompareAndSwapInt32(&q.closed, 0, 1) { - q.currentObjectLock.Lock() - defer q.currentObjectLock.Unlock() - - if q.currentObject != nil { - q.currentObject.close() - } - } + atomic.StoreInt32(&q.closed, 1) } func (q *requestQueue) RequestRevision(revision git.Revision) error { @@ -122,46 +112,74 @@ func (q *requestQueue) Flush() error { return nil } +type readerFunc func([]byte) (int, error) + +func (fn readerFunc) Read(buf []byte) (int, error) { return fn(buf) } + func (q *requestQueue) ReadObject() (*Object, error) { if !q.isObjectQueue { panic("object queue used to read object info") } - q.currentObjectLock.Lock() - defer q.currentObjectLock.Unlock() - - if q.currentObject != nil { - // If the current object is still dirty, then we must not try to read a new object. - if q.currentObject.isDirty() { - return nil, fmt.Errorf("current object has not been fully read") - } - - q.currentObject.close() - q.currentObject = nil - - // If we have already read an object before, then we must consume the trailing - // newline after the object's data. - if _, err := q.stdout.ReadByte(); err != nil { - return nil, err - } + // We need to ensure that only a single call to `ReadObject()` can happen at the + // same point in time. + // + // Note that this must happen before we read the current object: otherwise, a + // concurrent caller might've already swapped it out under our feet. + if !atomic.CompareAndSwapInt32(&q.isReadingObject, 0, 1) { + return nil, fmt.Errorf("current object has not been fully read") } objectInfo, err := q.readInfo() if err != nil { + // In the general case we cannot know why reading the object's info has failed. And + // given that git-cat-file(1) is stateful, we cannot say whether it's safe to + // continue reading from it now or whether we need to keep the queue dirty instead. + // So we keep `isReadingObject == 0` in the general case so that it continues to + // stay dirty. + // + // One known exception is when we've got a NotFoundError: this is a graceful failure + // and we can continue reading from the process. + if IsNotFound(err) { + atomic.StoreInt32(&q.isReadingObject, 0) + } + return nil, err } q.trace.recordRequest(objectInfo.Type) - q.currentObject = &Object{ - ObjectInfo: *objectInfo, - dataReader: io.LimitedReader{ + // objectReader first reads the object data from stdout. After that, it discards + // the trailing newline byte that separate the different objects. Finally, it + // undirties the reader so the next object can be read. + objectReader := io.MultiReader( + &io.LimitedReader{ R: q.stdout, N: objectInfo.Size, }, - bytesRemaining: objectInfo.Size, - } + readerFunc(func([]byte) (int, error) { + if _, err := io.CopyN(io.Discard, q.stdout, 1); err != nil { + return 0, fmt.Errorf("discard newline: %q", err) + } - return q.currentObject, nil + atomic.StoreInt32(&q.isReadingObject, 0) + + return 0, io.EOF + }), + ) + + return &Object{ + ObjectInfo: *objectInfo, + dataReader: readerFunc(func(buf []byte) (int, error) { + // The tests assert that no data can be read after the queue is closed. + // Some data could be actually read even after the queue closes due to the buffering. + // Check here if the queue is closed and refuse to read more if so. + if q.isClosed() { + return 0, os.ErrClosed + } + + return objectReader.Read(buf) + }), + }, nil } func (q *requestQueue) ReadInfo() (*ObjectInfo, error) { @@ -183,7 +201,7 @@ func (q *requestQueue) readInfo() (*ObjectInfo, error) { return nil, fmt.Errorf("cannot read object info: %w", os.ErrClosed) } - // We first need to determine wether there are any queued requests at all. If not, then we + // We first need to determine whether there are any queued requests at all. If not, then we // cannot read anything. queuedRequests := atomic.LoadInt64(&q.outstandingRequests) if queuedRequests == 0 { @@ -198,5 +216,5 @@ func (q *requestQueue) readInfo() (*ObjectInfo, error) { return nil, fmt.Errorf("concurrent read on request queue") } - return ParseObjectInfo(q.stdout) + return ParseObjectInfo(q.objectHash, q.stdout) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue_test.go new file mode 100644 index 0000000000..59f71e1544 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/request_queue_test.go @@ -0,0 +1,339 @@ +package catfile + +import ( + "context" + "fmt" + "io" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestRequestQueue_ReadObject(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + oid := git.ObjectID(strings.Repeat("1", gittest.DefaultObjectHash.EncodedLen())) + + t.Run("ReadInfo on ReadObject queue", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, "#!/bin/sh\nread\n") + + require.PanicsWithValue(t, "object queue used to read object info", func() { + _, _ = queue.ReadInfo() + }) + }) + + t.Run("read without request", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, "#!/bin/sh\nread\n") + _, err := queue.ReadObject() + require.Equal(t, fmt.Errorf("no outstanding request"), err) + }) + + t.Run("read on closed reader", func(t *testing.T) { + reader, queue := newInterceptedQueue(ctx, t, "#!/bin/sh\nread\n") + + require.NoError(t, queue.RequestRevision("foo")) + require.True(t, queue.isDirty()) + + reader.close() + require.True(t, queue.isDirty()) + + _, err := queue.ReadObject() + require.Equal(t, fmt.Errorf("cannot read object info: %w", fmt.Errorf("file already closed")), err) + }) + + t.Run("read with unconsumed object", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + echo "%s commit 464" + `, oid)) + + // We queue two revisions... + require.NoError(t, queue.RequestRevision("foo")) + require.NoError(t, queue.RequestRevision("foo")) + + // .. and only unqueue one object. This object isn't read though, ... + _, err := queue.ReadObject() + require.NoError(t, err) + + // ... which means that trying to read the second object should fail now. + _, err = queue.ReadObject() + require.Equal(t, fmt.Errorf("current object has not been fully read"), err) + + require.True(t, queue.isDirty()) + }) + + t.Run("read with invalid object header", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, `#!/bin/sh + echo "something something" + `) + + require.NoError(t, queue.RequestRevision("foo")) + + _, err := queue.ReadObject() + require.Equal(t, fmt.Errorf("invalid info line: %q", "something something"), err) + + // The queue must be dirty when we failed due to an unexpected error. + require.True(t, queue.isDirty()) + }) + + t.Run("read with unexpected exit", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, `#!/bin/sh + exit 1 + `) + + require.NoError(t, queue.RequestRevision("foo")) + + _, err := queue.ReadObject() + require.Equal(t, fmt.Errorf("read info line: %w", io.EOF), err) + + // The queue must be dirty when we failed due to an unexpected error. + require.True(t, queue.isDirty()) + }) + + t.Run("read with missing object", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + echo "%s missing" + `, oid)) + + require.NoError(t, queue.RequestRevision("foo")) + + _, err := queue.ReadObject() + require.Equal(t, NotFoundError{error: fmt.Errorf("object not found")}, err) + + // The queue must be empty even if the object wasn't found: this is a graceful + // failure that we should handle alright. + require.False(t, queue.isDirty()) + }) + + t.Run("read single object", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + echo "%s blob 10" + echo "1234567890" + `, oid)) + + require.NoError(t, queue.RequestRevision("foo")) + require.True(t, queue.isDirty()) + + object, err := queue.ReadObject() + require.NoError(t, err) + require.Equal(t, ObjectInfo{ + Oid: oid, + Type: "blob", + Size: 10, + }, object.ObjectInfo) + + data, err := io.ReadAll(object) + require.NoError(t, err) + require.Equal(t, "1234567890", string(data)) + + require.False(t, queue.isDirty()) + }) + + t.Run("read multiple objects", func(t *testing.T) { + secondOID := git.ObjectID(strings.Repeat("2", gittest.DefaultObjectHash.EncodedLen())) + + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + echo "%s blob 10" + echo "1234567890" + echo "%s commit 10" + echo "0987654321" + `, oid, secondOID)) + + require.NoError(t, queue.RequestRevision("foo")) + require.NoError(t, queue.RequestRevision("foo")) + require.True(t, queue.isDirty()) + + for _, expectedObject := range []struct { + info ObjectInfo + data string + }{ + { + info: ObjectInfo{ + Oid: oid, + Type: "blob", + Size: 10, + }, + data: "1234567890", + }, + { + info: ObjectInfo{ + Oid: secondOID, + Type: "commit", + Size: 10, + }, + data: "0987654321", + }, + } { + require.True(t, queue.isDirty()) + + object, err := queue.ReadObject() + require.NoError(t, err) + require.Equal(t, expectedObject.info, object.ObjectInfo) + + data, err := io.ReadAll(object) + require.NoError(t, err) + require.Equal(t, expectedObject.data, string(data)) + } + + require.False(t, queue.isDirty()) + }) + + t.Run("truncated object", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + echo "%s blob 10" + printf "123" + `, oid)) + + require.NoError(t, queue.RequestRevision("foo")) + require.True(t, queue.isDirty()) + + object, err := queue.ReadObject() + require.NoError(t, err) + require.Equal(t, ObjectInfo{ + Oid: oid, + Type: "blob", + Size: 10, + }, object.ObjectInfo) + + // The first read will succeed and return the prefix. + var buf [10]byte + n, err := object.Read(buf[:]) + require.NoError(t, err) + require.Equal(t, 3, n) + require.Equal(t, "123", string(buf[:n])) + + // But the second read must fail and give us a hint that the read had been + // truncated. Note that we explicitly expect to not see an io.EOF here, + // which might indicate success to the caller. + _, err = object.Read(buf[:]) + require.Equal(t, fmt.Errorf("discard newline: \"EOF\""), err) + + require.True(t, queue.isDirty()) + }) +} + +func TestRequestQueue_RequestRevision(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + oid := git.ObjectID(strings.Repeat("1", gittest.DefaultObjectHash.EncodedLen())) + + requireRevision := func(t *testing.T, queue *requestQueue, rev git.Revision) { + object, err := queue.ReadObject() + require.NoError(t, err) + + data, err := io.ReadAll(object) + require.NoError(t, err) + require.Equal(t, rev, git.Revision(data)) + } + + t.Run("requesting revision on closed queue", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, "#!/bin/sh") + queue.close() + + require.Equal(t, fmt.Errorf("cannot request revision: %w", os.ErrClosed), queue.RequestRevision("foo")) + }) + + t.Run("requesting revision on closed process", func(t *testing.T) { + process, queue := newInterceptedQueue(ctx, t, "#!/bin/sh") + + process.close() + + require.Equal(t, fmt.Errorf("cannot request revision: %w", os.ErrClosed), queue.RequestRevision("foo")) + }) + + t.Run("single request", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + read revision + echo "%s blob ${#revision}" + echo "${revision}" + `, oid)) + + require.NoError(t, queue.RequestRevision("foo")) + require.NoError(t, queue.Flush()) + + requireRevision(t, queue, "foo") + }) + + t.Run("multiple request", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + while read revision + do + echo "%s blob ${#revision}" + echo "${revision}" + done + `, oid)) + + require.NoError(t, queue.RequestRevision("foo")) + require.NoError(t, queue.RequestRevision("bar")) + require.NoError(t, queue.RequestRevision("baz")) + require.NoError(t, queue.RequestRevision("qux")) + require.NoError(t, queue.Flush()) + + requireRevision(t, queue, "foo") + requireRevision(t, queue, "bar") + requireRevision(t, queue, "baz") + requireRevision(t, queue, "qux") + }) + + t.Run("multiple request with intermediate flushing", func(t *testing.T) { + _, queue := newInterceptedQueue(ctx, t, fmt.Sprintf(`#!/bin/sh + while read revision + do + read flush + if test "$flush" != "FLUSH" + then + echo "expected a flush" + exit 1 + fi + + echo "%s blob ${#revision}" + echo "${revision}" + done + `, oid)) + + for _, revision := range []git.Revision{ + "foo", + "bar", + "foo", + "qux", + } { + require.NoError(t, queue.RequestRevision(revision)) + require.NoError(t, queue.Flush()) + requireRevision(t, queue, revision) + } + }) +} + +func newInterceptedQueue(ctx context.Context, t *testing.T, script string) (ObjectReader, *requestQueue) { + cfg := testcfg.Build(t) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + commandFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return script + }) + repoExecutor := repoExecutor{ + GitRepo: repo, + gitCmdFactory: commandFactory, + } + + reader, err := newObjectReader(ctx, &repoExecutor, nil) + require.NoError(t, err) + t.Cleanup(reader.close) + + queue, cleanup, err := reader.objectQueue(ctx, "trace") + require.NoError(t, err) + t.Cleanup(cleanup) + + return reader, queue +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag.go index 6d5a91622e..67f38e8faa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // GetTag looks up a commit by tagID using an existing catfile.Batch instance. Note: we pass diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag_test.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag_test.go index d34511e1bd..efc54e20ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tag_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tag_test.go @@ -2,55 +2,47 @@ package catfile import ( "fmt" - "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestGetTag(t *testing.T) { ctx := testhelper.Context(t) - cfg, objectReader, testRepo := setupObjectReader(t, ctx) + cfg, objectReader, _, repoPath := setupObjectReader(t, ctx) + commitID := gittest.WriteCommit(t, cfg, repoPath) - testRepoPath := filepath.Join(cfg.Storages[0].Path, testRepo.RelativePath) - - testCases := []struct { + for _, tc := range []struct { tagName string - rev git.Revision message string }{ { tagName: fmt.Sprintf("%s-v1.0.2", t.Name()), - rev: "master^^^^", message: strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1) + "\n", }, { tagName: fmt.Sprintf("%s-v1.0.0", t.Name()), - rev: "master^^^", message: "Prod Release v1.0.0\n", }, { tagName: fmt.Sprintf("%s-v1.0.1", t.Name()), - rev: "master^^", message: strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1) + "\n", }, - } + } { + t.Run(tc.tagName, func(t *testing.T) { + tagID := gittest.WriteTag(t, cfg, repoPath, tc.tagName, commitID.Revision(), gittest.WriteTagConfig{Message: tc.message}) - for _, testCase := range testCases { - t.Run(testCase.tagName, func(t *testing.T) { - tagID := gittest.WriteTag(t, cfg, testRepoPath, testCase.tagName, testCase.rev, gittest.WriteTagConfig{Message: testCase.message}) - - tag, err := GetTag(ctx, objectReader, git.Revision(tagID), testCase.tagName) + tag, err := GetTag(ctx, objectReader, git.Revision(tagID), tc.tagName) require.NoError(t, err) - require.Equal(t, testCase.message, string(tag.Message)) - require.Equal(t, testCase.tagName, string(tag.GetName())) + require.Equal(t, tc.message, string(tag.Message)) + require.Equal(t, tc.tagName, string(tag.GetName())) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/blob-dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/blob-dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/blob-dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/blob-dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/commit-e63f41fe459e62e1228fcef60d7189127aeba95a b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/commit-e63f41fe459e62e1228fcef60d7189127aeba95a similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/commit-e63f41fe459e62e1228fcef60d7189127aeba95a rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/commit-e63f41fe459e62e1228fcef60d7189127aeba95a diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/tag-a509fa67c27202a2bc9dd5e014b4af7e6063ac76 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/tag-a509fa67c27202a2bc9dd5e014b4af7e6063ac76 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/tag-a509fa67c27202a2bc9dd5e014b4af7e6063ac76 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/tag-a509fa67c27202a2bc9dd5e014b4af7e6063ac76 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/tree-7e2f26d033ee47cd0745649d1a28277c56197921 b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/tree-7e2f26d033ee47cd0745649d1a28277c56197921 similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testdata/tree-7e2f26d033ee47cd0745649d1a28277c56197921 rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testdata/tree-7e2f26d033ee47cd0745649d1a28277c56197921 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testhelper_test.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testhelper_test.go index 9ad072f100..8d7e036a05 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/testhelper_test.go @@ -8,15 +8,15 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestMain(m *testing.M) { @@ -51,19 +51,27 @@ func (e *repoExecutor) GitVersion(ctx context.Context) (git.Version, error) { return git.Version{}, nil } -func setupObjectReader(t *testing.T, ctx context.Context) (config.Cfg, ObjectReader, *gitalypb.Repository) { +func (e *repoExecutor) ObjectHash(ctx context.Context) (git.ObjectHash, error) { + return gittest.DefaultObjectHash, nil +} + +func setupObjectReader(t *testing.T, ctx context.Context) (config.Cfg, ObjectReader, *gitalypb.Repository, string) { t.Helper() - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repoExecutor := newRepoExecutor(t, cfg, repo) cache := newCache(1*time.Hour, 1000, helper.NewTimerTicker(defaultEvictionInterval)) t.Cleanup(cache.Stop) - objectReader, err := cache.ObjectReader(ctx, repoExecutor) + objectReader, cancel, err := cache.ObjectReader(ctx, repoExecutor) require.NoError(t, err) + t.Cleanup(cancel) - return cfg, objectReader, repo + return cfg, objectReader, repo, repoPath } type staticObject struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tracing.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tracing.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tracing.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tracing.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tree_entries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tree_entries.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tree_entries.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tree_entries.go index 30996d6627..7e27edb810 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile/tree_entries.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile/tree_entries.go @@ -11,8 +11,8 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type revisionPath struct{ revision, path string } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum.go index adc46fabc0..ce4fb25d07 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum.go @@ -65,7 +65,7 @@ func (c *Checksum) Bytes() []byte { // String returns the checksum as a hex encoded string. func (c *Checksum) String() string { if c.IsZero() { - return ZeroOID.String() + return ObjectHashSHA1.ZeroOID.String() } return hex.EncodeToString(c.Bytes()) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum_test.go index f750b244ba..b70650d3d2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/checksum_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/checksum_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( @@ -51,7 +53,7 @@ func TestChecksum(t *testing.T) { { desc: "zero", expectedZero: true, - expected: ZeroOID.String(), + expected: ObjectHashSHA1.ZeroOID.String(), }, { desc: "single ref", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description.go index d68560554a..1000cd9184 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_description.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description.go @@ -2,7 +2,6 @@ package git import ( "fmt" - "log" "math" "runtime" "strings" @@ -54,12 +53,12 @@ var commandDescriptions = map[string]commandDescription{ flags: scNoEndOfOptions, }, "clone": { - opts: append([]GlobalOption{ + opts: append(append([]GlobalOption{ // See "init" for why we set the template directory to the empty string. ConfigPair{Key: "init.templateDir", Value: ""}, // See "fetch" for why we disable following redirects. ConfigPair{Key: "http.followRedirects", Value: "false"}, - }, packConfiguration()...), + }, packConfiguration()...), fetchFsckConfiguration()...), }, "commit": { flags: 0, @@ -85,7 +84,17 @@ var commandDescriptions = map[string]commandDescription{ "fetch": { flags: 0, - opts: append([]GlobalOption{ + opts: append(append([]GlobalOption{ + // We've observed performance issues when fetching into big repositories + // part of an object pool. The root cause of this seems to be the + // connectivity check, which by default will also include references of any + // alternates. Given that object pools often have hundreds of thousands of + // references, this is quite expensive to compute. Below config entry will + // disable listing of alternate refs: they shouldn't even be included in the + // negotiation phase, so they aren't going to matter in the connectivity + // check either. + ConfigPair{Key: "core.alternateRefsCommand", Value: "exit 0 #"}, + // While git-fetch(1) by default won't write commit graphs, both CNG and // Omnibus set this value to true. This has caused performance issues when // doing internal fetches, and furthermore it's not encouraged to run such @@ -109,7 +118,7 @@ var commandDescriptions = map[string]commandDescription{ // of time though because we never populate submodules at all. We thus // disable recursion into submodules. ConfigPair{Key: "fetch.recurseSubmodules", Value: "no"}, - }, fsckConfiguration("fetch")...), + }, fetchFsckConfiguration()...), packConfiguration()...), }, "for-each-ref": { flags: scNoRefUpdates, @@ -119,6 +128,7 @@ var commandDescriptions = map[string]commandDescription{ }, "fsck": { flags: scNoRefUpdates, + opts: fsckConfiguration(), }, "gc": { flags: scNoRefUpdates, @@ -147,7 +157,7 @@ var commandDescriptions = map[string]commandDescription{ ConfigPair{Key: "init.defaultBranch", Value: DefaultBranch}, // When creating a new repository, then Git will by default copy over all - // files from the femplate directory into the repository. These templates + // files from the template directory into the repository. These templates // are non-mandatory files which help the user to configure parts of Git // correctly, like hook templates or an exclude file. Given that repos // should not be touched by admins anyway as they are completely owned by @@ -205,7 +215,7 @@ var commandDescriptions = map[string]commandDescription{ }, "receive-pack": { flags: 0, - opts: append(append([]GlobalOption{ + opts: append(append(append([]GlobalOption{ // In case the repository belongs to an object pool, we want to prevent // Git from including the pool's refs in the ref advertisement. We do // this by rigging core.alternateRefsCommand to produce no output. @@ -216,7 +226,7 @@ var commandDescriptions = map[string]commandDescription{ // Make git-receive-pack(1) advertise the push options // capability to clients. ConfigPair{Key: "receive.advertisePushOptions", Value: "true"}, - }, hiddenReceivePackRefPrefixes()...), fsckConfiguration("receive")...), + }, hiddenReceivePackRefPrefixes()...), receiveFsckConfiguration()...), packConfiguration()...), }, "remote": { // While git-remote(1)'s `add` subcommand does support `--end-of-options`, @@ -233,6 +243,10 @@ var commandDescriptions = map[string]commandDescription{ // Write bitmap indices when packing objects, which // speeds up packfile creation for fetches. ConfigPair{Key: "repack.writeBitmaps", Value: "true"}, + // Do not run git-update-server-info(1), which generates data structures + // required to server repositories via the dumb HTTP protocol. We don't + // serve this protocol though, so it's fine to skip it. + ConfigPair{Key: "repack.updateServerInfo", Value: "false"}, }, packConfiguration()...), }, "rev-list": { @@ -285,12 +299,12 @@ var commandDescriptions = map[string]commandDescription{ }, "upload-pack": { flags: scNoRefUpdates, - opts: append([]GlobalOption{ + opts: append(append([]GlobalOption{ ConfigPair{Key: "uploadpack.allowFilter", Value: "true"}, // Enables the capability to request individual SHA1's from the // remote repo. ConfigPair{Key: "uploadpack.allowAnySHA1InWant", Value: "true"}, - }, packConfiguration()...), + }, hiddenUploadPackRefPrefixes()...), packConfiguration()...), }, "version": { flags: scNoRefUpdates, @@ -300,34 +314,6 @@ var commandDescriptions = map[string]commandDescription{ }, } -func init() { - // This is the poor-mans static assert that all internal ref prefixes are properly hidden - // from git-receive-pack(1) such that they cannot be written to when the user pushes. - receivePackDesc, ok := commandDescriptions["receive-pack"] - if !ok { - log.Fatal("could not find command description of git-receive-pack(1)") - } - - hiddenRefs := map[string]bool{} - for _, opt := range receivePackDesc.opts { - configPair, ok := opt.(ConfigPair) - if !ok { - continue - } - if configPair.Key != "receive.hideRefs" { - continue - } - - hiddenRefs[configPair.Value] = true - } - - for _, internalRef := range InternalRefPrefixes { - if !hiddenRefs[internalRef] { - log.Fatalf("command description of receive-pack is missing hidden ref %q", internalRef) - } - } -} - // mayUpdateRef indicates if a command is known to update references. // This is useful to determine if a command requires reference hook // configuration. A non-exhaustive list of commands is consulted to determine if @@ -390,48 +376,95 @@ func validatePositionalArg(arg string) error { } func hiddenReceivePackRefPrefixes() []GlobalOption { - var cps []GlobalOption + config := make([]GlobalOption, 0, len(InternalRefPrefixes)) - for _, ns := range InternalRefPrefixes { - cps = append(cps, ConfigPair{Key: "receive.hideRefs", Value: ns}) + for refPrefix, refType := range InternalRefPrefixes { + switch refType { + case InternalReferenceTypeReadonly, InternalReferenceTypeHidden: + // We want to hide both read-only and hidden refs in git-receive-pack(1) so + // that we make neither of them writeable. + config = append(config, ConfigPair{Key: "receive.hideRefs", Value: refPrefix}) + default: + panic(fmt.Sprintf("unhandled internal reference type: %v", refType)) + } } - return cps + return config } -// fsckConfiguration generates our fsck configuration, including ignored checks. The prefix must -// either be "receive" or "fetch" and indicates whether it should apply to git-receive-pack(1) or to -// git-fetch-pack(1). -func fsckConfiguration(prefix string) []GlobalOption { - var configPairs []GlobalOption - for key, value := range map[string]string{ - // When receiving objects from an untrusted source, we want to always assert that - // all objects are valid. - "fsckObjects": "true", +func hiddenUploadPackRefPrefixes() []GlobalOption { + config := make([]GlobalOption, 0, len(InternalRefPrefixes)) + for refPrefix, refType := range InternalRefPrefixes { + switch refType { + case InternalReferenceTypeHidden: + config = append(config, ConfigPair{Key: "uploadpack.hideRefs", Value: refPrefix}) + case InternalReferenceTypeReadonly: + // git-upload-pack(1) doesn't allow writing references, and we do want to + // announce read-only references that aren't hidden. + default: + panic(fmt.Sprintf("unhandled internal reference type: %v", refType)) + } + } + + return config +} + +// fsckConfiguration generates default fsck options used by git-fsck(1). +func fsckConfiguration() []GlobalOption { + return templateFsckConfiguration("fsck") +} + +// fetchFsckConfiguration generates default fsck options used by git-fetch-pack(1). +func fetchFsckConfiguration() []GlobalOption { + return templateFsckConfiguration("fetch.fsck") +} + +// receiveFsckConfiguration generates default fsck options used by git-receive-pack(1). +func receiveFsckConfiguration() []GlobalOption { + return templateFsckConfiguration("receive.fsck") +} + +// templateFsckConfiguration generates our fsck configuration, including ignored checks. +// The prefix must either be "fsck", "receive.fsck" or "fetch.fsck" and indicates whether +// it should apply to git-fsck(1), git-receive-pack(1) or to git-fetch-pack(1). +func templateFsckConfiguration(prefix string) []GlobalOption { + configPairs := []GlobalOption{ + // When receiving objects from an untrusted source, we want to always assert that + // all objects are valid. When fetch.fsckObjects or receive.fsckObjects are not set, + // the value of transfer.fsckObjects is used instead. Since the fsck configuration + // of git-fetch-pack(1) and git-receive-pack(1) is coupled, transfer.fsckObjects can + // be used for both. + ConfigPair{Key: "transfer.fsckObjects", Value: "true"}, + } + + for _, config := range []struct { + key string + value string + }{ // In the past, there was a bug in git that caused users to create commits with // invalid timezones. As a result, some histories contain commits that do not match // the spec. As we fsck received packfiles by default, any push containing such // a commit will be rejected. As this is a mostly harmless issue, we add the // following flag to ignore this check. - "fsck.badTimezone": "ignore", + {key: "badTimezone", value: "ignore"}, // git-fsck(1) complains in case a signature does not have a space // between mail and date. The most common case where this can be hit // is in case the date is missing completely. This error is harmless // enough and we cope just fine parsing such signatures, so we can // ignore this error. - "fsck.missingSpaceBeforeDate": "ignore", + {key: "missingSpaceBeforeDate", value: "ignore"}, // Oldish Git versions used to zero-pad some filemodes, e.g. instead of a - // file mode of 40000 the tree object would have endcoded the filemode as + // file mode of 40000 the tree object would have encoded the filemode as // 04000. This doesn't cause any and Git can cope with it alright, so let's // ignore it. - "fsck.zeroPaddedFilemode": "ignore", + {key: "zeroPaddedFilemode", value: "ignore"}, } { configPairs = append(configPairs, ConfigPair{ - Key: fmt.Sprintf("%s.%s", prefix, key), - Value: value, + Key: fmt.Sprintf("%s.%s", prefix, config.key), + Value: config.value, }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description_test.go new file mode 100644 index 0000000000..f5895492b5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_description_test.go @@ -0,0 +1,116 @@ +//go:build !gitaly_test_sha256 + +package git + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCommandDescriptions_revListPositionalArgs(t *testing.T) { + revlist, ok := commandDescriptions["rev-list"] + require.True(t, ok) + require.NotNil(t, revlist.validatePositionalArgs) + + for _, tc := range []struct { + desc string + args []string + expectedErr error + }{ + { + desc: "normal reference", + args: []string{ + "master", + }, + }, + { + desc: "reference with leading dash", + args: []string{ + "-master", + }, + expectedErr: fmt.Errorf("rev-list: %w", + fmt.Errorf("positional arg \"-master\" cannot start with dash '-': %w", ErrInvalidArg), + ), + }, + { + desc: "revisions and pseudo-revisions", + args: []string{ + "master --not --all", + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + err := revlist.validatePositionalArgs(tc.args) + require.Equal(t, tc.expectedErr, err) + }) + } +} + +func TestThreadsConfigValue(t *testing.T) { + t.Parallel() + for _, tt := range []struct { + cpus int + threads string + }{ + {1, "1"}, + {2, "1"}, + {3, "1"}, + {4, "2"}, + {8, "3"}, + {9, "3"}, + {13, "3"}, + {16, "4"}, + {27, "4"}, + {32, "5"}, + } { + actualThreads := threadsConfigValue(tt.cpus) + require.Equal(t, tt.threads, actualThreads) + } +} + +func TestFsckConfiguration_prefix(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + prefix string + expected []ConfigPair + }{ + { + prefix: "fsck", + expected: []ConfigPair{ + {Key: "transfer.fsckObjects", Value: "true"}, + {Key: "fsck.badTimezone", Value: "ignore"}, + {Key: "fsck.missingSpaceBeforeDate", Value: "ignore"}, + {Key: "fsck.zeroPaddedFilemode", Value: "ignore"}, + }, + }, + { + prefix: "fetch.fsck", + expected: []ConfigPair{ + {Key: "transfer.fsckObjects", Value: "true"}, + {Key: "fetch.fsck.badTimezone", Value: "ignore"}, + {Key: "fetch.fsck.missingSpaceBeforeDate", Value: "ignore"}, + {Key: "fetch.fsck.zeroPaddedFilemode", Value: "ignore"}, + }, + }, + { + prefix: "receive.fsck", + expected: []ConfigPair{ + {Key: "transfer.fsckObjects", Value: "true"}, + {Key: "receive.fsck.badTimezone", Value: "ignore"}, + {Key: "receive.fsck.missingSpaceBeforeDate", Value: "ignore"}, + {Key: "receive.fsck.zeroPaddedFilemode", Value: "ignore"}, + }, + }, + } { + t.Run(tc.prefix, func(t *testing.T) { + opts := templateFsckConfiguration(tc.prefix) + + for _, config := range tc.expected { + require.Containsf(t, opts, config, fmt.Sprintf("missing %s", config.Key)) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory.go similarity index 60% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory.go index 3a5c58bacf..dae7199358 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory.go @@ -5,44 +5,20 @@ import ( "errors" "fmt" "os" - "os/exec" "path/filepath" "sync" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/alternates" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/alternates" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) -var globalOptions = []GlobalOption{ - // Synchronize object files to lessen the likelihood of - // repository corruption in case the server crashes. - ConfigPair{Key: "core.fsyncObjectFiles", Value: "true"}, - - // Disable automatic garbage collection as we handle scheduling - // of it ourselves. - ConfigPair{Key: "gc.auto", Value: "0"}, - - // CRLF line endings will get replaced with LF line endings - // when writing blobs to the object database. No conversion is - // done when reading blobs from the object database. This is - // required for the web editor. - ConfigPair{Key: "core.autocrlf", Value: "input"}, - - // Git allows the use of replace refs, where a given object ID can be replaced with a - // different one. The result is that Git commands would use the new object instead of the - // old one in almost all contexts. This is a security threat: an adversary may use this - // mechanism to replace malicious commits with seemingly benign ones. We thus globally - // disable this mechanism. - ConfigPair{Key: "core.useReplaceRefs", Value: "false"}, -} - // CommandFactory is designed to create and run git commands in a protected and fully managed manner. type CommandFactory interface { // New creates a new command for the repo repository. @@ -57,6 +33,11 @@ type CommandFactory interface { HooksPath(context.Context) string // GitVersion returns the Git version used by the command factory. GitVersion(context.Context) (Version, error) + + // SidecarGitConfiguration returns the Git configuration is it should be used by the Ruby + // sidecar. This is a design wart and shouldn't ever be used outside of the context of the + // sidecar. + SidecarGitConfiguration(context.Context) ([]ConfigPair, error) } type execCommandFactoryConfig struct { @@ -147,7 +128,7 @@ func NewExecCommandFactory(cfg config.Cfg, opts ...ExecCommandFactoryOption) (_ cfg: cfg, execEnvs: execEnvs, locator: config.NewLocator(cfg), - cgroupsManager: cgroups.NewManager(cfg.Cgroups), + cgroupsManager: cgroups.NewManager(cfg.Cgroups, os.Getpid()), invalidCommandsMetric: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_invalid_commands_total", @@ -165,9 +146,30 @@ func NewExecCommandFactory(cfg config.Cfg, opts ...ExecCommandFactoryOption) (_ // setupGitExecutionEnvironments assembles a Git execution environment that can be used to run Git // commands. It warns if no path was specified in the configuration. func setupGitExecutionEnvironments(cfg config.Cfg, factoryCfg execCommandFactoryConfig) ([]ExecutionEnvironment, func(), error) { + sharedEnvironment := []string{ + // Force English locale for consistency on output messages and to help us debug in + // case we get bug reports from customers whose system-locale would be different. + "LANG=en_US.UTF-8", + // Ask Git to never prompt us for any information like e.g. credentials. + "GIT_TERMINAL_PROMPT=0", + } + + // Prevent the environment from affecting git calls by ignoring the configuration files. + // This should be done always but we have to wait until 15.0 due to backwards compatibility + // concerns. + // + // See https://gitlab.com/gitlab-org/gitaly/-/issues/3617. + if cfg.Git.IgnoreGitconfig { + sharedEnvironment = append(sharedEnvironment, + "GIT_CONFIG_GLOBAL=/dev/null", + "GIT_CONFIG_SYSTEM=/dev/null", + "XDG_CONFIG_HOME=/dev/null", + ) + } + if factoryCfg.gitBinaryPath != "" { return []ExecutionEnvironment{ - {BinaryPath: factoryCfg.gitBinaryPath}, + {BinaryPath: factoryCfg.gitBinaryPath, EnvironmentVariables: sharedEnvironment}, }, func() {}, nil } @@ -186,11 +188,23 @@ func setupGitExecutionEnvironments(cfg config.Cfg, factoryCfg execCommandFactory return nil, nil, fmt.Errorf("constructing Git environment: %w", err) } + execEnv.EnvironmentVariables = append(execEnv.EnvironmentVariables, sharedEnvironment...) + execEnvs = append(execEnvs, execEnv) } if len(execEnvs) == 0 { - return nil, nil, fmt.Errorf("could not set up any Git execution environments") + execEnv, err := FallbackGitEnvironmentConstructor{}.Construct(cfg) + if err != nil { + return nil, nil, fmt.Errorf("could not set up any Git execution environments") + } + execEnv.EnvironmentVariables = append(execEnv.EnvironmentVariables, sharedEnvironment...) + + logrus.WithFields(logrus.Fields{ + "resolvedPath": execEnv.BinaryPath, + }).Warn("Git has not been properly configured, falling back to Git found on PATH") + + execEnvs = append(execEnvs, execEnv) } return execEnvs, func() { @@ -243,7 +257,7 @@ func (cf *ExecCommandFactory) GetExecutionEnvironment(ctx context.Context) Execu } // If none is enabled though, we simply use the first execution environment, which is also - // the one with highest priority. This can for example happen in case we only were able to + // the one with the highest priority. This can for example happen in case we only were able to // construct a single execution environment that is currently feature flagged. return cf.execEnvs[0] } @@ -271,11 +285,9 @@ func setupHookDirectories(cfg config.Cfg, factoryCfg execCommandFactoryConfig) ( return hookDirectories{}, nil, fmt.Errorf("creating temporary hooks directory: %w", err) } - gitalyHooksPath := filepath.Join(cfg.BinDir, "gitaly-hooks") - // And now we symlink all required hooks to the wrapper script. for _, hook := range []string{"pre-receive", "post-receive", "update", "reference-transaction"} { - if err := os.Symlink(gitalyHooksPath, filepath.Join(tempHooksPath, hook)); err != nil { + if err := os.Symlink(cfg.BinaryPath("gitaly-hooks"), filepath.Join(tempHooksPath, hook)); err != nil { return hookDirectories{}, nil, fmt.Errorf("creating symlink for %s hook: %w", hook, err) } } @@ -317,10 +329,12 @@ func (cf *ExecCommandFactory) GitVersion(ctx context.Context) (Version, error) { cf.cachedGitVersionLock.Lock() defer cf.cachedGitVersionLock.Unlock() + execEnv := cf.GetExecutionEnvironment(ctx) + // We cannot reuse the stat(3P) information from above given that it wasn't acquired under // the write-lock. As such, it may have been invalidated by a concurrent thread which has // already updated the Git version information. - stat, err = os.Stat(cf.GetExecutionEnvironment(ctx).BinaryPath) + stat, err = os.Stat(execEnv.BinaryPath) if err != nil { return Version{}, fmt.Errorf("cannot stat Git binary: %w", err) } @@ -330,9 +344,11 @@ func (cf *ExecCommandFactory) GitVersion(ctx context.Context) (Version, error) { // though: it can also happen after `GitVersion()` was called, so it doesn't really help to // retry version detection here. Instead, we just live with this raciness -- the next call // to `GitVersion()` would detect the version being out-of-date anyway and thus correct it. - cmd, err := cf.NewWithoutRepo(ctx, SubCmd{ - Name: "version", - }) + // + // Furthermore, note that we're not using `newCommand()` but instead hand-craft the command. + // This is required to avoid a cyclic dependency when we need to check the version in + // `newCommand()` itself. + cmd, err := command.New(ctx, []string{execEnv.BinaryPath, "version"}, command.WithEnvironment(execEnv.EnvironmentVariables)) if err != nil { return Version{}, fmt.Errorf("spawning version command: %w", err) } @@ -342,6 +358,10 @@ func (cf *ExecCommandFactory) GitVersion(ctx context.Context) (Version, error) { return Version{}, err } + if err := cmd.Wait(); err != nil { + return Version{}, fmt.Errorf("waiting for version: %w", err) + } + cf.cachedGitVersionByBinary[gitBinary] = cachedGitVersion{ version: gitVersion, stat: stat, @@ -379,23 +399,23 @@ func (cf *ExecCommandFactory) newCommand(ctx context.Context, repo repository.Gi execEnv := cf.GetExecutionEnvironment(ctx) - env = append(env, command.GitEnv...) env = append(env, execEnv.EnvironmentVariables...) - execCommand := exec.Command(execEnv.BinaryPath, args...) - execCommand.Dir = dir - - command, err := command.New(ctx, execCommand, config.stdin, config.stdout, config.stderr, env...) + cmdGitVersion, err := cf.GitVersion(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("getting Git version: %w", err) } - command.SetMetricsSubCmd(sc.Subcommand()) - - if featureflag.RunCommandsInCGroup.IsEnabled(ctx) { - if err := cf.cgroupsManager.AddCommand(command); err != nil { - return nil, err - } + command, err := command.New(ctx, append([]string{execEnv.BinaryPath}, args...), append( + config.commandOpts, + command.WithDir(dir), + command.WithEnvironment(env), + command.WithCommandName("git", sc.Subcommand()), + command.WithCgroup(cf.cgroupsManager, repo), + command.WithCommandGitVersion(cmdGitVersion.String()), + )...) + if err != nil { + return nil, err } return command, nil @@ -436,20 +456,11 @@ func (cf *ExecCommandFactory) combineArgs(ctx context.Context, gitConfig []confi return nil, fmt.Errorf("invalid sub command name %q: %w", sc.Subcommand(), ErrInvalidArg) } - // As global options may cancel out each other, we have a clearly defined order in which - // globals get applied. The order is similar to how git handles configuration options from - // most general to most specific. This allows callsites to override options which would - // otherwise be set up automatically. The exception to this is configuration specified by - // the admin, which always overrides all other items. The following order of precedence - // applies: - // - // 1. Globals which get set up by default for all git commands. - // 2. Globals which get set up by default for a given git command. - // 3. Globals passed via command options, e.g. as set up by - // `WithReftxHook()`. - // 4. Configuration as provided by the admin in Gitaly's config.toml. - var combinedGlobals []GlobalOption - combinedGlobals = append(combinedGlobals, globalOptions...) + combinedGlobals, err := cf.globalConfiguration(ctx) + if err != nil { + return nil, fmt.Errorf("getting global Git configuration: %w", err) + } + combinedGlobals = append(combinedGlobals, commandDescription.opts...) combinedGlobals = append(combinedGlobals, cc.globals...) for _, configPair := range gitConfig { @@ -474,3 +485,137 @@ func (cf *ExecCommandFactory) combineArgs(ctx context.Context, gitConfig []confi return append(args, scArgs...), nil } + +// globalConfiguration returns the global Git configuration that should be applied to every Git +// command. +func (cf *ExecCommandFactory) globalConfiguration(ctx context.Context) ([]GlobalOption, error) { + // It's fine to ask for the Git version whenever we spawn a command: the value is cached + // nowadays, so this would typically only boil down to a single stat(3P) call to determine + // whether the cache is stale or not. + gitVersion, err := cf.GitVersion(ctx) + if err != nil { + return nil, fmt.Errorf("determining Git version: %w", err) + } + + // As global options may cancel out each other, we have a clearly defined order in which + // globals get applied. The order is similar to how git handles configuration options from + // most general to most specific. This allows callsites to override options which would + // otherwise be set up automatically. The exception to this is configuration specified by + // the admin, which always overrides all other items. The following order of precedence + // applies: + // + // 1. Globals which get set up by default for all git commands. + // 2. Globals which get set up by default for a given git command. + // 3. Globals passed via command options, e.g. as set up by + // `WithReftxHook()`. + // 4. Configuration as provided by the admin in Gitaly's config.toml. + config := []GlobalOption{ + // Disable automatic garbage collection as we handle scheduling + // of it ourselves. + ConfigPair{Key: "gc.auto", Value: "0"}, + + // CRLF line endings will get replaced with LF line endings + // when writing blobs to the object database. No conversion is + // done when reading blobs from the object database. This is + // required for the web editor. + ConfigPair{Key: "core.autocrlf", Value: "input"}, + + // Git allows the use of replace refs, where a given object ID can be replaced with a + // different one. The result is that Git commands would use the new object instead of the + // old one in almost all contexts. This is a security threat: an adversary may use this + // mechanism to replace malicious commits with seemingly benign ones. We thus globally + // disable this mechanism. + ConfigPair{Key: "core.useReplaceRefs", Value: "false"}, + + // Commit-graphs are used as an optimization to speed up reading commits and to be + // able to perform certain commit-related queries faster. One property that these + // graphs are storing is the generation number of a commit, where there are two + // different types of generation numbers: + // + // - Topological level: a commit with no parents has a level of 1. A commit with + // at least one parent has a level one more than the largest topological level + // of its parents. + // + // - Corrected committer date: a commit with no parents has a corrected commit + // date equal to its committer date. A commit with at least one parent has a + // corrected committer date equal to the maximum between either its own + // committer date or the largest corrected committer date across its parents + // plus 1. + // + // By default, newer Git versions store both generation numbers for commits, where + // the corrected committer date allows for some more optimizations. But due to a bug + // in Git v2.35.0 and earlier, the corrected committer date wasn't ever read. + // + // This bug was fixed in Git v2.36.0, together with a few other bugs in this area. + // But unfortunately, a new bug was introduced: when upgrading a commit-graph + // written by Git v2.35.0 or newer with Git v2.36.0 and later with `--changed-paths` + // enabled then the resulting commit-graph may be corrupt. + // + // Let's disable reading and writing corrected committer dates for now until the fix + // to this issue is upstream. + ConfigPair{Key: "commitGraph.generationVersion", Value: "1"}, + } + + // Git v2.36.0 introduced new fine-grained configuration for what data should be fsynced and + // how that should happen. + if gitVersion.HasGranularFsyncConfig() { + config = append( + config, + // This is the same as below, but in addition we're also syncing packed-refs + // and loose refs to disk. This fixes a long-standing issue we've had where + // hard reboots of a server could end up corrupting loose references. + ConfigPair{Key: "core.fsync", Value: "objects,derived-metadata,reference"}, + ConfigPair{Key: "core.fsyncMethod", Value: "fsync"}, + ) + } else { + // Synchronize object files to lessen the likelihood of + // repository corruption in case the server crashes. + config = append( + config, ConfigPair{Key: "core.fsyncObjectFiles", Value: "true"}, + ) + } + + return config, nil +} + +// SidecarGitConfiguration assembles the Git configuration as required by the Ruby sidecar. This +// includes global configuration, command-specific configuration for all commands executed in the +// sidecar, as well as configuration that was configured by the administrator in Gitaly's config. +// +// This function should not be used for anything else but the Ruby sidecar. +func (cf *ExecCommandFactory) SidecarGitConfiguration(ctx context.Context) ([]ConfigPair, error) { + // Collect the global configuration that is specific to the current Git version... + options, err := cf.globalConfiguration(ctx) + if err != nil { + return nil, fmt.Errorf("getting global config: %w", err) + } + + // ... as well as all configuration that exists for specific Git subcommands. The sidecar + // only executes git-update-ref(1) nowadays, and this set of commands is not expected to + // grow anymore. So while really intimate with how the sidecar does this, it is good enough + // until we finally remove it. + options = append(options, commandDescriptions["update-ref"].opts...) + + // Convert the `GlobalOption`s into `ConfigPair`s. + configPairs := make([]ConfigPair, 0, len(options)+len(cf.cfg.Git.Config)) + for _, option := range options { + configPair, ok := option.(ConfigPair) + if !ok { + continue + } + + configPairs = append(configPairs, configPair) + } + + // Lastly, we also apply the Git configuration as set by the administrator in Gitaly's + // config. Note that we do not check for conflicts here: administrators should be able to + // override whatever is configured by Gitaly. + for _, configEntry := range cf.cfg.Git.Config { + configPairs = append(configPairs, ConfigPair{ + Key: configEntry.Key, + Value: configEntry.Value, + }) + } + + return configPairs, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_cgroup_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_cgroup_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_cgroup_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_cgroup_test.go index 922e3d12ab..93ce9724fe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_cgroup_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_cgroup_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( @@ -8,11 +10,12 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) type mockCgroupsManager struct { @@ -23,9 +26,9 @@ func (m *mockCgroupsManager) Setup() error { return nil } -func (m *mockCgroupsManager) AddCommand(c *command.Command) error { +func (m *mockCgroupsManager) AddCommand(c *command.Command, repo repository.GitRepo) (string, error) { m.commands = append(m.commands, c) - return nil + return "", nil } func (m *mockCgroupsManager) Cleanup() error { @@ -39,15 +42,20 @@ func TestNewCommandAddsToCgroup(t *testing.T) { root := testhelper.TempDir(t) cfg := config.Cfg{ + BinDir: filepath.Join(root, "bin.d"), SocketPath: "/path/to/socket", + Git: config.Git{ + IgnoreGitconfig: true, + }, Cgroups: cgroups.Config{ - Count: 1, + Repositories: cgroups.Repositories{ + Count: 1, + }, }, Storages: []config.Storage{{ Name: "storage-1", Path: root, }}, - BinDir: filepath.Join(root, "bin.d"), } require.NoError(t, os.MkdirAll(cfg.BinDir, 0o755)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_test.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_test.go index 438e23adc0..f208635357 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_factory_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_factory_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git_test import ( @@ -10,15 +12,17 @@ import ( "os" "os/exec" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestGitCommandProxy(t *testing.T) { @@ -31,9 +35,8 @@ func TestGitCommandProxy(t *testing.T) { })) defer ts.Close() - oldHTTPProxy := os.Getenv("http_proxy") - defer require.NoError(t, os.Setenv("http_proxy", oldHTTPProxy)) - require.NoError(t, os.Setenv("http_proxy", ts.URL)) + t.Setenv("http_proxy", ts.URL) + ctx := testhelper.Context(t) dir := testhelper.TempDir(t) @@ -145,8 +148,8 @@ func TestExecCommandFactory_NewWithDir(t *testing.T) { } func TestCommandFactory_ExecutionEnvironment(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "") - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", "") + testhelper.Unsetenv(t, "GITALY_TESTING_GIT_BINARY") + testhelper.Unsetenv(t, "GITALY_TESTING_BUNDLED_GIT_PATH") ctx := testhelper.Context(t) @@ -163,24 +166,62 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) { require.Equal(t, expectedExecEnv.EnvironmentVariables, actualExecEnv.EnvironmentVariables) } - t.Run("set in config", func(t *testing.T) { + t.Run("set in config without ignored gitconfig", func(t *testing.T) { assertExecEnv(t, config.Cfg{ - Git: config.Git{BinPath: "/path/to/myGit"}, + Git: config.Git{ + BinPath: "/path/to/myGit", + IgnoreGitconfig: false, + }, }, git.ExecutionEnvironment{ BinaryPath: "/path/to/myGit", + EnvironmentVariables: []string{ + "LANG=en_US.UTF-8", + "GIT_TERMINAL_PROMPT=0", + }, + }) + }) + + t.Run("set in config", func(t *testing.T) { + assertExecEnv(t, config.Cfg{ + Git: config.Git{ + BinPath: "/path/to/myGit", + IgnoreGitconfig: true, + }, + }, git.ExecutionEnvironment{ + BinaryPath: "/path/to/myGit", + EnvironmentVariables: []string{ + "LANG=en_US.UTF-8", + "GIT_TERMINAL_PROMPT=0", + "GIT_CONFIG_GLOBAL=/dev/null", + "GIT_CONFIG_SYSTEM=/dev/null", + "XDG_CONFIG_HOME=/dev/null", + }, }) }) t.Run("set using GITALY_TESTING_GIT_BINARY", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "/path/to/env_git") + t.Setenv("GITALY_TESTING_GIT_BINARY", "/path/to/env_git") - assertExecEnv(t, config.Cfg{Git: config.Git{}}, git.ExecutionEnvironment{ + assertExecEnv(t, config.Cfg{ + Git: config.Git{ + IgnoreGitconfig: true, + }, + }, git.ExecutionEnvironment{ BinaryPath: "/path/to/env_git", + EnvironmentVariables: []string{ + "NO_SET_GIT_TEMPLATE_DIR=YesPlease", + "LANG=en_US.UTF-8", + "GIT_TERMINAL_PROMPT=0", + "GIT_CONFIG_GLOBAL=/dev/null", + "GIT_CONFIG_SYSTEM=/dev/null", + "XDG_CONFIG_HOME=/dev/null", + }, }) }) t.Run("set using GITALY_TESTING_BUNDLED_GIT_PATH", func(t *testing.T) { - suffix := "-v2.35.1.gl1" + ctx := featureflag.ContextWithFeatureFlag(ctx, featureflag.GitV2371Gl1, true) + suffix := "-v2.37.1.gl1" bundledGitDir := testhelper.TempDir(t) @@ -196,7 +237,7 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) { bundledGitExecutable := filepath.Join(bundledGitDir, "gitaly-git"+suffix) bundledGitRemoteExecutable := filepath.Join(bundledGitDir, "gitaly-git-remote-http"+suffix) - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitDir) + t.Setenv("GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitDir) t.Run("missing bin_dir", func(t *testing.T) { _, _, err := git.NewExecCommandFactory(config.Cfg{Git: config.Git{}}, git.WithSkipHooks()) @@ -266,13 +307,24 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) { resolvedPath, err := exec.LookPath("git") require.NoError(t, err) - assertExecEnv(t, config.Cfg{}, git.ExecutionEnvironment{ + assertExecEnv(t, config.Cfg{ + Git: config.Git{ + IgnoreGitconfig: true, + }, + }, git.ExecutionEnvironment{ BinaryPath: resolvedPath, + EnvironmentVariables: []string{ + "LANG=en_US.UTF-8", + "GIT_TERMINAL_PROMPT=0", + "GIT_CONFIG_GLOBAL=/dev/null", + "GIT_CONFIG_SYSTEM=/dev/null", + "XDG_CONFIG_HOME=/dev/null", + }, }) }) t.Run("doesn't exist in the system", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "PATH", "") + testhelper.Unsetenv(t, "PATH") _, _, err := git.NewExecCommandFactory(config.Cfg{}, git.WithSkipHooks()) require.EqualError(t, err, "setting up Git execution environment: could not set up any Git execution environments") @@ -298,7 +350,7 @@ func TestExecCommandFactoryHooksPath(t *testing.T) { for _, hook := range []string{"update", "pre-receive", "post-receive", "reference-transaction"} { target, err := os.Readlink(filepath.Join(hooksPath, hook)) require.NoError(t, err) - require.Equal(t, filepath.Join(cfg.BinDir, "gitaly-hooks"), target) + require.Equal(t, cfg.BinaryPath("gitaly-hooks"), target) } }) @@ -359,7 +411,9 @@ func TestExecCommandFactory_GitVersion(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { gitCmdFactory := gittest.NewInterceptingCommandFactory( - ctx, t, testcfg.Build(t), generateVersionScript(tc.versionString), git.WithSkipHooks(), + ctx, t, testcfg.Build(t), generateVersionScript(tc.versionString), + gittest.WithRealCommandFactoryOptions(git.WithSkipHooks()), + gittest.WithInterceptedVersion(), ) actualVersion, err := gitCmdFactory.GitVersion(ctx) @@ -374,7 +428,9 @@ func TestExecCommandFactory_GitVersion(t *testing.T) { t.Run("caching", func(t *testing.T) { gitCmdFactory := gittest.NewInterceptingCommandFactory( - ctx, t, testcfg.Build(t), generateVersionScript("git version 1.2.3"), git.WithSkipHooks(), + ctx, t, testcfg.Build(t), generateVersionScript("git version 1.2.3"), + gittest.WithRealCommandFactoryOptions(git.WithSkipHooks()), + gittest.WithInterceptedVersion(), ) gitPath := gitCmdFactory.GetExecutionEnvironment(ctx).BinaryPath @@ -413,3 +469,195 @@ func TestExecCommandFactory_GitVersion(t *testing.T) { require.Equal(t, "2.34.1", version.String()) }) } + +func TestExecCommandFactory_config(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + // Create a repository and remove its gitconfig to bring us into a known state where there + // is no repo-level configuration that interferes with our test. + repo, repoDir := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + require.NoError(t, os.Remove(filepath.Join(repoDir, "config"))) + + commonEnv := []string{ + "gc.auto=0", + "core.autocrlf=input", + "core.usereplacerefs=false", + "commitgraph.generationversion=1", + } + + for _, tc := range []struct { + desc string + version string + expectedEnv []string + }{ + { + desc: "without support for core.fsync", + version: "2.35.0", + expectedEnv: append(commonEnv, "core.fsyncobjectfiles=true"), + }, + { + desc: "with support for core.fsync", + version: "2.36.0", + expectedEnv: append(commonEnv, "core.fsync=objects,derived-metadata,reference", "core.fsyncmethod=fsync"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + factory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf( + `#!/usr/bin/env bash + if test "$1" = "version" + then + echo "git version %s" + exit 0 + fi + exec %q "$@" + `, tc.version, execEnv.BinaryPath) + }, gittest.WithInterceptedVersion()) + + var stdout bytes.Buffer + cmd, err := factory.New(ctx, repo, git.SubCmd{ + Name: "config", + Flags: []git.Option{ + git.Flag{Name: "--list"}, + }, + }, git.WithStdout(&stdout)) + require.NoError(t, err) + + require.NoError(t, cmd.Wait()) + require.Equal(t, tc.expectedEnv, strings.Split(strings.TrimSpace(stdout.String()), "\n")) + }) + } +} + +func TestExecCommandFactory_SidecarGitConfiguration(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + cfg.Git.Config = []config.GitConfig{ + {Key: "custom.key", Value: "injected"}, + } + + commonHead := []git.ConfigPair{ + {Key: "gc.auto", Value: "0"}, + {Key: "core.autocrlf", Value: "input"}, + {Key: "core.useReplaceRefs", Value: "false"}, + {Key: "commitGraph.generationVersion", Value: "1"}, + } + + commonTail := []git.ConfigPair{ + {Key: "custom.key", Value: "injected"}, + } + + for _, tc := range []struct { + desc string + version string + expectedConfig []git.ConfigPair + }{ + { + desc: "without support for core.fsync", + version: "2.35.0", + expectedConfig: append(append(commonHead, + git.ConfigPair{Key: "core.fsyncObjectFiles", Value: "true"}, + ), commonTail...), + }, + { + desc: "with support for core.fsync", + version: "2.36.0", + expectedConfig: append(append(commonHead, + git.ConfigPair{Key: "core.fsync", Value: "objects,derived-metadata,reference"}, + git.ConfigPair{Key: "core.fsyncMethod", Value: "fsync"}, + ), commonTail...), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + factory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(git.ExecutionEnvironment) string { + return fmt.Sprintf( + `#!/usr/bin/env bash + echo "git version %s" + `, tc.version) + }, gittest.WithInterceptedVersion()) + + configPairs, err := factory.SidecarGitConfiguration(ctx) + require.NoError(t, err) + require.Equal(t, tc.expectedConfig, configPairs) + }) + } +} + +// TestFsckConfiguration tests the hardcoded configuration of the +// git fsck subcommand generated through the command factory. +func TestFsckConfiguration(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + desc string + data string + }{ + { + desc: "with valid commit", + data: strings.Join([]string{ + "tree " + gittest.DefaultObjectHash.EmptyTreeOID.String(), + "author " + gittest.DefaultCommitterSignature, + "committer " + gittest.DefaultCommitterSignature, + "", + "message", + }, "\n"), + }, + { + desc: "with missing space", + data: strings.Join([]string{ + "tree " + gittest.DefaultObjectHash.EmptyTreeOID.String(), + "author Scrooge McDuck 1659043074 -0500", + "committer Scrooge McDuck 1659975573 -0500", + "", + "message", + }, "\n"), + }, + { + desc: "with bad timezone", + data: strings.Join([]string{ + "tree " + gittest.DefaultObjectHash.EmptyTreeOID.String(), + "author Scrooge McDuck 1659043074 -0500BAD", + "committer Scrooge McDuck 1659975573 -0500BAD", + "", + "message", + }, "\n"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, + gittest.CreateRepositoryConfig{SkipCreationViaService: true}, + ) + + // Create commit object. + commitOut := gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: bytes.NewBufferString(tc.data)}, + "-C", repoPath, "hash-object", "-w", "-t", "commit", "--stdin", "--literally", + ) + _, err := gittest.DefaultObjectHash.FromHex(text.ChompBytes(commitOut)) + require.NoError(t, err) + + gitCmdFactory, cleanup, err := git.NewExecCommandFactory(cfg) + require.NoError(t, err) + defer cleanup() + + // Create fsck command with configured ignore rules options. + cmd, err := gitCmdFactory.New(ctx, repoProto, + git.SubCmd{Name: "fsck"}, + ) + require.NoError(t, err) + + // Execute git fsck command. + err = cmd.Wait() + require.NoError(t, err) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options.go index 6b9f8dbb72..d72c8f120d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options.go @@ -5,16 +5,16 @@ import ( "fmt" "io" "os" - "path/filepath" "regexp" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/x509" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/x509" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" @@ -82,6 +82,21 @@ func (cp ConfigPair) GlobalArgs() ([]string, error) { return []string{"-c", fmt.Sprintf("%s=%s", cp.Key, cp.Value)}, nil } +// ConfigPairsToGitEnvironment converts the given config pairs into a set of environment variables +// that can be injected into a Git executable. +func ConfigPairsToGitEnvironment(configPairs []ConfigPair) []string { + env := make([]string, 0, len(configPairs)*2+1) + + for i, configPair := range configPairs { + env = append(env, + fmt.Sprintf("GIT_CONFIG_KEY_%d=%s", i, configPair.Key), + fmt.Sprintf("GIT_CONFIG_VALUE_%d=%s", i, configPair.Value), + ) + } + + return append(env, fmt.Sprintf("GIT_CONFIG_COUNT=%d", len(configPairs))) +} + // Flag is a single token optional command line argument that enables or // disables functionality (e.g. "-L") type Flag struct { @@ -153,9 +168,7 @@ func ConvertConfigOptions(options []string) ([]ConfigPair, error) { type cmdCfg struct { env []string globals []GlobalOption - stdin io.Reader - stdout io.Writer - stderr io.Writer + commandOpts []command.Option hooksConfigured bool } @@ -166,7 +179,15 @@ type CmdOpt func(context.Context, config.Cfg, CommandFactory, *cmdCfg) error // command suitable for `Write()`ing to. func WithStdin(r io.Reader) CmdOpt { return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { - c.stdin = r + c.commandOpts = append(c.commandOpts, command.WithStdin(r)) + return nil + } +} + +// WithSetupStdin sets up the command so that it can be `Write()`en to. +func WithSetupStdin() CmdOpt { + return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { + c.commandOpts = append(c.commandOpts, command.WithSetupStdin()) return nil } } @@ -174,7 +195,7 @@ func WithStdin(r io.Reader) CmdOpt { // WithStdout sets the command's stdout. func WithStdout(w io.Writer) CmdOpt { return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { - c.stdout = w + c.commandOpts = append(c.commandOpts, command.WithStdout(w)) return nil } } @@ -182,7 +203,7 @@ func WithStdout(w io.Writer) CmdOpt { // WithStderr sets the command's stderr. func WithStderr(w io.Writer) CmdOpt { return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { - c.stderr = w + c.commandOpts = append(c.commandOpts, command.WithStderr(w)) return nil } } @@ -210,17 +231,7 @@ func WithConfig(configPairs ...ConfigPair) CmdOpt { // via the process's command line. func WithConfigEnv(configPairs ...ConfigPair) CmdOpt { return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { - env := make([]string, 0, len(configPairs)*2+1) - - for i, configPair := range configPairs { - env = append(env, - fmt.Sprintf("GIT_CONFIG_KEY_%d=%s", i, configPair.Key), - fmt.Sprintf("GIT_CONFIG_VALUE_%d=%s", i, configPair.Value), - ) - } - env = append(env, fmt.Sprintf("GIT_CONFIG_COUNT=%d", len(configPairs))) - - c.env = append(c.env, env...) + c.env = append(c.env, ConfigPairsToGitEnvironment(configPairs)...) return nil } } @@ -273,14 +284,17 @@ func withInternalFetch(req repoScopedRequest, withSidechannel bool) func(ctx con return helper.ErrInvalidArgumentf("empty Gitaly address") } - featureFlagPairs := featureflag.AllFlags(ctx) + var flagsWithValue []string + for flag, value := range featureflag.FromContext(ctx) { + flagsWithValue = append(flagsWithValue, flag.FormatWithValue(value)) + } c.env = append(c.env, fmt.Sprintf("GITALY_PAYLOAD=%s", payload), - fmt.Sprintf("GIT_SSH_COMMAND=%s %s", filepath.Join(cfg.BinDir, "gitaly-ssh"), "upload-pack"), + fmt.Sprintf("GIT_SSH_COMMAND=%s %s", cfg.BinaryPath("gitaly-ssh"), "upload-pack"), fmt.Sprintf("GITALY_ADDRESS=%s", storageInfo.Address), fmt.Sprintf("GITALY_TOKEN=%s", storageInfo.Token), - fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(featureFlagPairs, ",")), + fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(flagsWithValue, ",")), fmt.Sprintf("CORRELATION_ID=%s", correlation.ExtractFromContextOrGenerate(ctx)), // please see https://github.com/git/git/commit/0da0e49ba12225684b75e86a4c9344ad121652cb for mote details "GIT_SSH_VARIANT=simple", @@ -297,3 +311,12 @@ func withInternalFetch(req repoScopedRequest, withSidechannel bool) func(ctx con return nil } } + +// WithFinalizer sets up the finalizer to be run when the command is being wrapped up. It will be +// called after `Wait()` has returned. +func WithFinalizer(finalizer func(*command.Command)) CmdOpt { + return func(_ context.Context, _ config.Cfg, _ CommandFactory, c *cmdCfg) error { + c.commandOpts = append(c.commandOpts, command.WithFinalizer(finalizer)) + return nil + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options_test.go index 9a8dfa1d88..30410909d5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/command_options_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/command_options_test.go @@ -1,17 +1,18 @@ +//go:build !gitaly_test_sha256 + package git import ( "bytes" "encoding/base64" "fmt" - "path/filepath" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/encoding/protojson" @@ -203,7 +204,12 @@ func TestGlobalOption(t *testing.T) { } func TestWithConfig(t *testing.T) { - cfg := config.Cfg{BinDir: testhelper.TempDir(t)} + cfg := config.Cfg{ + BinDir: testhelper.TempDir(t), + Git: config.Git{ + IgnoreGitconfig: true, + }, + } ctx := testhelper.Context(t) @@ -274,11 +280,16 @@ func TestWithConfig(t *testing.T) { } func TestExecCommandFactoryGitalyConfigOverrides(t *testing.T) { - cfg := config.Cfg{BinDir: testhelper.TempDir(t)} - - cfg.Git.Config = []config.GitConfig{ - {Key: "foo.bar", Value: "from-gitaly-config"}, + cfg := config.Cfg{ + BinDir: testhelper.TempDir(t), + Git: config.Git{ + Config: []config.GitConfig{ + {Key: "foo.bar", Value: "from-gitaly-config"}, + }, + IgnoreGitconfig: true, + }, } + ctx := testhelper.Context(t) gitCmdFactory := newCommandFactory(t, cfg, WithSkipHooks()) @@ -299,7 +310,12 @@ func TestExecCommandFactoryGitalyConfigOverrides(t *testing.T) { } func TestWithConfigEnv(t *testing.T) { - cfg := config.Cfg{BinDir: testhelper.TempDir(t)} + cfg := config.Cfg{ + BinDir: testhelper.TempDir(t), + Git: config.Git{ + IgnoreGitconfig: true, + }, + } ctx := testhelper.Context(t) @@ -451,7 +467,7 @@ func TestWithInternalFetch(t *testing.T) { require.NoError(t, option(ctx, cfg, gitCmdFactory, &commandCfg)) require.Subset(t, commandCfg.env, []string{ - fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", filepath.Join(cfg.BinDir, "gitaly-ssh")), + fmt.Sprintf("GIT_SSH_COMMAND=%s upload-pack", cfg.BinaryPath("gitaly-ssh")), fmt.Sprintf("GITALY_PAYLOAD=%s", tc.expectedPayload), "CORRELATION_ID=correlation-id-1", "GIT_SSH_VARIANT=simple", @@ -465,3 +481,50 @@ func TestWithInternalFetch(t *testing.T) { }) } } + +func TestConfigPairsToEnvironment(t *testing.T) { + for _, tc := range []struct { + desc string + configPairs []ConfigPair + expectedEnv []string + }{ + { + desc: "no pairs", + expectedEnv: []string{ + "GIT_CONFIG_COUNT=0", + }, + }, + { + desc: "single pair", + configPairs: []ConfigPair{ + {Key: "foo.bar", Value: "baz"}, + }, + expectedEnv: []string{ + "GIT_CONFIG_KEY_0=foo.bar", + "GIT_CONFIG_VALUE_0=baz", + "GIT_CONFIG_COUNT=1", + }, + }, + { + desc: "multiple pairs", + configPairs: []ConfigPair{ + {Key: "duplicate.key", Value: "first"}, + {Key: "foo.bar", Value: "baz"}, + {Key: "duplicate.key", Value: "second"}, + }, + expectedEnv: []string{ + "GIT_CONFIG_KEY_0=duplicate.key", + "GIT_CONFIG_VALUE_0=first", + "GIT_CONFIG_KEY_1=foo.bar", + "GIT_CONFIG_VALUE_1=baz", + "GIT_CONFIG_KEY_2=duplicate.key", + "GIT_CONFIG_VALUE_2=second", + "GIT_CONFIG_COUNT=3", + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.expectedEnv, ConfigPairsToGitEnvironment(tc.configPairs)) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict/parser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict/parser.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict/parser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict/parser.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict/parser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict/parser_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict/parser_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict/parser_test.go index 52c308320a..5d3ece314a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict/parser_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict/parser_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package conflict import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/decoder.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/decoder.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/decoder.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/decoder.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/decoder_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/decoder_test.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/decoder_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/decoder_test.go index e2ee0850cc..34073658e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/decoder_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/decoder_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git_test import ( @@ -6,19 +8,21 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestShowRefDecoder(t *testing.T) { cfg := testcfg.Build(t) ctx := testhelper.Context(t) - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - RelativePath: "repo.git", + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: "repo.git", }) repo := localrepo.NewTestRepo(t, cfg, repoProto) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/dirs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/dirs.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/dirs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/dirs.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/dirs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/dirs_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/dirs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/dirs_test.go index 1486814f6f..4734cae51f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/dirs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/dirs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( @@ -6,7 +8,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestObjectDirs(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment.go index f5aa36b532..9de1a0b943 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment.go @@ -9,8 +9,8 @@ import ( "path/filepath" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "golang.org/x/sys/unix" ) @@ -25,11 +25,16 @@ var ( // that will be preferred when executing Git commands. Later environments may be used in // case `IsEnabled()` returns `false` though. ExecutionEnvironmentConstructors = []ExecutionEnvironmentConstructor{ + BundledGitEnvironmentConstructor{ + Suffix: "-v2.37.1.gl1", + FeatureFlags: []featureflag.FeatureFlag{ + featureflag.GitV2371Gl1, + }, + }, BundledGitEnvironmentConstructor{ Suffix: "-v2.35.1.gl1", }, DistributedGitEnvironmentConstructor{}, - FallbackGitEnvironmentConstructor{}, } ) @@ -82,8 +87,17 @@ type DistributedGitEnvironmentConstructor struct{} // `GITALY_TESTING_GIT_BINARY` environment variable is set. func (c DistributedGitEnvironmentConstructor) Construct(cfg config.Cfg) (ExecutionEnvironment, error) { binaryPath := cfg.Git.BinPath + var environmentVariables []string if override := os.Getenv("GITALY_TESTING_GIT_BINARY"); binaryPath == "" && override != "" { binaryPath = override + environmentVariables = []string{ + // When using Git's bin-wrappers as testing binary then the wrapper will + // automatically set up the location of the Git templates and export the + // environment variable. This would override our own defaults though and + // thus leads to diverging behaviour. To fix this we simply ask the bin + // wrappers not to do this. + "NO_SET_GIT_TEMPLATE_DIR=YesPlease", + } } if binaryPath == "" { @@ -91,7 +105,8 @@ func (c DistributedGitEnvironmentConstructor) Construct(cfg config.Cfg) (Executi } return ExecutionEnvironment{ - BinaryPath: binaryPath, + BinaryPath: binaryPath, + EnvironmentVariables: environmentVariables, }, nil } @@ -241,10 +256,6 @@ func (c FallbackGitEnvironmentConstructor) Construct(config.Cfg) (ExecutionEnvir return ExecutionEnvironment{}, fmt.Errorf("resolving git executable: %w", err) } - logrus.WithFields(logrus.Fields{ - "resolvedPath": resolvedPath, - }).Warn("git path not configured. Using default path resolution") - return ExecutionEnvironment{ BinaryPath: resolvedPath, // We always pretend that this environment is disabled. This has the effect that diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment_test.go index e3775c1131..5340110a55 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/execution_environment_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/execution_environment_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git_test import ( @@ -8,15 +10,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestDistributedGitEnvironmentConstructor(t *testing.T) { constructor := git.DistributedGitEnvironmentConstructor{} - testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "") + testhelper.Unsetenv(t, "GITALY_TESTING_GIT_BINARY") t.Run("empty configuration fails", func(t *testing.T) { _, err := constructor.Construct(config.Cfg{}) @@ -37,18 +39,20 @@ func TestDistributedGitEnvironmentConstructor(t *testing.T) { }) t.Run("empty configuration with environment override", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "/foo/bar") + t.Setenv("GITALY_TESTING_GIT_BINARY", "/foo/bar") execEnv, err := constructor.Construct(config.Cfg{}) require.NoError(t, err) defer execEnv.Cleanup() require.Equal(t, "/foo/bar", execEnv.BinaryPath) - require.Equal(t, []string(nil), execEnv.EnvironmentVariables) + require.Equal(t, []string{ + "NO_SET_GIT_TEMPLATE_DIR=YesPlease", + }, execEnv.EnvironmentVariables) }) t.Run("configuration overrides environment variable", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "envvar") + t.Setenv("GITALY_TESTING_GIT_BINARY", "envvar") execEnv, err := constructor.Construct(config.Cfg{ Git: config.Git{ @@ -64,7 +68,7 @@ func TestDistributedGitEnvironmentConstructor(t *testing.T) { } func TestBundledGitEnvironmentConstructor(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", "") + testhelper.Unsetenv(t, "GITALY_TESTING_BUNDLED_GIT_PATH") constructor := git.BundledGitEnvironmentConstructor{} @@ -147,13 +151,13 @@ func TestBundledGitEnvironmentConstructor(t *testing.T) { }) t.Run("bundled Git path without binary directory fails", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", "/does/not/exist") + t.Setenv("GITALY_TESTING_BUNDLED_GIT_PATH", "/does/not/exist") _, err := constructor.Construct(config.Cfg{}) require.Equal(t, errors.New("cannot use bundled binaries without bin path being set"), err) }) t.Run("nonexistent bundled Git path via environment fails", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", "/does/not/exist") + t.Setenv("GITALY_TESTING_BUNDLED_GIT_PATH", "/does/not/exist") _, err := constructor.Construct(config.Cfg{ BinDir: testhelper.TempDir(t), }) @@ -163,7 +167,7 @@ func TestBundledGitEnvironmentConstructor(t *testing.T) { t.Run("incomplete bundled Git environment fails", func(t *testing.T) { bundledGitPath := seedDirWithExecutables(t, "gitaly-git", "gitaly-git-remote-http") - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitPath) + t.Setenv("GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitPath) _, err := constructor.Construct(config.Cfg{ BinDir: testhelper.TempDir(t), @@ -174,7 +178,7 @@ func TestBundledGitEnvironmentConstructor(t *testing.T) { t.Run("complete bundled Git environment populates binary directory", func(t *testing.T) { bundledGitPath := seedDirWithExecutables(t, "gitaly-git", "gitaly-git-remote-http", "gitaly-git-http-backend") - testhelper.ModifyEnvironment(t, "GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitPath) + t.Setenv("GITALY_TESTING_BUNDLED_GIT_PATH", bundledGitPath) execEnv, err := constructor.Construct(config.Cfg{ BinDir: testhelper.TempDir(t), @@ -230,7 +234,7 @@ func TestFallbackGitEnvironmentConstructor(t *testing.T) { constructor := git.FallbackGitEnvironmentConstructor{} t.Run("failing lookup of executable causes failure", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "PATH", "/does/not/exist") + t.Setenv("PATH", "/does/not/exist") _, err := constructor.Construct(config.Cfg{}) require.Equal(t, fmt.Errorf("%w: no git executable found in PATH", git.ErrNotConfigured), err) @@ -241,7 +245,7 @@ func TestFallbackGitEnvironmentConstructor(t *testing.T) { gitPath := filepath.Join(tempDir, "git") require.NoError(t, os.WriteFile(gitPath, nil, 0o755)) - testhelper.ModifyEnvironment(t, "PATH", "/does/not/exist:"+tempDir) + t.Setenv("PATH", "/does/not/exist:"+tempDir) execEnv, err := constructor.Construct(config.Cfg{}) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/fetch_scanner.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/fetch_scanner.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/fetch_scanner.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/fetch_scanner.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/fetch_scanner_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/fetch_scanner_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/fetch_scanner_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/fetch_scanner_test.go index d49feda934..c05d297f04 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/fetch_scanner_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/fetch_scanner_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/hashfile.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/hashfile.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/hashfile.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/hashfile.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/hashfile_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/hashfile_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/hashfile_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/hashfile_test.go index a18dea7f84..d17d73cb61 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/hashfile_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/hashfile_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package gitio import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/trailer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/trailer.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/trailer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/trailer.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/trailer_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/trailer_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/trailer_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/trailer_test.go index a8731e3311..7ce88a2510 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio/trailer_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio/trailer_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package gitio import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info.go index b756e08f3f..07e29525b6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info.go @@ -7,10 +7,11 @@ import ( "errors" "fmt" "io" + "sync/atomic" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" ) // CatfileInfoResult is a result for the CatfileInfo pipeline step. @@ -26,6 +27,7 @@ type CatfileInfoResult struct { type catfileInfoConfig struct { skipResult func(*catfile.ObjectInfo) bool + diskUsage bool } // CatfileInfoOption is an option for the CatfileInfo and CatfileInfoAllObjects pipeline steps. @@ -40,6 +42,14 @@ func WithSkipCatfileInfoResult(skipResult func(*catfile.ObjectInfo) bool) Catfil } } +// WithDiskUsageSize will cause the size of the object to be returned to be the +// size it takes up on disk. This value will override the existing size field. +func WithDiskUsageSize() CatfileInfoOption { + return func(cfg *catfileInfoConfig) { + cfg.diskUsage = true + } +} + type catfileInfoRequest struct { objectID git.ObjectID objectName []byte @@ -61,67 +71,72 @@ func CatfileInfo( opt(&cfg) } - queue, cleanup, err := objectInfoReader.InfoQueue(ctx) + queue, queueCleanup, err := objectInfoReader.InfoQueue(ctx) if err != nil { return nil, err } - defer cleanup() + var queueRefcount int32 = 2 requestChan := make(chan catfileInfoRequest, 32) go func() { - defer close(requestChan) + defer func() { + close(requestChan) + if atomic.AddInt32(&queueRefcount, -1) == 0 { + queueCleanup() + } + }() var i int64 for it.Next() { if err := queue.RequestRevision(it.ObjectID().Revision()); err != nil { - select { - case requestChan <- catfileInfoRequest{err: err}: - case <-ctx.Done(): - return - } + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: err}) + return } - select { - case requestChan <- catfileInfoRequest{ + if isDone := sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{ objectID: it.ObjectID(), objectName: it.ObjectName(), - }: - case <-ctx.Done(): + }); isDone { + // If the context got cancelled, then we need to flush out all + // outstanding requests so that the downstream consumer is + // unblocked. + if err := queue.Flush(); err != nil { + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: err}) + return + } + + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: ctx.Err()}) return } i++ if i%int64(cap(requestChan)) == 0 { if err := queue.Flush(); err != nil { - select { - case requestChan <- catfileInfoRequest{err: err}: - case <-ctx.Done(): - return - } + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: err}) + return } } } if err := it.Err(); err != nil { - select { - case requestChan <- catfileInfoRequest{err: err}: - case <-ctx.Done(): - return - } + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: err}) + return } if err := queue.Flush(); err != nil { - select { - case requestChan <- catfileInfoRequest{err: err}: - case <-ctx.Done(): - return - } + sendCatfileInfoRequest(ctx, requestChan, catfileInfoRequest{err: err}) + return } }() resultChan := make(chan CatfileInfoResult) go func() { - defer close(resultChan) + defer func() { + close(resultChan) + if atomic.AddInt32(&queueRefcount, -1) == 0 { + queueCleanup() + } + }() // It's fine to iterate over the request channel without paying attention to // context cancellation because the request channel itself would be closed if the @@ -154,7 +169,8 @@ func CatfileInfo( }() return &catfileInfoIterator{ - ch: resultChan, + ctx: ctx, + ch: resultChan, }, nil } @@ -178,12 +194,27 @@ func CatfileInfoAllObjects( go func() { defer close(resultChan) + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + sendCatfileInfoResult(ctx, resultChan, CatfileInfoResult{ + err: fmt.Errorf("detecting object hash: %w", err), + }) + return + } + + batchCheckOption := git.Flag{Name: "--batch-check"} + + if cfg.diskUsage { + batchCheckOption.Name = batchCheckOption.Name + + fmt.Sprintf("=%%(objectname) %%(objecttype) %%(objectsize:disk)") + } + var stderr bytes.Buffer cmd, err := repo.Exec(ctx, git.SubCmd{ Name: "cat-file", Flags: []git.Option{ + batchCheckOption, git.Flag{Name: "--batch-all-objects"}, - git.Flag{Name: "--batch-check"}, git.Flag{Name: "--buffer"}, git.Flag{Name: "--unordered"}, }, @@ -197,7 +228,7 @@ func CatfileInfoAllObjects( reader := bufio.NewReader(cmd) for { - objectInfo, err := catfile.ParseObjectInfo(reader) + objectInfo, err := catfile.ParseObjectInfo(objectHash, reader) if err != nil { if errors.Is(err, io.EOF) { break @@ -229,7 +260,8 @@ func CatfileInfoAllObjects( }() return &catfileInfoIterator{ - ch: resultChan, + ctx: ctx, + ch: resultChan, } } @@ -252,3 +284,19 @@ func sendCatfileInfoResult(ctx context.Context, ch chan<- CatfileInfoResult, res return true } } + +func sendCatfileInfoRequest(ctx context.Context, ch chan<- catfileInfoRequest, request catfileInfoRequest) bool { + // Please refer to `sendCatfileInfoResult()` for why we treat the context specially. + select { + case <-ctx.Done(): + return true + default: + } + + select { + case ch <- request: + return false + case <-ctx.Done(): + return true + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_iterator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_iterator.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_iterator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_iterator.go index 35c7826990..9147d910cf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_info_iterator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_iterator.go @@ -1,6 +1,10 @@ package gitpipe -import "gitlab.com/gitlab-org/gitaly/v14/internal/git" +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" +) // CatfileInfoIterator is an iterator returned by the Revlist function. type CatfileInfoIterator interface { @@ -10,7 +14,7 @@ type CatfileInfoIterator interface { } // NewCatfileInfoIterator returns a new CatfileInfoIterator for the given items. -func NewCatfileInfoIterator(items []CatfileInfoResult) CatfileInfoIterator { +func NewCatfileInfoIterator(ctx context.Context, items []CatfileInfoResult) CatfileInfoIterator { itemChan := make(chan CatfileInfoResult, len(items)) for _, item := range items { itemChan <- item @@ -18,11 +22,13 @@ func NewCatfileInfoIterator(items []CatfileInfoResult) CatfileInfoIterator { close(itemChan) return &catfileInfoIterator{ - ch: itemChan, + ctx: ctx, + ch: itemChan, } } type catfileInfoIterator struct { + ctx context.Context ch <-chan CatfileInfoResult result CatfileInfoResult } @@ -32,13 +38,31 @@ func (it *catfileInfoIterator) Next() bool { return false } - var ok bool - it.result, ok = <-it.ch - if !ok || it.result.err != nil { + // Prioritize context cancellation errors so that we don't try to fetch results anymore when + // the context is done. + select { + case <-it.ctx.Done(): + it.result = CatfileInfoResult{err: it.ctx.Err()} return false + default: } - return true + select { + case <-it.ctx.Done(): + it.result = CatfileInfoResult{err: it.ctx.Err()} + return false + case result, ok := <-it.ch: + if !ok { + return false + } + + it.result = result + if result.err != nil { + return false + } + + return true + } } func (it *catfileInfoIterator) Err() error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_test.go new file mode 100644 index 0000000000..317c93ba33 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_info_test.go @@ -0,0 +1,396 @@ +package gitpipe + +import ( + "bytes" + "context" + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "google.golang.org/grpc/metadata" +) + +func TestCatfileInfo(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133)) + blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127)) + blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127)) + blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129)) + + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("contents")) + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "branch-test.txt", Mode: "100644", OID: blobID}, + }) + + for _, tc := range []struct { + desc string + revlistInputs []RevisionResult + opts []CatfileInfoOption + expectedResults []CatfileInfoResult + expectedErr error + }{ + { + desc: "single blob", + revlistInputs: []RevisionResult{ + {OID: blobA}, + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + }, + }, + { + desc: "multiple blobs", + revlistInputs: []RevisionResult{ + {OID: blobA}, + {OID: blobB}, + {OID: blobC}, + {OID: blobD}, + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}}, + }, + }, + { + desc: "object name", + revlistInputs: []RevisionResult{ + {OID: treeID}, + {OID: blobID, ObjectName: []byte("branch-test.txt")}, + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 8}, ObjectName: []byte("branch-test.txt")}, + }, + }, + { + desc: "invalid object ID", + revlistInputs: []RevisionResult{ + {OID: "invalidobjectid"}, + }, + expectedErr: errors.New("retrieving object info for \"invalidobjectid\": object not found"), + }, + { + desc: "mixed valid and invalid revision", + revlistInputs: []RevisionResult{ + {OID: blobA}, + {OID: "invalidobjectid"}, + {OID: blobB}, + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + }, + expectedErr: errors.New("retrieving object info for \"invalidobjectid\": object not found"), + }, + { + desc: "skip everything", + revlistInputs: []RevisionResult{ + {OID: blobA}, + {OID: blobB}, + }, + opts: []CatfileInfoOption{ + WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return true }), + }, + }, + { + desc: "skip one", + revlistInputs: []RevisionResult{ + {OID: blobA}, + {OID: blobB}, + }, + opts: []CatfileInfoOption{ + WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool { + return objectInfo.Oid == blobA + }), + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}, + }, + }, + { + desc: "skip nothing", + revlistInputs: []RevisionResult{ + {OID: blobA}, + {OID: blobB}, + }, + opts: []CatfileInfoOption{ + WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return false }), + }, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, tc.revlistInputs), tc.opts...) + require.NoError(t, err) + + var results []CatfileInfoResult + for it.Next() { + results = append(results, it.Result()) + } + + // We're converting the error here to a plain un-nested error such + // that we don't have to replicate the complete error's structure. + err = it.Err() + if err != nil { + err = errors.New(err.Error()) + } + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResults, results) + }) + } + + t.Run("context cancellation", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectInfoReader, objectInfoReaderCancel, err := catfileCache.ObjectInfoReader(ctx, repo) + require.NoError(t, err) + defer objectInfoReaderCancel() + + it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, []RevisionResult{ + {OID: blobA}, + {OID: blobA}, + })) + require.NoError(t, err) + + require.True(t, it.Next()) + require.NoError(t, it.Err()) + require.Equal(t, CatfileInfoResult{ + ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}, + }, it.Result()) + + cancel() + + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + require.Equal(t, CatfileInfoResult{ + err: context.Canceled, + }, it.Result()) + }) + + t.Run("context cancellation with cached process", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + ctx = testhelper.MergeIncomingMetadata(ctx, metadata.Pairs( + catfile.SessionIDField, "1", + )) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectInfoReader, objectInfoReaderCancel, err := catfileCache.ObjectInfoReader(ctx, repo) + require.NoError(t, err) + defer objectInfoReaderCancel() + + inputIter, inputCh, nextCh := newChanObjectIterator() + + it, err := CatfileInfo(ctx, objectInfoReader, inputIter) + require.NoError(t, err) + + // We request a single object from the catfile process. Because the request queue is + // not flushed after every object this means that the request is currently + // outstanding. + <-nextCh + inputCh <- blobA + + // Wait for the pipeline to request the next object. + <-nextCh + + // We now cancel the context with the outstanding request. In the past, this used to + // block the downstream consumer of the object data. This is because of two reasons: + // + // - When the process is being cached then cancellation of the context doesn't cause + // the process to get killed. So consequentially, the process would sit around + // waiting for input. + // - We didn't flush the queue when the context was cancelled, so the buffered input + // never arrived at the process. + cancel() + + // Now we queue another request that should cause the pipeline to fail. + inputCh <- blobA + + // Verify whether we can receive any more objects via the iterator. This should + // fail because the context got cancelled, but in any case it shouldn't block. Note + // that we're forced to reach into the channel directly: `Next()` would return + // `false` immediately because the context is cancelled. + _, ok := <-it.(*catfileInfoIterator).ch + require.False(t, ok) + + // Sanity-check whether the iterator is in the expected state. + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + }) + + t.Run("spawning two pipes fails", func(t *testing.T) { + ctx := testhelper.Context(t) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + input := []RevisionResult{ + {OID: blobA}, + } + + it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, input)) + require.NoError(t, err) + + // Reusing the queue is not allowed, so we should get an error here. + _, err = CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, input)) + require.Equal(t, fmt.Errorf("object info queue already in use"), err) + + // We now consume all the input of the iterator. + require.True(t, it.Next()) + require.False(t, it.Next()) + + // Which means that the queue should now be unused, so we can again use it. + _, err = CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, input)) + require.NoError(t, err) + }) +} + +func TestCatfileInfoAllObjects(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + ctx := testhelper.Context(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + blob1 := gittest.WriteBlob(t, cfg, repoPath, []byte("foobar")) + blob2 := gittest.WriteBlob(t, cfg, repoPath, []byte("barfoo")) + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "foobar", Mode: "100644", OID: blob1}, + }) + commit := gittest.WriteCommit(t, cfg, repoPath) + + actualObjects := []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blob1, Type: "blob", Size: 6}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blob2, Type: "blob", Size: 6}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(34, 46)}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: hashDependentObjectSize(177, 201)}}, + } + + t.Run("successful", func(t *testing.T) { + it := CatfileInfoAllObjects(ctx, repo) + + var results []CatfileInfoResult + for it.Next() { + results = append(results, it.Result()) + } + require.NoError(t, it.Err()) + + require.ElementsMatch(t, actualObjects, results) + }) + + t.Run("context cancellation", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + it := CatfileInfoAllObjects(ctx, repo) + + require.True(t, it.Next()) + require.NoError(t, it.Err()) + require.Contains(t, actualObjects, it.Result()) + + cancel() + + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + require.Equal(t, CatfileInfoResult{ + err: context.Canceled, + }, it.Result()) + }) +} + +func TestCatfileInfo_WithDiskUsageSize(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + ctx := testhelper.Context(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + tree1 := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "foobar", + Mode: "100644", + OID: gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 100)), + }, + }) + initialCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTree(tree1)) + + tree2 := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "foobar", + Mode: "100644", + // take advantage of compression + OID: gittest.WriteBlob(t, cfg, repoPath, append(bytes.Repeat([]byte("a"), 100), + '\n', + 'b', + )), + }, + }) + gittest.WriteCommit( + t, + cfg, + repoPath, + gittest.WithTree(tree2), + gittest.WithParents(initialCommitID), + gittest.WithBranch("master"), + ) + + gittest.Exec(t, cfg, "-C", repoPath, "gc") + + itWithoutDiskSize := CatfileInfoAllObjects(ctx, repo) + itWithDiskSize := CatfileInfoAllObjects(ctx, repo, WithDiskUsageSize()) + + var totalWithoutDiskSize, totalWithDiskSize int64 + for itWithoutDiskSize.Next() { + totalWithoutDiskSize += itWithoutDiskSize.Result().ObjectSize() + } + require.NoError(t, itWithoutDiskSize.Err()) + + for itWithDiskSize.Next() { + totalWithDiskSize += itWithDiskSize.Result().ObjectSize() + } + require.NoError(t, itWithDiskSize.Err()) + + require.Less(t, totalWithDiskSize, totalWithoutDiskSize) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object.go index 49e33b859c..5fe031579d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object.go @@ -6,9 +6,10 @@ import ( "fmt" "io" "sync" + "sync/atomic" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" ) // CatfileObjectResult is a result for the CatfileObject pipeline step. @@ -38,64 +39,87 @@ func CatfileObject( objectReader catfile.ObjectReader, it ObjectIterator, ) (CatfileObjectIterator, error) { - queue, cleanup, err := objectReader.ObjectQueue(ctx) + queue, queueCleanup, err := objectReader.ObjectQueue(ctx) if err != nil { return nil, err } - defer cleanup() + var queueRefcount int32 = 2 requestChan := make(chan catfileObjectRequest, 32) go func() { - defer close(requestChan) + defer func() { + close(requestChan) + if atomic.AddInt32(&queueRefcount, -1) == 0 { + queueCleanup() + } + }() + + sendRequest := func(request catfileObjectRequest) bool { + // Please refer to `sendResult()` for why we treat the context specially. + select { + case <-ctx.Done(): + return true + default: + } + + select { + case requestChan <- request: + return false + case <-ctx.Done(): + return true + } + } var i int64 for it.Next() { if err := queue.RequestRevision(it.ObjectID().Revision()); err != nil { - select { - case requestChan <- catfileObjectRequest{err: err}: - case <-ctx.Done(): - return - } + sendRequest(catfileObjectRequest{err: err}) + return } - select { - case requestChan <- catfileObjectRequest{objectName: it.ObjectName()}: - case <-ctx.Done(): + if isDone := sendRequest(catfileObjectRequest{ + objectName: it.ObjectName(), + }); isDone { + // If the context got cancelled, then we need to flush out all + // outstanding requests so that the downstream consumer is + // unblocked. + if err := queue.Flush(); err != nil { + sendRequest(catfileObjectRequest{err: err}) + return + } + + sendRequest(catfileObjectRequest{err: ctx.Err()}) return } i++ if i%int64(cap(requestChan)) == 0 { if err := queue.Flush(); err != nil { - select { - case requestChan <- catfileObjectRequest{err: err}: - case <-ctx.Done(): - return - } + sendRequest(catfileObjectRequest{err: err}) + return } } } if err := it.Err(); err != nil { - select { - case requestChan <- catfileObjectRequest{err: err}: - case <-ctx.Done(): - return - } + sendRequest(catfileObjectRequest{err: err}) + return } if err := queue.Flush(); err != nil { - select { - case requestChan <- catfileObjectRequest{err: err}: - case <-ctx.Done(): - return - } + sendRequest(catfileObjectRequest{err: err}) + return } }() resultChan := make(chan CatfileObjectResult) go func() { - defer close(resultChan) + defer func() { + close(resultChan) + if atomic.AddInt32(&queueRefcount, -1) == 0 { + queueCleanup() + } + }() sendResult := func(result CatfileObjectResult) bool { // In case the context has been cancelled, we have a race between observing @@ -164,7 +188,8 @@ func CatfileObject( }() return &catfileObjectIterator{ - ch: resultChan, + ctx: ctx, + ch: resultChan, }, nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_iterator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_iterator.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_iterator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_iterator.go index c457088e04..5d2ca9fb0e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/catfile_object_iterator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_iterator.go @@ -1,6 +1,10 @@ package gitpipe -import "gitlab.com/gitlab-org/gitaly/v14/internal/git" +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" +) // CatfileObjectIterator is an iterator returned by the Revlist function. type CatfileObjectIterator interface { @@ -10,7 +14,7 @@ type CatfileObjectIterator interface { } // NewCatfileObjectIterator returns a new CatfileObjectIterator for the given items. -func NewCatfileObjectIterator(items []CatfileObjectResult) CatfileObjectIterator { +func NewCatfileObjectIterator(ctx context.Context, items []CatfileObjectResult) CatfileObjectIterator { itemChan := make(chan CatfileObjectResult, len(items)) for _, item := range items { itemChan <- item @@ -18,11 +22,13 @@ func NewCatfileObjectIterator(items []CatfileObjectResult) CatfileObjectIterator close(itemChan) return &catfileObjectIterator{ - ch: itemChan, + ctx: ctx, + ch: itemChan, } } type catfileObjectIterator struct { + ctx context.Context ch <-chan CatfileObjectResult result CatfileObjectResult } @@ -32,13 +38,31 @@ func (it *catfileObjectIterator) Next() bool { return false } - var ok bool - it.result, ok = <-it.ch - if !ok || it.result.err != nil { + // Prioritize context cancellation errors so that we don't try to fetch results anymore when + // the context is done. + select { + case <-it.ctx.Done(): + it.result = CatfileObjectResult{err: it.ctx.Err()} return false + default: } - return true + select { + case <-it.ctx.Done(): + it.result = CatfileObjectResult{err: it.ctx.Err()} + return false + case result, ok := <-it.ch: + if !ok { + return false + } + + it.result = result + if result.err != nil { + return false + } + + return true + } } func (it *catfileObjectIterator) Err() error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_test.go new file mode 100644 index 0000000000..fe4f5d3198 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/catfile_object_test.go @@ -0,0 +1,251 @@ +package gitpipe + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "google.golang.org/grpc/metadata" +) + +func TestCatfileObject(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133)) + blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127)) + blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127)) + blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129)) + + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("contents")) + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "branch-test.txt", Mode: "100644", OID: blobID}, + }) + + for _, tc := range []struct { + desc string + catfileInfoInputs []CatfileInfoResult + expectedResults []CatfileObjectResult + expectedErr error + }{ + { + desc: "single blob", + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + }, + expectedResults: []CatfileObjectResult{ + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}}, + }, + }, + { + desc: "multiple blobs", + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}}, + }, + expectedResults: []CatfileObjectResult{ + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}}}, + }, + }, + { + desc: "revlist result with object names", + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, + }, + expectedResults: []CatfileObjectResult{ + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 8}}, ObjectName: []byte("branch-test.txt")}, + }, + }, + { + desc: "invalid object ID", + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "invalidobjectid", Type: "blob"}}, + }, + expectedErr: errors.New("requesting object: object not found"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + it, err := CatfileObject(ctx, objectReader, NewCatfileInfoIterator(ctx, tc.catfileInfoInputs)) + require.NoError(t, err) + + var results []CatfileObjectResult + for it.Next() { + result := it.Result() + + objectData, err := io.ReadAll(result) + require.NoError(t, err) + require.Len(t, objectData, int(result.ObjectSize())) + + // We only really want to compare the publicly visible fields + // containing info about the object itself, and not the object's + // private state. We thus need to reconstruct the objects here. + results = append(results, CatfileObjectResult{ + Object: &catfile.Object{ + ObjectInfo: catfile.ObjectInfo{ + Oid: result.ObjectID(), + Type: result.ObjectType(), + Size: result.ObjectSize(), + }, + }, + ObjectName: result.ObjectName, + }) + } + + // We're converting the error here to a plain un-nested error such + // that we don't have to replicate the complete error's structure. + err = it.Err() + if err != nil { + err = errors.New(err.Error()) + } + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResults, results) + }) + } + + t.Run("context cancellation", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectReader, objectReaderCancel, err := catfileCache.ObjectReader(ctx, repo) + require.NoError(t, err) + defer objectReaderCancel() + + it, err := CatfileObject(ctx, objectReader, NewCatfileInfoIterator(ctx, []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}, + })) + require.NoError(t, err) + + require.True(t, it.Next()) + require.NoError(t, it.Err()) + require.Equal(t, blobA, it.Result().ObjectID()) + + _, err = io.Copy(io.Discard, it.Result()) + require.NoError(t, err) + + cancel() + + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + require.Equal(t, CatfileObjectResult{ + err: context.Canceled, + }, it.Result()) + }) + + t.Run("context cancellation with cached process", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + ctx = testhelper.MergeIncomingMetadata(ctx, metadata.Pairs( + catfile.SessionIDField, "1", + )) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectReader, objectReaderCancel, err := catfileCache.ObjectReader(ctx, repo) + require.NoError(t, err) + defer objectReaderCancel() + + inputIter, inputCh, nextCh := newChanObjectIterator() + + it, err := CatfileObject(ctx, objectReader, inputIter) + require.NoError(t, err) + + // We request a single object from the catfile process. Because the request queue is + // not flushed after every object this means that the request is currently + // outstanding. + <-nextCh + inputCh <- blobA + + // Wait for the pipeline to request the next object. + <-nextCh + + // We now cancel the context with the outstanding request. In the past, this used to + // block the downstream consumer of the object data. This is because of two reasons: + // + // - When the process is being cached then cancellation of the context doesn't cause + // the process to get killed. So consequentially, the process would sit around + // waiting for input. + // - We didn't flush the queue when the context was cancelled, so the buffered input + // never arrived at the process. + cancel() + + // Now we queue another request that should cause the pipeline to fail. + inputCh <- blobA + + // Verify whether we can receive any more objects via the iterator. This should + // fail because the context got cancelled, but in any case it shouldn't block. Note + // that we're forced to reach into the channel directly: `Next()` would return + // `false` immediately because the context is cancelled. + _, ok := <-it.(*catfileObjectIterator).ch + require.False(t, ok) + + // Sanity-check whether the iterator is in the expected state. + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + }) + + t.Run("spawning two pipes fails", func(t *testing.T) { + ctx := testhelper.Context(t) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + input := []RevisionResult{ + {OID: blobA}, + } + + it, err := CatfileObject(ctx, objectReader, NewRevisionIterator(ctx, input)) + require.NoError(t, err) + + // Reusing the queue is not allowed, so we should get an error here. + _, err = CatfileObject(ctx, objectReader, NewRevisionIterator(ctx, input)) + require.Equal(t, fmt.Errorf("object queue already in use"), err) + + // We now consume all the input of the iterator. + require.True(t, it.Next()) + _, err = io.Copy(io.Discard, it.Result()) + require.NoError(t, err) + require.False(t, it.Next()) + + // Which means that the queue should now be unused, so we can again use it. + _, err = CatfileObject(ctx, objectReader, NewRevisionIterator(ctx, input)) + require.NoError(t, err) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree.go new file mode 100644 index 0000000000..cf81a1ba3d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree.go @@ -0,0 +1,147 @@ +package gitpipe + +import ( + "bufio" + "bytes" + "context" + "fmt" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" +) + +// diffTreeConfig is configuration for the DiffTree pipeline step. +type diffTreeConfig struct { + recursive bool + ignoreSubmodules bool + skipResult func(*RevisionResult) bool +} + +// DiffTreeOption is an option for the DiffTree pipeline step. +type DiffTreeOption func(cfg *diffTreeConfig) + +// DiffTreeWithRecursive will make DiffTree recurse into subtrees. +func DiffTreeWithRecursive() DiffTreeOption { + return func(cfg *diffTreeConfig) { + cfg.recursive = true + } +} + +// DiffTreeWithIgnoreSubmodules causes git-diff-tree(1) to exclude submodule changes. +func DiffTreeWithIgnoreSubmodules() DiffTreeOption { + return func(cfg *diffTreeConfig) { + cfg.ignoreSubmodules = true + } +} + +// DiffTreeWithSkip will execute the given function for each RevisionResult processed by the +// pipeline. If the callback returns `true`, then the object will be skipped and not passed down +// the pipeline. +func DiffTreeWithSkip(skipResult func(*RevisionResult) bool) DiffTreeOption { + return func(cfg *diffTreeConfig) { + cfg.skipResult = skipResult + } +} + +// DiffTree runs git-diff-tree(1) between the two given revisions. The returned +// channel will contain the new object IDs listed by this command. For deleted +// files this would be the all-zeroes object ID. Cancelling the context will cause the +// pipeline to be cancelled, too. By default, it will not recurse into subtrees. +func DiffTree( + ctx context.Context, + repo *localrepo.Repo, + leftRevision, rightRevision string, + options ...DiffTreeOption, +) RevisionIterator { + var cfg diffTreeConfig + for _, option := range options { + option(&cfg) + } + + resultChan := make(chan RevisionResult) + go func() { + defer close(resultChan) + + flags := []git.Option{} + + if cfg.recursive { + flags = append(flags, git.Flag{Name: "-r"}) + } + if cfg.ignoreSubmodules { + flags = append(flags, git.Flag{Name: "--ignore-submodules"}) + } + + var stderr strings.Builder + cmd, err := repo.Exec(ctx, + git.SubCmd{ + Name: "diff-tree", + Flags: flags, + Args: []string{leftRevision, rightRevision}, + }, + git.WithStderr(&stderr), + ) + if err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("executing diff-tree: %w", err), + }) + return + } + + scanner := bufio.NewScanner(cmd) + for scanner.Scan() { + // We need to copy the line here because we'll hand it over to the caller + // asynchronously, and the next call to `Scan()` will overwrite the buffer. + line := make([]byte, len(scanner.Bytes())) + copy(line, scanner.Bytes()) + + attrsAndFile := bytes.SplitN(line, []byte{'\t'}, 2) + if len(attrsAndFile) != 2 { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("splitting diff-tree attributes and file"), + }) + return + } + + attrs := bytes.SplitN(attrsAndFile[0], []byte{' '}, 5) + if len(attrs) != 5 { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("splitting diff-tree attributes"), + }) + return + } + + result := RevisionResult{ + OID: git.ObjectID(attrs[3]), + ObjectName: attrsAndFile[1], + } + + if cfg.skipResult != nil && cfg.skipResult(&result) { + continue + } + + if isDone := sendRevisionResult(ctx, resultChan, result); isDone { + return + } + } + + if err := scanner.Err(); err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("scanning diff-tree output: %w", err), + }) + return + } + + if err := cmd.Wait(); err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("diff-tree pipeline command: %w, stderr: %q", err, stderr.String()), + }) + return + } + }() + + return &revisionIterator{ + ctx: ctx, + ch: resultChan, + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree_test.go new file mode 100644 index 0000000000..ca29d509a2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/diff_tree_test.go @@ -0,0 +1,234 @@ +package gitpipe + +import ( + "bytes" + "errors" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestDiffTree(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + for _, tc := range []struct { + desc string + setup func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) + options []DiffTreeOption + expectedErr error + }{ + { + desc: "single file", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "unchanged", Mode: "100644", Content: "unchanged"}, + {Path: "changed", Mode: "100644", Content: "a"}, + }) + + changedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "unchanged", Mode: "100644", Content: "unchanged"}, + {Path: "changed", Mode: "100644", OID: changedBlob}, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedBlob, ObjectName: []byte("changed")}, + } + }, + }, + { + desc: "single file in subtree without recursive", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "unchanged", + Mode: "100644", + Content: "unchanged", + }, + { + Path: "subtree", + Mode: "040000", + OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "changed", Mode: "100644", Content: "a"}, + }), + }, + }) + + changedSubtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "changed", Mode: "100644", Content: "b"}, + }) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "unchanged", + Mode: "100644", + Content: "unchanged", + }, + { + Path: "subtree", + Mode: "040000", + OID: changedSubtree, + }, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedSubtree, ObjectName: []byte("subtree")}, + } + }, + }, + { + desc: "single file in subtree with recursive", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "unchanged", + Mode: "100644", + Content: "unchanged", + }, + { + Path: "subtree", + Mode: "040000", + OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "changed", Mode: "100644", Content: "a"}, + }), + }, + }) + + changedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "unchanged", + Mode: "100644", + Content: "unchanged", + }, + { + Path: "subtree", + Mode: "040000", + OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "changed", Mode: "100644", OID: changedBlob}, + }), + }, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedBlob, ObjectName: []byte("subtree/changed")}, + } + }, + options: []DiffTreeOption{ + DiffTreeWithRecursive(), + }, + }, + { + desc: "with submodules", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + submodule := gittest.WriteCommit(t, cfg, repoPath) + + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitmodules", Mode: "100644", Content: "a"}, + }) + + changedGitmodules := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitmodules", Mode: "100644", OID: changedGitmodules}, + {Path: "submodule", Mode: "160000", OID: submodule}, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedGitmodules, ObjectName: []byte(".gitmodules")}, + {OID: submodule, ObjectName: []byte("submodule")}, + } + }, + }, + { + desc: "without submodules", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + submodule := gittest.WriteCommit(t, cfg, repoPath) + + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitmodules", Mode: "100644", Content: "a"}, + }) + + changedGitmodules := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitmodules", Mode: "100644", OID: changedGitmodules}, + {Path: "submodule", Mode: "160000", OID: submodule}, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedGitmodules, ObjectName: []byte(".gitmodules")}, + } + }, + options: []DiffTreeOption{ + DiffTreeWithIgnoreSubmodules(), + }, + }, + { + desc: "with skip function", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "a", Mode: "100644", Content: "1"}, + {Path: "b", Mode: "100644", Content: "2"}, + }) + + changedBlobA := gittest.WriteBlob(t, cfg, repoPath, []byte("x")) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "a", Mode: "100644", OID: changedBlobA}, + {Path: "b", Mode: "100644", Content: "y"}, + }) + + return treeA.Revision(), treeB.Revision(), []RevisionResult{ + {OID: changedBlobA, ObjectName: []byte("a")}, + } + }, + options: []DiffTreeOption{ + DiffTreeWithSkip(func(r *RevisionResult) bool { + return bytes.Equal(r.ObjectName, []byte("b")) + }), + }, + }, + { + desc: "invalid revision", + setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) { + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + return "refs/heads/main", "refs/heads/does-not-exist", nil + }, + expectedErr: errors.New("diff-tree pipeline command: exit status 128, stderr: " + + "\"fatal: ambiguous argument 'refs/heads/does-not-exist': unknown revision or path not in the working tree.\\n" + + "Use '--' to separate paths from revisions, like this:\\n" + + "'git [...] -- [...]'\\n\""), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + leftRevision, rightRevision, expectedResults := tc.setup(t, repoPath) + + it := DiffTree(ctx, repo, leftRevision.String(), rightRevision.String(), tc.options...) + + var results []RevisionResult + for it.Next() { + results = append(results, it.Result()) + } + + // We're converting the error here to a plain un-nested error such that we + // don't have to replicate the complete error's structure. + err := it.Err() + if err != nil { + err = errors.New(err.Error()) + } + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, expectedResults, results) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree.go new file mode 100644 index 0000000000..3c21c1eb0b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree.go @@ -0,0 +1,134 @@ +package gitpipe + +import ( + "context" + "errors" + "fmt" + "io" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" +) + +// lsTreeConfig is configuration for the LsTree pipeline step. +type lsTreeConfig struct { + recursive bool + typeFilter func(*lstree.Entry) bool + skipResult func(*RevisionResult) bool +} + +// LsTreeOption is an option for the LsTree pipeline step. +type LsTreeOption func(cfg *lsTreeConfig) + +// LsTreeWithRecursive will make LsTree recursive into subtrees. +func LsTreeWithRecursive() LsTreeOption { + return func(cfg *lsTreeConfig) { + cfg.recursive = true + } +} + +// LsTreeWithBlobFilter configures LsTree to only pass through blob objects. +func LsTreeWithBlobFilter() LsTreeOption { + return func(cfg *lsTreeConfig) { + cfg.typeFilter = func(e *lstree.Entry) bool { return e.Type == lstree.Blob } + } +} + +// LsTree runs git-ls-tree(1) for the given revisions. The returned channel will +// contain all object IDs listed by this command. This might include: +// - Blobs +// - Trees, unless you're calling it with LsTreeWithRecursive() +// - Submodules, referring to the commit of the submodule +func LsTree( + ctx context.Context, + repo *localrepo.Repo, + revision string, + options ...LsTreeOption, +) RevisionIterator { + var cfg lsTreeConfig + for _, option := range options { + option(&cfg) + } + + resultChan := make(chan RevisionResult) + go func() { + defer close(resultChan) + + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("detecting object hash: %w", err), + }) + return + } + + flags := []git.Option{ + git.Flag{Name: "-z"}, + } + + if cfg.recursive { + flags = append(flags, git.Flag{Name: "-r"}) + } + + var stderr strings.Builder + cmd, err := repo.Exec(ctx, + git.SubCmd{ + Name: "ls-tree", + Flags: flags, + Args: []string{revision}, + }, + git.WithStderr(&stderr), + ) + if err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("spawning ls-tree: %w", err), + }) + return + } + + parser := lstree.NewParser(cmd, objectHash) + for { + entry, err := parser.NextEntry() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("scanning ls-tree output: %w", err), + }) + return + } + + if cfg.typeFilter != nil && !cfg.typeFilter(entry) { + continue + } + + result := RevisionResult{ + OID: entry.ObjectID, + ObjectName: []byte(entry.Path), + } + + if cfg.skipResult != nil && cfg.skipResult(&result) { + continue + } + + if isDone := sendRevisionResult(ctx, resultChan, result); isDone { + return + } + } + + if err := cmd.Wait(); err != nil { + sendRevisionResult(ctx, resultChan, RevisionResult{ + err: fmt.Errorf("ls-tree pipeline command: %w, stderr: %q", err, stderr.String()), + }) + return + } + }() + + return &revisionIterator{ + ctx: ctx, + ch: resultChan, + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree_test.go new file mode 100644 index 0000000000..e5a7bdccfb --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/ls_tree_test.go @@ -0,0 +1,188 @@ +package gitpipe + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestLsTree(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + for _, tc := range []struct { + desc string + setup func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) + options []LsTreeOption + expectedErr error + }{ + { + desc: "initial commit", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + blobA := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + blobB := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + blobC := gittest.WriteBlob(t, cfg, repoPath, []byte("c")) + + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitignore", Mode: "100644", OID: blobA}, + {Path: "LICENSE", Mode: "100644", OID: blobB}, + {Path: "README.md", Mode: "100644", OID: blobC}, + }) + + return tree.Revision(), []RevisionResult{ + {OID: blobA, ObjectName: []byte(".gitignore")}, + {OID: blobB, ObjectName: []byte("LICENSE")}, + {OID: blobC, ObjectName: []byte("README.md")}, + } + }, + }, + { + desc: "includes submodule", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + commit := gittest.WriteCommit(t, cfg, repoPath) + + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob", Mode: "100644", OID: blob}, + {Path: "submodule", Mode: "160000", OID: commit}, + }) + + return tree.Revision(), []RevisionResult{ + {OID: blob, ObjectName: []byte("blob")}, + {OID: commit, ObjectName: []byte("submodule")}, + } + }, + }, + { + desc: "filter blobs only", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + commit := gittest.WriteCommit(t, cfg, repoPath) + + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "blob", + Mode: "100644", + OID: blob, + }, + { + Path: "submodule", + Mode: "160000", + OID: commit, + }, + { + Path: "subtree", + Mode: "040000", + OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob-in-subtree", Mode: "100644", Content: "something"}, + }), + }, + }) + + return tree.Revision(), []RevisionResult{ + {OID: blob, ObjectName: []byte("blob")}, + } + }, + options: []LsTreeOption{ + LsTreeWithBlobFilter(), + }, + }, + { + desc: "empty tree", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + return gittest.DefaultObjectHash.EmptyTreeOID.Revision(), nil + }, + }, + { + desc: "non-recursive", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob-in-subtree", Mode: "100644", Content: "something"}, + }) + + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob", Mode: "100644", OID: blob}, + {Path: "subtree", Mode: "040000", OID: subtree}, + }) + + return tree.Revision(), []RevisionResult{ + {OID: blob, ObjectName: []byte("blob")}, + {OID: subtree, ObjectName: []byte("subtree")}, + } + }, + }, + { + desc: "recursive", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + blobInSubtree := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "blob", + Mode: "100644", + OID: blob, + }, + { + Path: "subtree", + Mode: "040000", + OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob-in-subtree", Mode: "100644", OID: blobInSubtree}, + }), + }, + }) + + return tree.Revision(), []RevisionResult{ + {OID: blob, ObjectName: []byte("blob")}, + {OID: blobInSubtree, ObjectName: []byte("subtree/blob-in-subtree")}, + } + }, + options: []LsTreeOption{ + LsTreeWithRecursive(), + }, + }, + { + desc: "invalid revision", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + return "refs/heads/does-not-exist", nil + }, + expectedErr: errors.New("ls-tree pipeline command: exit status 128, stderr: " + + "\"fatal: Not a valid object name refs/heads/does-not-exist\\n\""), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + revision, expectedResults := tc.setup(t, repoPath) + + it := LsTree(ctx, repo, revision.String(), tc.options...) + + var results []RevisionResult + for it.Next() { + results = append(results, it.Result()) + } + + // We're converting the error here to a plain un-nested error such that we + // don't have to replicate the complete error's structure. + err := it.Err() + if err != nil { + err = errors.New(err.Error()) + } + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, expectedResults, results) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/object_iterator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/object_iterator.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/object_iterator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/object_iterator.go index 5628bc2c74..3546513af6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/object_iterator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/object_iterator.go @@ -1,6 +1,6 @@ package gitpipe -import "gitlab.com/gitlab-org/gitaly/v14/internal/git" +import "gitlab.com/gitlab-org/gitaly/v15/internal/git" // ObjectIterator is a common interface that is shared across the pipeline steps that work with // objects. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/pipeline_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/pipeline_test.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/pipeline_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/pipeline_test.go index 069bb55846..2af0f0496f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/pipeline_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/pipeline_test.go @@ -8,20 +8,40 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestPipeline_revlist(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) + blobA := gittest.WriteBlob(t, cfg, repoPath, []byte("blob a")) + blobB := gittest.WriteBlob(t, cfg, repoPath, []byte("b")) + blobC := gittest.WriteBlob(t, cfg, repoPath, []byte("longer blob c")) + + subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "subblob", Mode: "100644", OID: blobA}, + }) + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "blob", Mode: "100644", OID: blobB}, + {Path: "subtree", Mode: "040000", OID: subtree}, + }) + + commitA := gittest.WriteCommit(t, cfg, repoPath) + commitB := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(commitA), gittest.WithTree(tree), gittest.WithBranch("main")) + for _, tc := range []struct { desc string revisions []string @@ -33,79 +53,81 @@ func TestPipeline_revlist(t *testing.T) { { desc: "single blob", revisions: []string{ - lfsPointer1, + blobA.String(), }, revlistOptions: []RevlistOption{ WithObjects(), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}}, }, }, { desc: "single blob without objects", revisions: []string{ - lfsPointer1, + blobA.String(), }, expectedResults: nil, }, { desc: "multiple blobs", revisions: []string{ - lfsPointer1, - lfsPointer2, - lfsPointer3, + blobA.String(), + blobB.String(), + blobC.String(), }, revlistOptions: []RevlistOption{ WithObjects(), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 13}}}, }, }, { desc: "multiple blobs with filter", revisions: []string{ - lfsPointer1, - lfsPointer2, - lfsPointer3, + blobA.String(), + blobB.String(), + blobC.String(), }, revlistOptions: []RevlistOption{ WithObjects(), WithSkipRevlistResult(func(r *RevisionResult) bool { - return r.OID != lfsPointer2 + return r.OID != blobB }), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}}, }, }, { desc: "tree", revisions: []string{ - "b95c0fad32f4361845f91d9ce4c1721b52b82793", + tree.String(), }, revlistOptions: []RevlistOption{ WithObjects(), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(66, 90)}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: subtree, Type: "tree", Size: hashDependentObjectSize(35, 47)}}, ObjectName: []byte("subtree")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "tree without objects", revisions: []string{ - "b95c0fad32f4361845f91d9ce4c1721b52b82793", + tree.String(), }, expectedResults: nil, }, { desc: "tree with blob filter", revisions: []string{ - "b95c0fad32f4361845f91d9ce4c1721b52b82793", + tree.String(), }, revlistOptions: []RevlistOption{ WithObjects(), @@ -116,37 +138,35 @@ func TestPipeline_revlist(t *testing.T) { }), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "revision range", revisions: []string{ - "^master~", - "master", + "^" + commitB.String() + "~", + commitB.String(), }, revlistOptions: []RevlistOption{ WithObjects(), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "07f8147e8e73aab6c935c296e8cdc5194dee729b", Type: "tree", Size: 780}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", Type: "tree", Size: 258}}, ObjectName: []byte("files")}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "2132d150328bd9334cc4e62a16a5d998a7e399b9", Type: "tree", Size: 31}}, ObjectName: []byte("files/flat")}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", Type: "tree", Size: 34}}, ObjectName: []byte("files/flat/path")}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "ea7249055466085d0a6c69951908ef47757e92f4", Type: "tree", Size: 39}}, ObjectName: []byte("files/flat/path/correct")}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: commitB, Type: "commit", Size: hashDependentObjectSize(225, 273)}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(66, 90)}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: subtree, Type: "tree", Size: hashDependentObjectSize(35, 47)}}, ObjectName: []byte("subtree")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "revision range without objects", revisions: []string{ - "^master~", - "master", + "^" + commitB.String() + "~", + commitB.String(), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: commitB, Type: "commit", Size: hashDependentObjectSize(225, 273)}}}, }, }, { @@ -157,20 +177,19 @@ func TestPipeline_revlist(t *testing.T) { revlistOptions: []RevlistOption{ WithObjects(), WithSkipRevlistResult(func(r *RevisionResult) bool { - // Let through two LFS pointers and a tree. - return r.OID != "b95c0fad32f4361845f91d9ce4c1721b52b82793" && - r.OID != lfsPointer1 && r.OID != lfsPointer2 + // Let through two blobs and a tree. + return r.OID != tree && r.OID != blobA && r.OID != blobB }), }, catfileInfoOptions: []CatfileInfoOption{ WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool { - // Only let through blobs, so only the two LFS pointers remain. + // Only let through blobs, so only the two blobs remain. return objectInfo.Type != "blob" }), }, expectedResults: []CatfileObjectResult{ - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, ObjectName: []byte("files/lfs/lfs_object.iso")}, - {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, ObjectName: []byte("another.lfs")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")}, + {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")}, }, }, { @@ -186,9 +205,9 @@ func TestPipeline_revlist(t *testing.T) { { desc: "mixed valid and invalid revision", revisions: []string{ - lfsPointer1, + blobA.String(), "doesnotexist", - lfsPointer2, + blobB.String(), }, expectedErr: errors.New("rev-list pipeline command: exit status 128, stderr: " + "\"fatal: ambiguous argument 'doesnotexist': unknown revision or path not in the working tree.\\n" + @@ -219,16 +238,16 @@ func TestPipeline_revlist(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) - catfileCache := catfile.NewCache(cfg) defer catfileCache.Stop() - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) require.NoError(t, err) + defer cancel() - objectReader, err := catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) require.NoError(t, err) + defer cancel() revlistIter := Revlist(ctx, repo, tc.revisions, tc.revlistOptions...) @@ -280,11 +299,13 @@ func TestPipeline_revlist(t *testing.T) { catfileCache := catfile.NewCache(cfg) defer catfileCache.Stop() - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancelReader, err := catfileCache.ObjectInfoReader(ctx, repo) require.NoError(t, err) + defer cancelReader() - objectReader, err := catfileCache.ObjectReader(ctx, repo) + objectReader, cancelReader, err := catfileCache.ObjectReader(ctx, repo) require.NoError(t, err) + defer cancelReader() revlistIter := Revlist(ctx, repo, []string{"--all"}) @@ -301,12 +322,12 @@ func TestPipeline_revlist(t *testing.T) { _, err := io.Copy(io.Discard, catfileObjectIter.Result()) require.NoError(t, err) - if i == 3 { + if i == 1 { cancel() } } - require.NoError(t, catfileObjectIter.Err()) + require.Equal(t, context.Canceled, catfileObjectIter.Err()) // Context cancellation is timing sensitive: at the point of cancelling the context, // the last pipeline step may already have queued up an additional result. We thus @@ -320,11 +341,13 @@ func TestPipeline_revlist(t *testing.T) { catfileCache := catfile.NewCache(cfg) defer catfileCache.Stop() - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) require.NoError(t, err) + defer cancel() - objectReader, err := catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) require.NoError(t, err) + defer cancel() revlistIter := Revlist(ctx, repo, []string{"--all"}, WithObjects()) @@ -358,25 +381,38 @@ func TestPipeline_revlist(t *testing.T) { // We could in theory assert the exact amount of objects, but this would make it // harder than necessary to change the test repo's contents. - require.Greater(t, i, 1000) + require.Equal(t, i, 7) }) } func TestPipeline_forEachRef(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) - ctx := testhelper.Context(t) + + keepaliveCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithReference("refs/keep-alive/a"), gittest.WithMessage("keepalive")) + mainCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main")) + featureCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature")) + tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", mainCommit.Revision(), gittest.WriteTagConfig{ + Message: "annotated", + }) catfileCache := catfile.NewCache(cfg) defer catfileCache.Stop() - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) require.NoError(t, err) + defer cancel() - objectReader, err := catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) require.NoError(t, err) + defer cancel() forEachRefIter := ForEachRef(ctx, repo, nil) @@ -391,6 +427,22 @@ func TestPipeline_forEachRef(t *testing.T) { content []byte } + expectedRefs := map[git.ReferenceName]object{ + "refs/keep-alive/a": {oid: keepaliveCommit, content: []byte("xx")}, + "refs/heads/main": {oid: mainCommit, content: []byte("xx")}, + "refs/heads/feature": {oid: featureCommit, content: []byte("xx")}, + "refs/tags/v1.0.0": {oid: tag, content: []byte("xx")}, + } + for expectedRef, expectedObject := range expectedRefs { + content, err := repo.ReadObject(ctx, expectedObject.oid) + require.NoError(t, err) + + expectedRefs[expectedRef] = object{ + oid: expectedObject.oid, + content: content, + } + } + objectsByRef := make(map[git.ReferenceName]object) for catfileObjectIter.Next() { result := catfileObjectIter.Result() @@ -405,24 +457,5 @@ func TestPipeline_forEachRef(t *testing.T) { } } require.NoError(t, catfileObjectIter.Err()) - require.Greater(t, len(objectsByRef), 90) - - // We certainly don't want to hard-code all the references, so we just cross-check with the - // localrepo implementation to verify that both return the same data. - refs, err := repo.GetReferences(ctx) - require.NoError(t, err) - require.Equal(t, len(refs), len(objectsByRef)) - - expectedObjectsByRef := make(map[git.ReferenceName]object) - for _, ref := range refs { - oid := git.ObjectID(ref.Target) - content, err := repo.ReadObject(ctx, oid) - require.NoError(t, err) - - expectedObjectsByRef[ref.Name] = object{ - oid: oid, - content: content, - } - } - require.Equal(t, expectedObjectsByRef, objectsByRef) + require.Equal(t, expectedRefs, objectsByRef) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision.go index 68fcecbbae..9e7f5be614 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision.go @@ -9,8 +9,8 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" ) // RevisionResult is a result for the revlist pipeline step. @@ -43,17 +43,19 @@ const ( // revlistConfig is configuration for the revlist pipeline step. type revlistConfig struct { - blobLimit int - objects bool - objectType ObjectType - order Order - reverse bool - maxParents uint - disabledWalk bool - firstParent bool - before, after time.Time - author []byte - skipResult func(*RevisionResult) bool + blobLimit int + objects bool + objectType ObjectType + order Order + reverse bool + maxParents uint + disabledWalk bool + firstParent bool + before, after time.Time + author []byte + regexIgnoreCase bool + commitMessagePatterns [][]byte + skipResult func(*RevisionResult) bool } // RevlistOption is an option for the revlist pipeline step. @@ -161,6 +163,22 @@ func WithAuthor(author []byte) RevlistOption { } } +// WithIgnoreCase causes git-rev-list(1) to apply regex patterns +// in case-insensitive manner. +func WithIgnoreCase(ignoreCase bool) RevlistOption { + return func(cfg *revlistConfig) { + cfg.regexIgnoreCase = ignoreCase + } +} + +// WithCommitMessagePatterns causes git-rev-list(1) to only show commits whose message +// matches any of the regex patterns in commitMessagePatterns. +func WithCommitMessagePatterns(commitMessagePatterns [][]byte) RevlistOption { + return func(cfg *revlistConfig) { + cfg.commitMessagePatterns = commitMessagePatterns + } +} + // WithSkipRevlistResult will execute the given function for each RevisionResult processed by the // pipeline. If the callback returns `true`, then the object will be skipped and not passed down // the pipeline. @@ -257,6 +275,16 @@ func Revlist( }) } + if cfg.regexIgnoreCase { + flags = append(flags, git.Flag{Name: "--regexp-ignore-case"}) + } + + if len(cfg.commitMessagePatterns) > 0 { + for _, pattern := range cfg.commitMessagePatterns { + flags = append(flags, git.Flag{Name: fmt.Sprintf("--grep=%s", pattern)}) + } + } + var stderr strings.Builder revlist, err := repo.Exec(ctx, git.SubCmd{ @@ -314,7 +342,8 @@ func Revlist( }() return &revisionIterator{ - ch: resultChan, + ctx: ctx, + ch: resultChan, } } @@ -443,7 +472,8 @@ func ForEachRef( }() return &revisionIterator{ - ch: resultChan, + ctx: ctx, + ch: resultChan, } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_iterator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_iterator.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_iterator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_iterator.go index 8d949e648d..1fc12716b5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_iterator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_iterator.go @@ -1,6 +1,10 @@ package gitpipe -import "gitlab.com/gitlab-org/gitaly/v14/internal/git" +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" +) // RevisionIterator is an iterator returned by the Revlist function. type RevisionIterator interface { @@ -10,7 +14,7 @@ type RevisionIterator interface { } // NewRevisionIterator returns a new RevisionIterator for the given items. -func NewRevisionIterator(items []RevisionResult) RevisionIterator { +func NewRevisionIterator(ctx context.Context, items []RevisionResult) RevisionIterator { itemChan := make(chan RevisionResult, len(items)) for _, item := range items { itemChan <- item @@ -18,11 +22,13 @@ func NewRevisionIterator(items []RevisionResult) RevisionIterator { close(itemChan) return &revisionIterator{ - ch: itemChan, + ctx: ctx, + ch: itemChan, } } type revisionIterator struct { + ctx context.Context ch <-chan RevisionResult result RevisionResult } @@ -32,13 +38,31 @@ func (it *revisionIterator) Next() bool { return false } - var ok bool - it.result, ok = <-it.ch - if !ok || it.result.err != nil { + // Prioritize context cancellation errors so that we don't try to fetch results anymore when + // the context is done. + select { + case <-it.ctx.Done(): + it.result = RevisionResult{err: it.ctx.Err()} return false + default: } - return true + select { + case <-it.ctx.Done(): + it.result = RevisionResult{err: it.ctx.Err()} + return false + case result, ok := <-it.ch: + if !ok { + return false + } + + it.result = result + if result.err != nil { + return false + } + + return true + } } func (it *revisionIterator) Err() error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_test.go index 091df9e3ff..723f1316bb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe/revision_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/revision_test.go @@ -1,26 +1,79 @@ package gitpipe import ( + "bytes" + "context" "errors" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestRevlist(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) + blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133)) + blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127)) + blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127)) + blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129)) + + blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a")) + subblob := gittest.WriteBlob(t, cfg, repoPath, []byte("larger blob")) + + treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "branch-test.txt", Mode: "100644", OID: blob}, + }) + commitA := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTree(treeA), + gittest.WithCommitterDate(time.Date(2000, 1, 1, 1, 1, 1, 1, time.UTC)), + ) + + subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "subblob", Mode: "100644", OID: subblob}, + }) + treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "branch-test.txt", Mode: "100644", OID: blob}, + {Path: "subtree", Mode: "040000", OID: subtree}, + }) + commitB := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(commitA), + gittest.WithTree(treeB), + gittest.WithCommitterDate(time.Date(1999, 1, 1, 1, 1, 1, 1, time.UTC)), + gittest.WithAuthorName("custom author"), + ) + + commitBParent := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(commitB), + gittest.WithTree(treeB), + gittest.WithCommitterDate(time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)), + ) + commitAParent := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(commitA), + gittest.WithTree(treeA), + gittest.WithCommitterDate(time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)), + ) + + mergeCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(commitAParent, commitBParent)) + + tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", mergeCommit.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", + }) + for _, tc := range []struct { desc string revisions []string @@ -31,150 +84,146 @@ func TestRevlist(t *testing.T) { { desc: "single blob", revisions: []string{ - lfsPointer1, + blobA.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: lfsPointer1}, + {OID: blobA}, }, }, { desc: "multiple blobs", revisions: []string{ - lfsPointer1, - lfsPointer2, - lfsPointer3, - lfsPointer4, + blobA.String(), + blobB.String(), + blobC.String(), + blobD.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: lfsPointer1}, - {OID: lfsPointer2}, - {OID: lfsPointer3}, - {OID: lfsPointer4}, + {OID: blobA}, + {OID: blobB}, + {OID: blobC}, + {OID: blobD}, }, }, { desc: "multiple blobs without objects", revisions: []string{ - lfsPointer1, - lfsPointer2, - lfsPointer3, - lfsPointer4, + blobA.String(), + blobB.String(), + blobC.String(), + blobD.String(), }, expectedResults: nil, }, { desc: "duplicated blob prints blob once only", revisions: []string{ - lfsPointer1, - lfsPointer1, + blobA.String(), + blobA.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: lfsPointer1}, + {OID: blobA}, }, }, { desc: "tree results in object names", revisions: []string{ - "b95c0fad32f4361845f91d9ce4c1721b52b82793", + treeA.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, - {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")}, + {OID: treeA}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, }, }, { desc: "tree without objects returns nothing", revisions: []string{ - "b95c0fad32f4361845f91d9ce4c1721b52b82793", + treeA.String(), }, expectedResults: nil, }, { desc: "revision without disabled walk", revisions: []string{ - "refs/heads/master", + commitB.String(), }, options: []RevlistOption{ WithDisabledWalk(), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, + {OID: commitB}, }, }, { desc: "revision range", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + "^" + commitB.String() + "~", + commitB.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "07f8147e8e73aab6c935c296e8cdc5194dee729b"}, - {OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", ObjectName: []byte("files")}, - {OID: "2132d150328bd9334cc4e62a16a5d998a7e399b9", ObjectName: []byte("files/flat")}, - {OID: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", ObjectName: []byte("files/flat/path")}, - {OID: "ea7249055466085d0a6c69951908ef47757e92f4", ObjectName: []byte("files/flat/path/correct")}, - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + {OID: commitB}, + {OID: treeB}, + {OID: subtree, ObjectName: []byte("subtree")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "revision range without objects", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + "^" + commitB.String() + "~", + commitB.String(), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + {OID: commitB}, }, }, { desc: "revision range without objects with at most one parent", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + mergeCommit.String(), }, options: []RevlistOption{ WithMaxParents(1), }, expectedResults: []RevisionResult{ - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + {OID: commitAParent}, + {OID: commitBParent}, + {OID: commitA}, + {OID: commitB}, }, }, { desc: "reverse revision range without objects", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + commitB.String(), }, options: []RevlistOption{ WithReverse(), }, expectedResults: []RevisionResult{ - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, + {OID: commitA}, + {OID: commitB}, }, }, { desc: "reverse revision range with objects", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + commitB.String(), }, options: []RevlistOption{ WithReverse(), @@ -183,110 +232,86 @@ func TestRevlist(t *testing.T) { expectedResults: []RevisionResult{ // Note that only commits are listed in reverse, // their referenced objects stay in the same order. - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, - {OID: "07f8147e8e73aab6c935c296e8cdc5194dee729b"}, - {OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", ObjectName: []byte("files")}, - {OID: "2132d150328bd9334cc4e62a16a5d998a7e399b9", ObjectName: []byte("files/flat")}, - {OID: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", ObjectName: []byte("files/flat/path")}, - {OID: "ea7249055466085d0a6c69951908ef47757e92f4", ObjectName: []byte("files/flat/path/correct")}, - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, + {OID: commitA}, + {OID: treeA}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, + {OID: commitB}, + {OID: treeB}, + {OID: subtree, ObjectName: []byte("subtree")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "revision range with topo order", revisions: []string{ - // This is one of the smaller examples I've found which reproduces - // different sorting orders between topo- and date-sorting. Expected - // results contain the same object for this and the next test case, - // but ordering is different. - "master", - "^master~5", - "flat-path", + mergeCommit.String(), }, options: []RevlistOption{ WithOrder(OrderTopo), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, - {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"}, - {OID: "c84ff944ff4529a70788a5e9003c2b7feae29047"}, - {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"}, - {OID: "55bc176024cfa3baaceb71db584c7e5df900ea65"}, - {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"}, - {OID: "4a24d82dbca5c11c61556f3b35ca472b7463187e"}, - {OID: "b83d6e391c22777fca1ed3012fce84f633d7fed0"}, - {OID: "498214de67004b1da3d820901307bed2a68a8ef6"}, - // The following commit is sorted differently in the next testcase. - {OID: "ce369011c189f62c815f5971d096b26759bab0d1"}, + // Note that the order here is different from the order in the next + // testcase, where we use date-order. + {OID: mergeCommit}, + {OID: commitBParent}, + {OID: commitB}, + {OID: commitAParent}, + {OID: commitA}, }, }, { desc: "revision range with date order", revisions: []string{ - "master", - "^master~5", - "flat-path", + mergeCommit.String(), }, options: []RevlistOption{ WithOrder(OrderDate), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, - {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"}, - {OID: "c84ff944ff4529a70788a5e9003c2b7feae29047"}, - {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"}, - {OID: "55bc176024cfa3baaceb71db584c7e5df900ea65"}, - // The following commit is sorted differently in the previous - // testcase. - {OID: "ce369011c189f62c815f5971d096b26759bab0d1"}, - {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"}, - {OID: "4a24d82dbca5c11c61556f3b35ca472b7463187e"}, - {OID: "b83d6e391c22777fca1ed3012fce84f633d7fed0"}, - {OID: "498214de67004b1da3d820901307bed2a68a8ef6"}, + {OID: mergeCommit}, + {OID: commitAParent}, + {OID: commitBParent}, + {OID: commitB}, + {OID: commitA}, }, }, { desc: "revision range with dates", revisions: []string{ - "refs/heads/master", + mergeCommit.String(), }, options: []RevlistOption{ - WithBefore(time.Date(2016, 6, 30, 18, 30, 0, 0, time.UTC)), - WithAfter(time.Date(2016, 6, 30, 18, 28, 0, 0, time.UTC)), + WithBefore(time.Date(2000, 12, 1, 1, 1, 1, 1, time.UTC)), + WithAfter(time.Date(1999, 12, 1, 1, 1, 1, 1, time.UTC)), }, expectedResults: []RevisionResult{ - {OID: "6907208d755b60ebeacb2e9dfea74c92c3449a1f"}, - {OID: "c347ca2e140aa667b968e51ed0ffe055501fe4f4"}, + {OID: commitA}, }, }, { desc: "revision range with author", revisions: []string{ - "refs/heads/master", + mergeCommit.String(), }, options: []RevlistOption{ - WithAuthor([]byte("Sytse")), + WithAuthor([]byte("custom author")), }, expectedResults: []RevisionResult{ - {OID: "e56497bb5f03a90a51293fc6d516788730953899"}, + {OID: commitB}, }, }, { desc: "first parent chain", revisions: []string{ - "master", - "^master~4", + mergeCommit.String(), }, options: []RevlistOption{ WithFirstParent(), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"}, - {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"}, - {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"}, + {OID: mergeCommit}, + {OID: commitAParent}, + {OID: commitA}, }, }, { @@ -298,22 +323,16 @@ func TestRevlist(t *testing.T) { // twice, once without and once with limit. desc: "tree with multiple blobs without limit", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + treeB.String(), }, options: []RevlistOption{ WithObjects(), }, expectedResults: []RevisionResult{ - {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, - {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")}, - {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")}, - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, - {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")}, - {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")}, - {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, - {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, + {OID: treeB}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, + {OID: subtree, ObjectName: []byte("subtree")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, { @@ -321,38 +340,30 @@ func TestRevlist(t *testing.T) { // get less blobs as result. desc: "tree with multiple blobs with limit", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + treeB.String(), }, options: []RevlistOption{ WithObjects(), - WithBlobLimit(10), + WithBlobLimit(5), }, expectedResults: []RevisionResult{ - {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: treeB}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, + {OID: subtree, ObjectName: []byte("subtree")}, }, }, { desc: "tree with blob object type filter", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + treeB.String(), }, options: []RevlistOption{ WithObjects(), WithObjectTypeFilter(ObjectTypeBlob), }, expectedResults: []RevisionResult{ - {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")}, - {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")}, - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, - {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")}, - {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")}, - {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, - {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, { @@ -365,53 +376,48 @@ func TestRevlist(t *testing.T) { WithObjectTypeFilter(ObjectTypeTag), }, expectedResults: []RevisionResult{ - {OID: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", ObjectName: []byte("v1.0.0")}, - {OID: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", ObjectName: []byte("v1.1.0")}, - {OID: "8f03acbcd11c53d9c9468078f32a2622005a4841", ObjectName: []byte("v1.1.1")}, + {OID: tag, ObjectName: []byte("v1.0.0")}, }, }, { - desc: "tree with commit object type filter", + desc: "tree with tree object type filter", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + commitA.String(), }, options: []RevlistOption{ WithObjects(), WithObjectTypeFilter(ObjectTypeTree), }, expectedResults: []RevisionResult{ - {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, + {OID: treeA}, }, }, { desc: "tree with commit object type filter", revisions: []string{ - "^refs/heads/master~", - "refs/heads/master", + commitB.String(), }, options: []RevlistOption{ WithObjects(), WithObjectTypeFilter(ObjectTypeCommit), }, expectedResults: []RevisionResult{ - {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, - {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + {OID: commitB}, + {OID: commitA}, }, }, { desc: "tree with object type and blob size filter", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + mergeCommit.String(), }, options: []RevlistOption{ WithObjects(), - WithBlobLimit(10), + WithBlobLimit(5), WithObjectTypeFilter(ObjectTypeBlob), }, expectedResults: []RevisionResult{ - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, }, }, { @@ -427,7 +433,7 @@ func TestRevlist(t *testing.T) { { desc: "mixed valid and invalid revision", revisions: []string{ - lfsPointer1, + blobA.String(), "refs/heads/does-not-exist", }, expectedErr: errors.New("rev-list pipeline command: exit status 128, stderr: " + @@ -438,11 +444,10 @@ func TestRevlist(t *testing.T) { { desc: "skip everything", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + mergeCommit.String(), }, options: []RevlistOption{ WithObjects(), - WithBlobLimit(10), WithObjectTypeFilter(ObjectTypeBlob), WithSkipRevlistResult(func(*RevisionResult) bool { return true }), }, @@ -450,42 +455,36 @@ func TestRevlist(t *testing.T) { { desc: "skip nothing", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + mergeCommit.String(), }, options: []RevlistOption{ WithObjects(), - WithBlobLimit(10), WithObjectTypeFilter(ObjectTypeBlob), WithSkipRevlistResult(func(*RevisionResult) bool { return false }), }, expectedResults: []RevisionResult{ - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: blob, ObjectName: []byte("branch-test.txt")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, { desc: "skip one", revisions: []string{ - "79d5f98270ad677c86a7e1ab2baa922958565135", + mergeCommit.String(), }, options: []RevlistOption{ WithObjects(), - WithBlobLimit(10), WithObjectTypeFilter(ObjectTypeBlob), WithSkipRevlistResult(func(r *RevisionResult) bool { - return string(r.ObjectName) == "hotfix-2.txt" + return bytes.Equal(r.ObjectName, []byte("branch-test.txt")) }), }, expectedResults: []RevisionResult{ - {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, - {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: subblob, ObjectName: []byte("subtree/subblob")}, }, }, } { t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) - it := Revlist(ctx, repo, tc.revisions, tc.options...) var results []RevisionResult @@ -504,9 +503,31 @@ func TestRevlist(t *testing.T) { require.Equal(t, tc.expectedResults, results) }) } + + t.Run("context cancellation", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + it := Revlist(ctx, repo, []string{mergeCommit.String()}) + + require.True(t, it.Next()) + require.NoError(t, it.Err()) + require.Equal(t, RevisionResult{ + OID: mergeCommit, + }, it.Result()) + + cancel() + + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + require.Equal(t, RevisionResult{ + err: context.Canceled, + }, it.Result()) + }) } func TestForEachRef(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) readRefs := func(t *testing.T, repo *localrepo.Repo, patterns []string, opts ...ForEachRefOption) []RevisionResult { @@ -521,55 +542,54 @@ func TestForEachRef(t *testing.T) { return results } - cfg, repoProto, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) - revisions := make(map[string]git.ObjectID) - for _, reference := range []string{"refs/heads/master", "refs/heads/feature"} { - revision, err := repo.ResolveRevision(ctx, git.Revision(reference)) - require.NoError(t, err) - - revisions[reference] = revision - } + mainCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main")) + featureCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature")) + tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", featureCommit.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", + }) t.Run("single fully qualified branch", func(t *testing.T) { require.Equal(t, []RevisionResult{ { - ObjectName: []byte("refs/heads/master"), - OID: revisions["refs/heads/master"], + ObjectName: []byte("refs/heads/main"), + OID: mainCommit, }, - }, readRefs(t, repo, []string{"refs/heads/master"})) + }, readRefs(t, repo, []string{"refs/heads/main"})) }) t.Run("unqualified branch name", func(t *testing.T) { - require.Nil(t, readRefs(t, repo, []string{"master"})) + require.Nil(t, readRefs(t, repo, []string{"main"})) }) t.Run("multiple branches", func(t *testing.T) { require.Equal(t, []RevisionResult{ { ObjectName: []byte("refs/heads/feature"), - OID: revisions["refs/heads/feature"], + OID: featureCommit, }, { - ObjectName: []byte("refs/heads/master"), - OID: revisions["refs/heads/master"], + ObjectName: []byte("refs/heads/main"), + OID: mainCommit, }, - }, readRefs(t, repo, []string{"refs/heads/master", "refs/heads/feature"})) + }, readRefs(t, repo, []string{"refs/heads/main", "refs/heads/feature"})) }) t.Run("branches pattern", func(t *testing.T) { refs := readRefs(t, repo, []string{"refs/heads/*"}) - require.Greater(t, len(refs), 90) - - require.Subset(t, refs, []RevisionResult{ - { - ObjectName: []byte("refs/heads/master"), - OID: revisions["refs/heads/master"], - }, + require.Equal(t, refs, []RevisionResult{ { ObjectName: []byte("refs/heads/feature"), - OID: revisions["refs/heads/feature"], + OID: featureCommit, + }, + { + ObjectName: []byte("refs/heads/main"), + OID: mainCommit, }, }) }) @@ -582,18 +602,31 @@ func TestForEachRef(t *testing.T) { require.Equal(t, refs, []RevisionResult{ { ObjectName: []byte("tag"), - OID: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + OID: tag, }, { ObjectName: []byte("peeled"), - OID: "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9", + OID: featureCommit, }, }) }) t.Run("multiple patterns", func(t *testing.T) { refs := readRefs(t, repo, []string{"refs/heads/*", "refs/tags/*"}) - require.Greater(t, len(refs), 90) + require.Equal(t, refs, []RevisionResult{ + { + ObjectName: []byte("refs/heads/feature"), + OID: featureCommit, + }, + { + ObjectName: []byte("refs/heads/main"), + OID: mainCommit, + }, + { + ObjectName: []byte("refs/tags/v1.0.0"), + OID: tag, + }, + }) }) t.Run("nonexisting branch", func(t *testing.T) { @@ -603,9 +636,32 @@ func TestForEachRef(t *testing.T) { t.Run("nonexisting pattern", func(t *testing.T) { require.Nil(t, readRefs(t, repo, []string{"refs/idontexist/*"})) }) + + t.Run("context cancellation", func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + it := ForEachRef(ctx, repo, []string{"refs/heads/*"}) + + require.True(t, it.Next()) + require.NoError(t, it.Err()) + require.Equal(t, RevisionResult{ + OID: featureCommit, + ObjectName: []byte("refs/heads/feature"), + }, it.Result()) + + cancel() + + require.False(t, it.Next()) + require.Equal(t, context.Canceled, it.Err()) + require.Equal(t, RevisionResult{ + err: context.Canceled, + }, it.Result()) + }) } func TestForEachRef_options(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) for _, tc := range []struct { @@ -658,8 +714,11 @@ func TestForEachRef_options(t *testing.T) { }, }, } { + cfg := testcfg.Build(t) - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) oid := tc.prepare(repoPath, cfg) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/testhelper_test.go new file mode 100644 index 0000000000..4bc9f18f7f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe/testhelper_test.go @@ -0,0 +1,59 @@ +package gitpipe + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +// chanObjectIterator is an object iterator that can be driven via a set of channels for +// deterministically exercising specific conditions in tests. +type chanObjectIterator struct { + ObjectIterator + + oid git.ObjectID + oidChan <-chan git.ObjectID + nextChan chan<- interface{} +} + +// newChanObjectIterator returns a new object iterator as well as two channels: one object ID +// channel that can be used to inject the next value returned by `Next()`. And then a second value +// that is written to when `Next()` is called. +func newChanObjectIterator() (ObjectIterator, chan<- git.ObjectID, <-chan interface{}) { + oidChan := make(chan git.ObjectID) + nextChan := make(chan interface{}) + return &chanObjectIterator{ + oidChan: oidChan, + nextChan: nextChan, + }, oidChan, nextChan +} + +func (ch *chanObjectIterator) Next() bool { + // Notify the caller that the next object was requested. + ch.nextChan <- struct{}{} + + var ok bool + ch.oid, ok = <-ch.oidChan + return ok +} + +func (ch *chanObjectIterator) ObjectID() git.ObjectID { + return ch.oid +} + +func (ch *chanObjectIterator) ObjectName() []byte { + return []byte("idontcare") +} + +func hashDependentObjectSize(sha1Size, sha256Size int64) int64 { + if gittest.ObjectHashIsSHA256() { + return sha256Size + } + return sha1Size +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command.go index 0621a32c56..376f928b47 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/command.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command.go @@ -6,9 +6,9 @@ import ( "os/exec" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) // ExecConfig contains configuration for ExecOpts. @@ -24,45 +24,58 @@ type ExecConfig struct { } // Exec runs a git command and returns the standard output, or fails. -func Exec(t testing.TB, cfg config.Cfg, args ...string) []byte { - t.Helper() - return ExecOpts(t, cfg, ExecConfig{}, args...) +func Exec(tb testing.TB, cfg config.Cfg, args ...string) []byte { + tb.Helper() + return ExecOpts(tb, cfg, ExecConfig{}, args...) } // ExecOpts runs a git command with the given configuration. -func ExecOpts(t testing.TB, cfg config.Cfg, execCfg ExecConfig, args ...string) []byte { - t.Helper() +func ExecOpts(tb testing.TB, cfg config.Cfg, execCfg ExecConfig, args ...string) []byte { + tb.Helper() - cmd := createCommand(t, cfg, execCfg, args...) + cmd := createCommand(tb, cfg, execCfg, args...) + + // If the caller has passed an stdout writer to us we cannot use `cmd.Output()`. So + // we detect this case and call `cmd.Run()` instead. + if execCfg.Stdout != nil { + if err := cmd.Run(); err != nil { + tb.Log(cfg.Git.BinPath, args) + if ee, ok := err.(*exec.ExitError); ok { + tb.Logf("%s\n", ee.Stderr) + } + tb.Fatal(err) + } + + return nil + } output, err := cmd.Output() if err != nil { - t.Log(cfg.Git.BinPath, args) + tb.Log(cfg.Git.BinPath, args) if ee, ok := err.(*exec.ExitError); ok { - t.Logf("%s: %s\n", ee.Stderr, output) + tb.Logf("%s: %s\n", ee.Stderr, output) } - t.Fatal(err) + tb.Fatal(err) } return output } // NewCommand creates a new Git command ready for execution. -func NewCommand(t testing.TB, cfg config.Cfg, args ...string) *exec.Cmd { - t.Helper() - return createCommand(t, cfg, ExecConfig{}, args...) +func NewCommand(tb testing.TB, cfg config.Cfg, args ...string) *exec.Cmd { + tb.Helper() + return createCommand(tb, cfg, ExecConfig{}, args...) } -func createCommand(t testing.TB, cfg config.Cfg, execCfg ExecConfig, args ...string) *exec.Cmd { - t.Helper() +func createCommand(tb testing.TB, cfg config.Cfg, execCfg ExecConfig, args ...string) *exec.Cmd { + tb.Helper() - ctx := testhelper.Context(t) + ctx := testhelper.Context(tb) - execEnv := NewCommandFactory(t, cfg).GetExecutionEnvironment(ctx) + execEnv := NewCommandFactory(tb, cfg).GetExecutionEnvironment(ctx) cmd := exec.CommandContext(ctx, execEnv.BinaryPath, args...) cmd.Env = command.AllowedEnvironment(os.Environ()) - cmd.Env = append(command.GitEnv, cmd.Env...) cmd.Env = append(cmd.Env, "GIT_AUTHOR_DATE=1572776879 +0100", "GIT_COMMITTER_DATE=1572776879 +0100", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_factory.go new file mode 100644 index 0000000000..863de697b1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_factory.go @@ -0,0 +1,27 @@ +package gittest + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" +) + +// NewCommandFactory creates a new Git command factory. +func NewCommandFactory(tb testing.TB, cfg config.Cfg, opts ...git.ExecCommandFactoryOption) git.CommandFactory { + tb.Helper() + factory, cleanup, err := git.NewExecCommandFactory(cfg, opts...) + require.NoError(tb, err) + tb.Cleanup(cleanup) + return factory +} + +// GitSupportsStatusFlushing returns whether or not the current version of Git +// supports status flushing. +func GitSupportsStatusFlushing(t *testing.T, ctx context.Context, cfg config.Cfg) bool { + version, err := NewCommandFactory(t, cfg).GitVersion(ctx) + require.NoError(t, err) + return version.FlushesUpdaterefStatus() +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_test.go new file mode 100644 index 0000000000..2cbe8dae34 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/command_test.go @@ -0,0 +1,51 @@ +package gittest + +import ( + "bytes" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +func TestExecOpts(t *testing.T) { + cfg, _, repoPath := setup(t) + + t.Run("default config", func(t *testing.T) { + toplevel := ExecOpts(t, cfg, ExecConfig{}, "-C", repoPath, "rev-parse", "--path-format=absolute", "--git-dir") + require.Equal(t, repoPath, text.ChompBytes(toplevel)) + }) + + t.Run("env", func(t *testing.T) { + configValue := ExecOpts(t, cfg, ExecConfig{ + Env: []string{ + "GIT_CONFIG_COUNT=1", + "GIT_CONFIG_KEY_0=injected.env-config", + "GIT_CONFIG_VALUE_0=some value", + }, + }, "-C", repoPath, "config", "injected.env-config") + + require.Equal(t, "some value", text.ChompBytes(configValue)) + }) + + t.Run("stdin", func(t *testing.T) { + blobID := ExecOpts(t, cfg, ExecConfig{ + Stdin: strings.NewReader("blob contents"), + }, "-C", repoPath, "hash-object", "-w", "--stdin") + + require.Equal(t, + "blob contents", + string(Exec(t, cfg, "-C", repoPath, "cat-file", "-p", text.ChompBytes(blobID))), + ) + }) + + t.Run("stdout", func(t *testing.T) { + var buf bytes.Buffer + ExecOpts(t, cfg, ExecConfig{ + Stdout: &buf, + }, "-C", repoPath, "rev-parse", "--path-format=absolute", "--git-dir") + + require.Equal(t, repoPath, text.ChompBytes(buf.Bytes())) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit.go new file mode 100644 index 0000000000..7e2adbc254 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit.go @@ -0,0 +1,261 @@ +package gittest + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +var ( + // DefaultCommitterName is the default name of the committer and author used to create + // commits. + DefaultCommitterName = "Scrooge McDuck" + // DefaultCommitterMail is the default mail of the committer and author used to create + // commits. + DefaultCommitterMail = "scrooge@mcduck.com" + // DefaultCommitTime is the default time used as written by WriteCommit(). + DefaultCommitTime = time.Date(2019, 11, 3, 11, 27, 59, 0, time.FixedZone("", 60*60)) + // DefaultCommitterSignature is the default signature in the format like it would be present + // in commits: "$name <$email> $unixtimestamp $timezone". + DefaultCommitterSignature = fmt.Sprintf( + "%s <%s> %d %s", DefaultCommitterName, DefaultCommitterMail, DefaultCommitTime.Unix(), DefaultCommitTime.Format("-0700"), + ) + // DefaultCommitAuthor is the Protobuf message representation of the default committer and + // author used to create commits. + DefaultCommitAuthor = &gitalypb.CommitAuthor{ + Name: []byte(DefaultCommitterName), + Email: []byte(DefaultCommitterMail), + Date: timestamppb.New(DefaultCommitTime), + Timezone: []byte("+0100"), + } +) + +type writeCommitConfig struct { + reference string + parents []git.ObjectID + authorDate time.Time + authorName string + committerName string + committerDate time.Time + message string + treeEntries []TreeEntry + treeID git.ObjectID + alternateObjectDir string +} + +// WriteCommitOption is an option which can be passed to WriteCommit. +type WriteCommitOption func(*writeCommitConfig) + +// WithReference is an option for WriteCommit which will cause it to update the given reference to +// point to the new commit. This function requires the fully-qualified reference name. +func WithReference(reference string) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.reference = reference + } +} + +// WithBranch is an option for WriteCommit which will cause it to update the given branch name to +// the new commit. +func WithBranch(branch string) WriteCommitOption { + return WithReference("refs/heads/" + branch) +} + +// WithMessage is an option for WriteCommit which will set the commit message. +func WithMessage(message string) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.message = message + } +} + +// WithParents is an option for WriteCommit which will set the parent OIDs of the resulting commit. +func WithParents(parents ...git.ObjectID) WriteCommitOption { + return func(cfg *writeCommitConfig) { + if parents != nil { + cfg.parents = parents + } else { + // We're explicitly initializing parents here such that we can discern the + // case where the commit should be created with no parents. + cfg.parents = []git.ObjectID{} + } + } +} + +// WithTreeEntries is an option for WriteCommit which will cause it to create a new tree and use it +// as root tree of the resulting commit. +func WithTreeEntries(entries ...TreeEntry) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.treeEntries = entries + } +} + +// WithTree is an option for WriteCommit which will cause it to use the given object ID as the root +// tree of the resulting commit. +// as root tree of the resulting commit. +func WithTree(treeID git.ObjectID) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.treeID = treeID + } +} + +// WithAuthorName is an option for WriteCommit which will set the author name. +func WithAuthorName(name string) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.authorName = name + } +} + +// WithAuthorDate is an option for WriteCommit which will set the author date. +func WithAuthorDate(date time.Time) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.authorDate = date + } +} + +// WithCommitterName is an option for WriteCommit which will set the committer name. +func WithCommitterName(name string) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.committerName = name + } +} + +// WithCommitterDate is an option for WriteCommit which will set the committer date. +func WithCommitterDate(date time.Time) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.committerDate = date + } +} + +// WithAlternateObjectDirectory will cause the commit to be written into the given alternate object +// directory. This can either be an absolute path or a relative path. In the latter case the path +// is considered to be relative to the repository path. +func WithAlternateObjectDirectory(alternateObjectDir string) WriteCommitOption { + return func(cfg *writeCommitConfig) { + cfg.alternateObjectDir = alternateObjectDir + } +} + +// WriteCommit writes a new commit into the target repository. +func WriteCommit(tb testing.TB, cfg config.Cfg, repoPath string, opts ...WriteCommitOption) git.ObjectID { + tb.Helper() + + var writeCommitConfig writeCommitConfig + for _, opt := range opts { + opt(&writeCommitConfig) + } + + message := "message" + if writeCommitConfig.message != "" { + message = writeCommitConfig.message + } + stdin := bytes.NewBufferString(message) + + if len(writeCommitConfig.treeEntries) > 0 && writeCommitConfig.treeID != "" { + require.FailNow(tb, "cannot set tree entries and tree ID at the same time") + } + + var tree string + if len(writeCommitConfig.treeEntries) > 0 { + tree = WriteTree(tb, cfg, repoPath, writeCommitConfig.treeEntries).String() + } else if writeCommitConfig.treeID != "" { + tree = writeCommitConfig.treeID.String() + } else if len(writeCommitConfig.parents) == 0 { + // If there are no parents, then we set the root tree to the empty tree. + tree = DefaultObjectHash.EmptyTreeOID.String() + } else { + tree = writeCommitConfig.parents[0].String() + "^{tree}" + } + + if writeCommitConfig.authorName == "" { + writeCommitConfig.authorName = DefaultCommitterName + } + + if writeCommitConfig.authorDate.IsZero() { + writeCommitConfig.authorDate = time.Date(2019, 11, 3, 11, 27, 59, 0, time.FixedZone("UTC+1", 1*60*60)) + } + + if writeCommitConfig.committerName == "" { + writeCommitConfig.committerName = DefaultCommitterName + } + + if writeCommitConfig.committerDate.IsZero() { + writeCommitConfig.committerDate = time.Date(2019, 11, 3, 11, 27, 59, 0, time.FixedZone("UTC+1", 1*60*60)) + } + + // Use 'commit-tree' instead of 'commit' because we are in a bare + // repository. What we do here is the same as "commit -m message + // --allow-empty". + commitArgs := []string{ + "-c", fmt.Sprintf("user.name=%s", writeCommitConfig.committerName), + "-c", fmt.Sprintf("user.email=%s", DefaultCommitterMail), + "-C", repoPath, + "commit-tree", "-F", "-", tree, + } + + var env []string + if writeCommitConfig.alternateObjectDir != "" { + require.True(tb, filepath.IsAbs(writeCommitConfig.alternateObjectDir), + "alternate object directory must be an absolute path") + require.NoError(tb, os.MkdirAll(writeCommitConfig.alternateObjectDir, 0o755)) + + env = append(env, + fmt.Sprintf("GIT_OBJECT_DIRECTORY=%s", writeCommitConfig.alternateObjectDir), + fmt.Sprintf("GIT_ALTERNATE_OBJECT_DIRECTORIES=%s", filepath.Join(repoPath, "objects")), + ) + } + + env = append(env, + fmt.Sprintf("GIT_AUTHOR_DATE=%d %s", writeCommitConfig.authorDate.Unix(), writeCommitConfig.authorDate.Format("-0700")), + fmt.Sprintf("GIT_AUTHOR_NAME=%s", writeCommitConfig.authorName), + fmt.Sprintf("GIT_AUTHOR_EMAIL=%s", DefaultCommitterMail), + fmt.Sprintf("GIT_COMMITTER_DATE=%d %s", writeCommitConfig.committerDate.Unix(), writeCommitConfig.committerDate.Format("-0700")), + fmt.Sprintf("GIT_COMMITTER_NAME=%s", writeCommitConfig.committerName), + fmt.Sprintf("GIT_COMMITTER_EMAIL=%s", DefaultCommitterMail), + ) + + for _, parent := range writeCommitConfig.parents { + commitArgs = append(commitArgs, "-p", parent.String()) + } + + stdout := ExecOpts(tb, cfg, ExecConfig{ + Stdin: stdin, + Env: env, + }, commitArgs...) + oid, err := DefaultObjectHash.FromHex(text.ChompBytes(stdout)) + require.NoError(tb, err) + + if writeCommitConfig.reference != "" { + ExecOpts(tb, cfg, ExecConfig{ + Env: env, + }, "-C", repoPath, "update-ref", writeCommitConfig.reference, oid.String()) + } + + return oid +} + +func authorEqualIgnoringDate(tb testing.TB, expected *gitalypb.CommitAuthor, actual *gitalypb.CommitAuthor) { + tb.Helper() + require.Equal(tb, expected.GetName(), actual.GetName(), "author name does not match") + require.Equal(tb, expected.GetEmail(), actual.GetEmail(), "author mail does not match") +} + +// CommitEqual tests if two `GitCommit`s are equal +func CommitEqual(tb testing.TB, expected, actual *gitalypb.GitCommit) { + tb.Helper() + + authorEqualIgnoringDate(tb, expected.GetAuthor(), actual.GetAuthor()) + authorEqualIgnoringDate(tb, expected.GetCommitter(), actual.GetCommitter()) + require.Equal(tb, expected.GetBody(), actual.GetBody(), "body does not match") + require.Equal(tb, expected.GetSubject(), actual.GetSubject(), "subject does not match") + require.Equal(tb, expected.GetId(), actual.GetId(), "object ID does not match") + require.Equal(tb, expected.GetParentIds(), actual.GetParentIds(), "parent IDs do not match") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit_test.go new file mode 100644 index 0000000000..b4fa49a177 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/commit_test.go @@ -0,0 +1,193 @@ +package gittest + +import ( + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +func TestWriteCommit(t *testing.T) { + cfg, _, repoPath := setup(t) + + treeEntryA := TreeEntry{Path: "file", Mode: "100644", Content: "something"} + + treeA := WriteTree(t, cfg, repoPath, []TreeEntry{treeEntryA}) + treeB := WriteTree(t, cfg, repoPath, []TreeEntry{ + {Path: "file", Mode: "100644", Content: "changed"}, + }) + commitA := WriteCommit(t, cfg, repoPath, WithTree(treeA)) + commitB := WriteCommit(t, cfg, repoPath, WithTree(treeB)) + + for _, tc := range []struct { + desc string + opts []WriteCommitOption + expectedCommit string + expectedTreeEntries []TreeEntry + expectedRevUpdate git.Revision + }{ + { + desc: "no options", + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + }, + { + desc: "with commit message", + opts: []WriteCommitOption{ + WithMessage("my custom message\n\nfoobar\n"), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "my custom message", + "", + "foobar", + }, "\n"), + }, + { + desc: "with author", + opts: []WriteCommitOption{ + WithAuthorName("John Doe"), + WithAuthorDate(time.Date(2005, 4, 7, 15, 13, 13, 0, time.FixedZone("UTC-7", -7*60*60))), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author John Doe 1112911993 -0700", + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + }, + { + desc: "with commiter", + opts: []WriteCommitOption{ + WithCommitterName("John Doe"), + WithCommitterDate(time.Date(2005, 4, 7, 15, 13, 13, 0, time.FixedZone("UTC-7", -7*60*60))), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer John Doe 1112911993 -0700", + "", + "message", + }, "\n"), + }, + { + desc: "with no parents", + opts: []WriteCommitOption{ + WithParents(), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + }, + { + desc: "with multiple parents", + opts: []WriteCommitOption{ + WithParents(commitA, commitB), + }, + expectedCommit: strings.Join([]string{ + "tree " + treeA.String(), + "parent " + commitA.String(), + "parent " + commitB.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + }, + { + desc: "with branch", + opts: []WriteCommitOption{ + WithBranch("foo"), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + expectedRevUpdate: "refs/heads/foo", + }, + { + desc: "with reference", + opts: []WriteCommitOption{ + WithReference("refs/custom/namespace"), + }, + expectedCommit: strings.Join([]string{ + "tree " + DefaultObjectHash.EmptyTreeOID.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + expectedRevUpdate: "refs/custom/namespace", + }, + { + desc: "with tree entry", + opts: []WriteCommitOption{ + WithTreeEntries(treeEntryA), + }, + expectedCommit: strings.Join([]string{ + "tree " + treeA.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + expectedTreeEntries: []TreeEntry{treeEntryA}, + }, + { + desc: "with tree", + opts: []WriteCommitOption{ + WithTree(treeA), + }, + expectedCommit: strings.Join([]string{ + "tree " + treeA.String(), + "author " + DefaultCommitterSignature, + "committer " + DefaultCommitterSignature, + "", + "message", + }, "\n"), + expectedTreeEntries: []TreeEntry{ + { + Content: "something", + Mode: "100644", + Path: "file", + }, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + oid := WriteCommit(t, cfg, repoPath, tc.opts...) + + commit := Exec(t, cfg, "-C", repoPath, "cat-file", "-p", oid.String()) + + require.Equal(t, tc.expectedCommit, text.ChompBytes(commit)) + + if tc.expectedTreeEntries != nil { + RequireTree(t, cfg, repoPath, oid.String(), tc.expectedTreeEntries) + } + + if tc.expectedRevUpdate != "" { + updatedOID := Exec(t, cfg, "-C", repoPath, "rev-parse", tc.expectedRevUpdate.String()) + require.Equal(t, oid, git.ObjectID(text.ChompBytes(updatedOID))) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/delta_islands.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/delta_islands.go new file mode 100644 index 0000000000..485afe95e6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/delta_islands.go @@ -0,0 +1,89 @@ +package gittest + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +// TestDeltaIslands checks whether functions that repack objects in a repository correctly set up +// delta islands. Based on https://github.com/git/git/blob/master/t/t5320-delta-islands.sh. Note +// that this function accepts two different repository paths: one repo to modify that shall grow the +// new references and objects, and one repository that we ultimately end up repacking. In the +// general case these should refer to the same repository, but for object pools these may be the +// pool member and the pool, respectively. +func TestDeltaIslands( + t *testing.T, + cfg config.Cfg, + repoPathToModify string, + repoPathToRepack string, + isPoolRepo bool, + repack func() error, +) { + t.Helper() + + // Create blobs that we expect Git to use delta compression on. + blob1 := strings.Repeat("X", 100000) + blob2 := blob1 + "\nblob 2" + // Create another, third blob that is longer than the second blob. Git prefers the largest + // blob as delta base, which means that it should in theory pick this blob. But we will make + // it reachable via a reference that is not part of the delta island, and thus it should not + // be used as delta base. + badBlob := blob2 + "\nbad blob" + + refsPrefix := "refs" + if isPoolRepo { + // Pool repositories use different references for their delta islands, so we need to + // adapt accordingly. + refsPrefix = git.ObjectPoolRefNamespace + } + + // Make the first two blobs reachable via references that are part of the delta island. + blob1ID := commitBlob(t, cfg, repoPathToModify, refsPrefix+"/heads/branch1", blob1) + blob2ID := commitBlob(t, cfg, repoPathToModify, refsPrefix+"/tags/tag2", blob2) + + // The bad blob will only be reachable via a reference that is not covered by a delta + // island. Because of that it should be excluded from delta chains in the main island. + badBlobID := commitBlob(t, cfg, repoPathToModify, refsPrefix+"/bad/ref3", badBlob) + + // Repack all objects into a single pack so that we can verify that delta chains are built + // by Git as expected. Most notably, we don't use the delta islands here yet and thus the + // delta base for both blob1 and blob2 should be the bad blob. + Exec(t, cfg, "-C", repoPathToModify, "repack", "-ad") + require.Equal(t, badBlobID, deltaBase(t, cfg, repoPathToModify, blob1ID), "expect blob 1 delta base to be bad blob after test setup") + require.Equal(t, badBlobID, deltaBase(t, cfg, repoPathToModify, blob2ID), "expect blob 2 delta base to be bad blob after test setup") + + // Now we run the repacking function provided to us by the caller. We expect it to use delta + // chains, and thus neither of the two blobs should use the bad blob as delta base. + require.NoError(t, repack(), "repack after delta island setup") + require.Equal(t, blob2ID, deltaBase(t, cfg, repoPathToRepack, blob1ID), "blob 1 delta base should be blob 2 after repack") + require.Equal(t, DefaultObjectHash.ZeroOID.String(), deltaBase(t, cfg, repoPathToRepack, blob2ID), "blob 2 should not be delta compressed after repack") +} + +func commitBlob(t *testing.T, cfg config.Cfg, repoPath, ref string, content string) string { + blobID := WriteBlob(t, cfg, repoPath, []byte(content)) + + // No parent, that means this will be an initial commit. Not very + // realistic but it doesn't matter for delta compression. + commitID := WriteCommit(t, cfg, repoPath, + WithTreeEntries(TreeEntry{ + Mode: "100644", OID: blobID, Path: "file", + }), + ) + + Exec(t, cfg, "-C", repoPath, "update-ref", ref, commitID.String()) + + return blobID.String() +} + +func deltaBase(t *testing.T, cfg config.Cfg, repoPath string, blobID string) string { + catfileOut := ExecOpts(t, cfg, ExecConfig{Stdin: strings.NewReader(blobID)}, + "-C", repoPath, "cat-file", "--batch-check=%(deltabase)", + ) + + return text.ChompBytes(catfileOut) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/hashcache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/hashcache.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/hashcache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/hashcache.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/hooks.go similarity index 55% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/hooks.go index d93c7c74b0..7bf13f2600 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/hooks.go @@ -5,19 +5,19 @@ import ( "path/filepath" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) // WriteEnvToCustomHook dumps the env vars that the custom hooks receives to a file -func WriteEnvToCustomHook(t testing.TB, repoPath, hookName string) string { - tempDir := testhelper.TempDir(t) +func WriteEnvToCustomHook(tb testing.TB, repoPath, hookName string) string { + tempDir := testhelper.TempDir(tb) outputPath := filepath.Join(tempDir, "hook.env") hookContent := fmt.Sprintf("#!/bin/sh\n/usr/bin/env >%s\n", outputPath) - WriteCustomHook(t, repoPath, hookName, []byte(hookContent)) + WriteCustomHook(tb, repoPath, hookName, []byte(hookContent)) return outputPath } @@ -26,8 +26,8 @@ func WriteEnvToCustomHook(t testing.TB, repoPath, hookName string) string { // if it can find the object in the quarantine directory. if // GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES were not passed // through correctly to the hooks, it will fail -func WriteCheckNewObjectExistsHook(t testing.TB, repoPath string) { - WriteCustomHook(t, repoPath, "pre-receive", []byte( +func WriteCheckNewObjectExistsHook(tb testing.TB, repoPath string) { + WriteCustomHook(tb, repoPath, "pre-receive", []byte( `#!/bin/sh while read oldrev newrev reference do @@ -37,23 +37,23 @@ func WriteCheckNewObjectExistsHook(t testing.TB, repoPath string) { } // WriteCustomHook writes a hook in the repo/path.git/custom_hooks directory -func WriteCustomHook(t testing.TB, repoPath, name string, content []byte) string { +func WriteCustomHook(tb testing.TB, repoPath, name string, content []byte) string { fullPath := filepath.Join(repoPath, "custom_hooks", name) - testhelper.WriteExecutable(t, fullPath, content) + testhelper.WriteExecutable(tb, fullPath, content) return fullPath } // CaptureHookEnv creates a Git command factory which injects a bogus 'update' Git hook to sniff out // what environment variables get set for hooks. -func CaptureHookEnv(t testing.TB, cfg config.Cfg) (git.CommandFactory, string) { - hooksPath := testhelper.TempDir(t) +func CaptureHookEnv(tb testing.TB, cfg config.Cfg) (git.CommandFactory, string) { + hooksPath := testhelper.TempDir(tb) hookOutputFile := filepath.Join(hooksPath, "hook.env") - testhelper.WriteExecutable(t, filepath.Join(hooksPath, "update"), []byte(fmt.Sprintf( + testhelper.WriteExecutable(tb, filepath.Join(hooksPath, "update"), []byte(fmt.Sprintf( `#!/usr/bin/env bash env | grep -e ^GIT -e ^GL_ >%q `, hookOutputFile))) - return NewCommandFactory(t, cfg, git.WithHooksPath(hooksPath)), hookOutputFile + return NewCommandFactory(tb, cfg, git.WithHooksPath(hooksPath)), hookOutputFile } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/http_server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/http_server.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/http_server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/http_server.go index e578098a59..d55f2987af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/http_server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/http_server.go @@ -10,17 +10,17 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // HTTPServer starts an HTTP server with git-http-backend(1) as CGI handler. The repository is // prepared such that git-http-backend(1) will serve it by creating the "git-daemon-export-ok" magic // file. -func HTTPServer(ctx context.Context, t testing.TB, gitCmdFactory git.CommandFactory, repoPath string, middleware func(http.ResponseWriter, *http.Request, http.Handler)) (int, func() error) { - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "git-daemon-export-ok"), nil, 0o644)) +func HTTPServer(ctx context.Context, tb testing.TB, gitCmdFactory git.CommandFactory, repoPath string, middleware func(http.ResponseWriter, *http.Request, http.Handler)) (int, func() error) { + require.NoError(tb, os.WriteFile(filepath.Join(repoPath, "git-daemon-export-ok"), nil, 0o644)) listener, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(t, err) + require.NoError(tb, err) gitExecEnv := gitCmdFactory.GetExecutionEnvironment(ctx) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory.go similarity index 55% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory.go index 46b06f7218..6c1894fa46 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/intercepting_command_factory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory.go @@ -2,14 +2,15 @@ package gittest import ( "context" + "fmt" "path/filepath" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) var _ git.CommandFactory = &InterceptingCommandFactory{} @@ -19,6 +20,33 @@ var _ git.CommandFactory = &InterceptingCommandFactory{} type InterceptingCommandFactory struct { realCommandFactory git.CommandFactory interceptingCommandFactory git.CommandFactory + interceptVersion bool +} + +type interceptingCommandFactoryConfig struct { + opts []git.ExecCommandFactoryOption + interceptVersion bool +} + +// InterceptingCommandFactoryOption is an option that can be passed to +// NewInterceptingCommandFactory. +type InterceptingCommandFactoryOption func(*interceptingCommandFactoryConfig) + +// WithRealCommandFactoryOptions is an option that allows the caller to pass options to the real +// git.ExecCommandFactory. +func WithRealCommandFactoryOptions(opts ...git.ExecCommandFactoryOption) InterceptingCommandFactoryOption { + return func(cfg *interceptingCommandFactoryConfig) { + cfg.opts = opts + } +} + +// WithInterceptedVersion will cause `GitVersion()` to use the intercepting Git command factory +// instead of the real Git command factory. This allows the caller to explicitly test version +// detection. +func WithInterceptedVersion() InterceptingCommandFactoryOption { + return func(cfg *interceptingCommandFactoryConfig) { + cfg.interceptVersion = true + } } // NewInterceptingCommandFactory creates a new command factory which intercepts Git commands. The @@ -30,21 +58,50 @@ func NewInterceptingCommandFactory( tb testing.TB, cfg config.Cfg, generateScript func(git.ExecutionEnvironment) string, - opts ...git.ExecCommandFactoryOption, + opts ...InterceptingCommandFactoryOption, ) *InterceptingCommandFactory { + var interceptingCommandFactoryCfg interceptingCommandFactoryConfig + for _, opt := range opts { + opt(&interceptingCommandFactoryCfg) + } + // We create two different command factories. The first one will set up the execution // environment such that we can deterministically resolve the Git binary path as well as // required environment variables for both bundled and non-bundled Git. The second one will // then use a separate config which overrides the Git binary path to point to a custom // script supplied by the user. - gitCmdFactory := NewCommandFactory(tb, cfg, opts...) + gitCmdFactory := NewCommandFactory(tb, cfg, interceptingCommandFactoryCfg.opts...) + execEnv := gitCmdFactory.GetExecutionEnvironment(ctx) scriptPath := filepath.Join(testhelper.TempDir(tb), "git") - testhelper.WriteExecutable(tb, scriptPath, []byte(generateScript(gitCmdFactory.GetExecutionEnvironment(ctx)))) + testhelper.WriteExecutable(tb, scriptPath, []byte(generateScript(execEnv))) + + // In case the user requested us to not intercept the Git version we need to write another + // wrapper script. This wrapper script detects whether git-version(1) is executed and, if + // so, instead executes the real Git binary. Otherwise, it executes the Git script as + // provided by the user. + // + // This is required in addition to the interception of `GitVersion()` itself so that calls + // to `interceptingCommandFactory.GitVersion()` also return the correct results whenever the + // factory calls its own `GitVersion()` function. + if !interceptingCommandFactoryCfg.interceptVersion { + wrapperScriptPath := filepath.Join(testhelper.TempDir(tb), "git") + testhelper.WriteExecutable(tb, wrapperScriptPath, []byte(fmt.Sprintf( + `#!/bin/bash + if test "$1" = "version" + then + exec %q "$@" + fi + exec %q "$@" + `, execEnv.BinaryPath, scriptPath))) + + scriptPath = wrapperScriptPath + } return &InterceptingCommandFactory{ realCommandFactory: gitCmdFactory, interceptingCommandFactory: NewCommandFactory(tb, cfg, git.WithGitBinaryPath(scriptPath)), + interceptVersion: interceptingCommandFactoryCfg.interceptVersion, } } @@ -86,5 +143,14 @@ func (f *InterceptingCommandFactory) HooksPath(ctx context.Context) string { // GitVersion returns the Git version as returned by the intercepted command. func (f *InterceptingCommandFactory) GitVersion(ctx context.Context) (git.Version, error) { - return f.interceptingCommandFactory.GitVersion(ctx) + if f.interceptVersion { + return f.interceptingCommandFactory.GitVersion(ctx) + } + return f.realCommandFactory.GitVersion(ctx) +} + +// SidecarGitConfiguration returns the Ruby sidecar Git configuration as computed by the actual Git +// command factory. +func (f *InterceptingCommandFactory) SidecarGitConfiguration(ctx context.Context) ([]git.ConfigPair, error) { + return f.interceptingCommandFactory.SidecarGitConfiguration(ctx) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory_test.go new file mode 100644 index 0000000000..d93f68afcf --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/intercepting_command_factory_test.go @@ -0,0 +1,124 @@ +package gittest + +import ( + "bytes" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestInterceptingCommandFactory(t *testing.T) { + cfg, repoProto, repoPath := setup(t) + ctx := testhelper.Context(t) + + factory := NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf( + `#!/usr/bin/env bash + %q rev-parse --sq-quote 'Hello, world!' + `, execEnv.BinaryPath) + }) + expectedString := " 'Hello, world'\\!''\n" + + t.Run("New", func(t *testing.T) { + var stdout bytes.Buffer + cmd, err := factory.New(ctx, repoProto, git.SubCmd{ + Name: "rev-parse", + Args: []string{"something"}, + }, git.WithStdout(&stdout)) + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + require.Equal(t, expectedString, stdout.String()) + }) + + t.Run("NewWithDir", func(t *testing.T) { + var stdout bytes.Buffer + cmd, err := factory.NewWithDir(ctx, repoPath, git.SubCmd{ + Name: "rev-parse", + Args: []string{"something"}, + }, git.WithStdout(&stdout)) + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + require.Equal(t, expectedString, stdout.String()) + }) + + t.Run("NewWithoutRepo", func(t *testing.T) { + var stdout bytes.Buffer + cmd, err := factory.NewWithoutRepo(ctx, git.SubCmd{ + Name: "rev-parse", + Args: []string{"something"}, + Flags: []git.Option{ + git.ValueFlag{Name: "-C", Value: repoPath}, + }, + }, git.WithStdout(&stdout)) + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + require.Equal(t, expectedString, stdout.String()) + }) +} + +func TestInterceptingCommandFactory_GitVersion(t *testing.T) { + cfg, _, _ := setup(t) + ctx := testhelper.Context(t) + + generateVersionScript := func(execEnv git.ExecutionEnvironment) string { + return `#!/usr/bin/env bash + echo "git version 1.2.3" + ` + } + + // Obtain the real Git version so that we can compare that it matches what we expect. + realFactory, cleanup, err := git.NewExecCommandFactory(cfg) + require.NoError(t, err) + defer cleanup() + + realVersion, err := realFactory.GitVersion(ctx) + require.NoError(t, err) + + // Furthermore, we need to obtain the intercepted version here because we cannot construct + // `git.Version` structs ourselves. + fakeVersion, err := NewInterceptingCommandFactory(ctx, t, cfg, generateVersionScript, WithInterceptedVersion()).GitVersion(ctx) + require.NoError(t, err) + require.Equal(t, "1.2.3", fakeVersion.String()) + + for _, tc := range []struct { + desc string + opts []InterceptingCommandFactoryOption + expectedVersion git.Version + }{ + { + desc: "without version interception", + expectedVersion: realVersion, + }, + { + desc: "with version interception", + opts: []InterceptingCommandFactoryOption{ + WithInterceptedVersion(), + }, + expectedVersion: fakeVersion, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + factory := NewInterceptingCommandFactory(ctx, t, cfg, generateVersionScript, tc.opts...) + + version, err := factory.GitVersion(ctx) + require.NoError(t, err) + require.Equal(t, tc.expectedVersion, version) + + // The real command factory should always return the real Git version. + version, err = factory.realCommandFactory.GitVersion(ctx) + require.NoError(t, err) + require.Equal(t, realVersion, version) + + // On the other hand, the intercepting command factory should return + // different versions depending on whether the version is intercepted or + // not. This is required such that it correctly handles version checks in + // case it calls `GitVersion()` on itself. + version, err = factory.interceptingCommandFactory.GitVersion(ctx) + require.NoError(t, err) + require.Equal(t, tc.expectedVersion, version) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/objects.go new file mode 100644 index 0000000000..d7499868fa --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/objects.go @@ -0,0 +1,88 @@ +package gittest + +import ( + "bytes" + "os/exec" + "path/filepath" + "strconv" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +// ObjectHashIsSHA256 returns if the current default object hash is SHA256. +func ObjectHashIsSHA256() bool { + return DefaultObjectHash.EmptyTreeOID == git.ObjectHashSHA256.EmptyTreeOID +} + +// RequireObjectExists asserts that the given repository does contain an object with the specified +// object ID. +func RequireObjectExists(tb testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID) { + requireObjectExists(tb, cfg, repoPath, objectID, true) +} + +// RequireObjectNotExists asserts that the given repository does not contain an object with the +// specified object ID. +func RequireObjectNotExists(tb testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID) { + requireObjectExists(tb, cfg, repoPath, objectID, false) +} + +func requireObjectExists(tb testing.TB, cfg config.Cfg, repoPath string, objectID git.ObjectID, exists bool) { + cmd := NewCommand(tb, cfg, "-C", repoPath, "cat-file", "-e", objectID.String()) + cmd.Env = []string{ + "GIT_ALLOW_PROTOCOL=", // To prevent partial clone reaching remote repo over SSH + } + + if exists { + require.NoError(tb, cmd.Run(), "checking for object should succeed") + return + } + require.Error(tb, cmd.Run(), "checking for object should fail") +} + +// GetGitPackfileDirSize gets the number of 1k blocks of a git object directory +func GetGitPackfileDirSize(tb testing.TB, repoPath string) int64 { + return getGitDirSize(tb, repoPath, "objects", "pack") +} + +func getGitDirSize(tb testing.TB, repoPath string, subdirs ...string) int64 { + cmd := exec.Command("du", "-s", "-k", filepath.Join(append([]string{repoPath}, subdirs...)...)) + output, err := cmd.Output() + require.NoError(tb, err) + if len(output) < 2 { + tb.Error("invalid output of du -s -k") + } + + outputSplit := strings.SplitN(string(output), "\t", 2) + blocks, err := strconv.ParseInt(outputSplit[0], 10, 64) + require.NoError(tb, err) + + return blocks +} + +// WriteBlobs writes n distinct blobs into the git repository's object +// database. Each object has the current time in nanoseconds as contents. +func WriteBlobs(tb testing.TB, cfg config.Cfg, testRepoPath string, n int) []string { + var blobIDs []string + for i := 0; i < n; i++ { + contents := []byte(strconv.Itoa(time.Now().Nanosecond())) + blobIDs = append(blobIDs, WriteBlob(tb, cfg, testRepoPath, contents).String()) + } + + return blobIDs +} + +// WriteBlob writes the given contents as a blob into the repository and returns its OID. +func WriteBlob(tb testing.TB, cfg config.Cfg, testRepoPath string, contents []byte) git.ObjectID { + hex := text.ChompBytes(ExecOpts(tb, cfg, ExecConfig{Stdin: bytes.NewReader(contents)}, + "-C", testRepoPath, "hash-object", "-w", "--stdin", + )) + oid, err := DefaultObjectHash.FromHex(hex) + require.NoError(tb, err) + return oid +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/pktline.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/pktline.go new file mode 100644 index 0000000000..622719b343 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/pktline.go @@ -0,0 +1,47 @@ +package gittest + +import ( + "fmt" + "io" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" +) + +// Pktlinef formats the given formatting string into a pktline. +func Pktlinef(t *testing.T, format string, a ...interface{}) string { + t.Helper() + var builder strings.Builder + _, err := pktline.WriteString(&builder, fmt.Sprintf(format, a...)) + require.NoError(t, err) + return builder.String() +} + +// WritePktlineString writes the pktline-formatted data into the writer. +func WritePktlineString(t *testing.T, writer io.Writer, data string) { + t.Helper() + _, err := pktline.WriteString(writer, data) + require.NoError(t, err) +} + +// WritePktlinef formats the given format string and writes the pktline-formatted data into the +// writer. +func WritePktlinef(t *testing.T, writer io.Writer, format string, args ...interface{}) { + t.Helper() + _, err := pktline.WriteString(writer, fmt.Sprintf(format, args...)) + require.NoError(t, err) +} + +// WritePktlineFlush writes the pktline-formatted flush into the writer. +func WritePktlineFlush(t *testing.T, writer io.Writer) { + t.Helper() + require.NoError(t, pktline.WriteFlush(writer)) +} + +// WritePktlineDelim writes the pktline-formatted delimiter into the writer. +func WritePktlineDelim(t *testing.T, writer io.Writer) { + t.Helper() + require.NoError(t, pktline.WriteDelim(writer)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/protocol.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/protocol.go new file mode 100644 index 0000000000..a47f33ec1a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/protocol.go @@ -0,0 +1,51 @@ +package gittest + +import ( + "context" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +// ProtocolDetectingCommandFactory is an intercepting Git command factory that allows the protocol +// to be tested. +type ProtocolDetectingCommandFactory struct { + git.CommandFactory + envPath string +} + +// NewProtocolDetectingCommandFactory returns a new ProtocolDetectingCommandFactory. +func NewProtocolDetectingCommandFactory(ctx context.Context, tb testing.TB, cfg config.Cfg) ProtocolDetectingCommandFactory { + envPath := filepath.Join(testhelper.TempDir(tb), "git-env") + + gitCmdFactory := NewInterceptingCommandFactory(ctx, tb, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf( + `#!/usr/bin/env bash + env | grep ^GIT_PROTOCOL= >>%q + exec %q "$@" + `, envPath, execEnv.BinaryPath) + }) + + return ProtocolDetectingCommandFactory{ + CommandFactory: gitCmdFactory, + envPath: envPath, + } +} + +// ReadProtocol reads the protocol used by previous Git executions. +func (p *ProtocolDetectingCommandFactory) ReadProtocol(t *testing.T) string { + data, err := os.ReadFile(p.envPath) + require.NoError(t, err) + return string(data) +} + +// Reset resets previously recorded protocols. +func (p *ProtocolDetectingCommandFactory) Reset(t *testing.T) { + require.NoError(t, os.RemoveAll(p.envPath)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref.go new file mode 100644 index 0000000000..cf9757fde2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref.go @@ -0,0 +1,24 @@ +package gittest + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +// WriteRef writes a reference into the repository pointing to the given object ID. +func WriteRef(tb testing.TB, cfg config.Cfg, repoPath string, ref git.ReferenceName, oid git.ObjectID) { + Exec(tb, cfg, "-C", repoPath, "update-ref", ref.String(), oid.String()) +} + +// ResolveRevision resolves the revision to an object ID. +func ResolveRevision(tb testing.TB, cfg config.Cfg, repoPath string, revision string) git.ObjectID { + tb.Helper() + output := Exec(tb, cfg, "-C", repoPath, "rev-parse", "--verify", revision) + objectID, err := DefaultObjectHash.FromHex(text.ChompBytes(output)) + require.NoError(tb, err) + return objectID +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref_test.go new file mode 100644 index 0000000000..afbf5c6b14 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/ref_test.go @@ -0,0 +1,16 @@ +package gittest + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" +) + +func TestResolveRevision(t *testing.T) { + cfg, _, repoPath := setup(t) + + commitID := WriteCommit(t, cfg, repoPath, WithBranch(git.DefaultBranch)) + + require.Equal(t, commitID, ResolveRevision(t, cfg, repoPath, git.DefaultBranch)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/remote.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/remote.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/remote.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/remote.go index 771315f13e..c3d5ea8e46 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/remote.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/remote.go @@ -4,16 +4,16 @@ import ( "strings" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" ) // RemoteExists tests if the repository at repoPath has a Git remote named remoteName. -func RemoteExists(t testing.TB, cfg config.Cfg, repoPath string, remoteName string) bool { +func RemoteExists(tb testing.TB, cfg config.Cfg, repoPath string, remoteName string) bool { if remoteName == "" { - t.Fatal("empty remote name") + tb.Fatal("empty remote name") } - remotes := Exec(t, cfg, "-C", repoPath, "remote") + remotes := Exec(tb, cfg, "-C", repoPath, "remote") for _, r := range strings.Split(string(remotes), "\n") { if r == remoteName { return true diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repo.go new file mode 100644 index 0000000000..0086fcad0d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repo.go @@ -0,0 +1,363 @@ +package gittest + +import ( + "bytes" + "context" + "crypto/sha256" + "os" + "path/filepath" + "runtime" + "testing" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +const ( + // GlRepository is the default repository name for newly created test + // repos. + GlRepository = "project-1" + // GlProjectPath is the default project path for newly created test + // repos. + GlProjectPath = "gitlab-org/gitlab-test" + + // SeedGitLabTest is the path of the gitlab-test.git repository in _build/testrepos + SeedGitLabTest = "gitlab-test.git" + + // SeedGitLabTestMirror is the path of the gitlab-test-mirror.git repository in _build/testrepos + SeedGitLabTestMirror = "gitlab-test-mirror.git" +) + +// InitRepoDir creates a temporary directory for a repo, without initializing it +func InitRepoDir(tb testing.TB, storagePath, relativePath string) *gitalypb.Repository { + repoPath := filepath.Join(storagePath, relativePath, "..") + require.NoError(tb, os.MkdirAll(repoPath, 0o755), "making repo parent dir") + return &gitalypb.Repository{ + StorageName: "default", + RelativePath: relativePath, + GlRepository: GlRepository, + GlProjectPath: GlProjectPath, + } +} + +// NewObjectPoolName returns a random pool repository name in format +// '@pools/[0-9a-z]{2}/[0-9a-z]{2}/[0-9a-z]{64}.git'. +func NewObjectPoolName(tb testing.TB) string { + return filepath.Join("@pools", newDiskHash(tb)+".git") +} + +// NewRepositoryName returns a random repository hash +// in format '@hashed/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{64}(.git)?'. +func NewRepositoryName(tb testing.TB, bare bool) string { + suffix := "" + if bare { + suffix = ".git" + } + + return filepath.Join("@hashed", newDiskHash(tb)+suffix) +} + +// newDiskHash generates a random directory path following the Rails app's +// approach in the hashed storage module, formatted as '[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{64}'. +// https://gitlab.com/gitlab-org/gitlab/-/blob/f5c7d8eb1dd4eee5106123e04dec26d277ff6a83/app/models/storage/hashed.rb#L38-43 +func newDiskHash(tb testing.TB) string { + // rails app calculates a sha256 and uses its hex representation + // as the directory path + b, err := text.RandomHex(sha256.Size) + require.NoError(tb, err) + return filepath.Join(b[0:2], b[2:4], b) +} + +// CreateRepositoryConfig allows for configuring how the repository is created. +type CreateRepositoryConfig struct { + // ClientConn is the connection used to create the repository. If unset, the config is used to + // dial the service. + ClientConn *grpc.ClientConn + // Storage determines the storage the repository is created in. If unset, the first storage + // from the config is used. + Storage config.Storage + // RelativePath sets the relative path of the repository in the storage. If unset, + // the relative path is set to a randomly generated hashed storage path + RelativePath string + // Seed determines which repository is used to seed the created repository. If unset, the repository + // is just created. The value should be one of the test repositories in _build/testrepos. + Seed string + // SkipCreationViaService skips creation of the repository by calling the respective RPC call. + // In general, this should not be skipped so that we end up in a state that is consistent + // and expected by both Gitaly and Praefect. It may be required though when testing at a + // level where there are no gRPC services available. + SkipCreationViaService bool + // ObjectFormat overrides the object format used by the repository. + ObjectFormat string +} + +func dialService(ctx context.Context, tb testing.TB, cfg config.Cfg) *grpc.ClientConn { + dialOptions := []grpc.DialOption{internalclient.UnaryInterceptor(), internalclient.StreamInterceptor()} + if cfg.Auth.Token != "" { + dialOptions = append(dialOptions, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token))) + } + + conn, err := client.DialContext(ctx, cfg.SocketPath, dialOptions) + require.NoError(tb, err) + return conn +} + +// CreateRepository creates a new repository and returns it and its absolute path. +func CreateRepository(ctx context.Context, tb testing.TB, cfg config.Cfg, configs ...CreateRepositoryConfig) (*gitalypb.Repository, string) { + tb.Helper() + + require.Less(tb, len(configs), 2, "you must either pass no or exactly one option") + + opts := CreateRepositoryConfig{} + if len(configs) == 1 { + opts = configs[0] + } + + if ObjectHashIsSHA256() || opts.ObjectFormat != "" { + require.Empty(tb, opts.Seed, "seeded repository creation not supported with non-default object format") + require.True(tb, opts.SkipCreationViaService, "repository creation via service not supported with non-default object format") + } + + storage := cfg.Storages[0] + if (opts.Storage != config.Storage{}) { + storage = opts.Storage + } + + relativePath := NewRepositoryName(tb, true) + if opts.RelativePath != "" { + relativePath = opts.RelativePath + } + + repository := &gitalypb.Repository{ + StorageName: storage.Name, + RelativePath: relativePath, + GlRepository: GlRepository, + GlProjectPath: GlProjectPath, + } + + var repoPath string + if !opts.SkipCreationViaService { + conn := opts.ClientConn + if conn == nil { + conn = dialService(ctx, tb, cfg) + tb.Cleanup(func() { testhelper.MustClose(tb, conn) }) + } + client := gitalypb.NewRepositoryServiceClient(conn) + + if opts.Seed != "" { + _, err := client.CreateRepositoryFromURL(ctx, &gitalypb.CreateRepositoryFromURLRequest{ + Repository: repository, + Url: testRepositoryPath(tb, opts.Seed), + Mirror: true, + }) + require.NoError(tb, err) + } else { + _, err := client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{ + Repository: repository, + }) + require.NoError(tb, err) + } + + tb.Cleanup(func() { + // The ctx parameter would be canceled by now as the tests defer the cancellation. + _, err := client.RemoveRepository(context.TODO(), &gitalypb.RemoveRepositoryRequest{ + Repository: repository, + }) + + if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { + // The tests may delete the repository, so this is not a failure. + return + } + + require.NoError(tb, err) + }) + + repoPath = filepath.Join(storage.Path, getReplicaPath(ctx, tb, conn, repository)) + } else { + repoPath = filepath.Join(storage.Path, repository.RelativePath) + + if opts.Seed != "" { + Exec(tb, cfg, "clone", "--no-hardlinks", "--dissociate", "--bare", testRepositoryPath(tb, opts.Seed), repoPath) + Exec(tb, cfg, "-C", repoPath, "remote", "remove", "origin") + } else { + args := []string{"init", "--bare"} + args = append(args, initRepoExtraArgs...) + args = append(args, repoPath) + if opts.ObjectFormat != "" { + args = append(args, "--object-format", opts.ObjectFormat) + } + + Exec(tb, cfg, args...) + } + + tb.Cleanup(func() { require.NoError(tb, os.RemoveAll(repoPath)) }) + } + + // Return a cloned repository so the above clean up function still targets the correct repository + // if the tests modify the returned repository. + clonedRepo := proto.Clone(repository).(*gitalypb.Repository) + + return clonedRepo, repoPath +} + +// GetReplicaPathConfig allows for configuring the GetReplicaPath call. +type GetReplicaPathConfig struct { + // ClientConn is the connection used to create the repository. If unset, the config is used to + // dial the service. + ClientConn *grpc.ClientConn +} + +// GetReplicaPath retrieves the repository's replica path if the test has been +// run with Praefect in front of it. This is necessary if the test creates a repository +// through Praefect and peeks into the filesystem afterwards. Conn should be pointing to +// Praefect. +func GetReplicaPath(ctx context.Context, tb testing.TB, cfg config.Cfg, repo repository.GitRepo, opts ...GetReplicaPathConfig) string { + require.Less(tb, len(opts), 2, "you must either pass no or exactly one option") + + var opt GetReplicaPathConfig + if len(opts) > 0 { + opt = opts[0] + } + + conn := opt.ClientConn + if conn == nil { + conn = dialService(ctx, tb, cfg) + defer conn.Close() + } + + return getReplicaPath(ctx, tb, conn, repo) +} + +func getReplicaPath(ctx context.Context, tb testing.TB, conn *grpc.ClientConn, repo repository.GitRepo) string { + metadata, err := gitalypb.NewPraefectInfoServiceClient(conn).GetRepositoryMetadata( + ctx, &gitalypb.GetRepositoryMetadataRequest{ + Query: &gitalypb.GetRepositoryMetadataRequest_Path_{ + Path: &gitalypb.GetRepositoryMetadataRequest_Path{ + VirtualStorage: repo.GetStorageName(), + RelativePath: repo.GetRelativePath(), + }, + }, + }) + if status, ok := status.FromError(err); ok && status.Code() == codes.Unimplemented && status.Message() == "unknown service gitaly.PraefectInfoService" { + // The repository is stored at relative path if the test is running without Praefect in front. + return repo.GetRelativePath() + } + require.NoError(tb, err) + + return metadata.ReplicaPath +} + +// RewrittenRepository returns the repository as it would be received by a Gitaly after being rewritten by Praefect. +// This should be used when the repository is being accessed through the filesystem to ensure the access path is +// correct. If the test is not running with Praefect in front, it returns the an unaltered copy of repository. +func RewrittenRepository(ctx context.Context, tb testing.TB, cfg config.Cfg, repository *gitalypb.Repository) *gitalypb.Repository { + // Don'tb modify the original repository. + rewritten := proto.Clone(repository).(*gitalypb.Repository) + rewritten.RelativePath = GetReplicaPath(ctx, tb, cfg, repository) + return rewritten +} + +// BundleRepo creates a bundle of a repository. `patterns` define the bundle contents as per +// `git-rev-list-args`. If there are no patterns then `--all` is assumed. +func BundleRepo(tb testing.TB, cfg config.Cfg, repoPath, bundlePath string, patterns ...string) { + if len(patterns) == 0 { + patterns = []string{"--all"} + } + Exec(tb, cfg, append([]string{"-C", repoPath, "bundle", "create", bundlePath}, patterns...)...) +} + +// ChecksumRepo calculates the checksum of a repository. +func ChecksumRepo(tb testing.TB, cfg config.Cfg, repoPath string) *git.Checksum { + var checksum git.Checksum + lines := bytes.Split(Exec(tb, cfg, "-C", repoPath, "show-ref", "--head"), []byte("\n")) + for _, line := range lines { + checksum.AddBytes(line) + } + return &checksum +} + +// testRepositoryPath returns the absolute path of local 'gitlab-org/gitlab-test.git' clone. +// It is cloned under the path by the test preparing step of make. +func testRepositoryPath(tb testing.TB, repo string) string { + _, currentFile, _, ok := runtime.Caller(0) + if !ok { + require.Fail(tb, "could not get caller info") + } + + path := filepath.Join(filepath.Dir(currentFile), "..", "..", "..", "_build", "testrepos", repo) + if !isValidRepoPath(path) { + makePath := filepath.Join(filepath.Dir(currentFile), "..", "..", "..") + makeTarget := "prepare-test-repos" + log.Printf("local clone of test repository %q not found in %q, running `make %v`", repo, path, makeTarget) + testhelper.MustRunCommand(tb, nil, "make", "-C", makePath, makeTarget) + } + + return path +} + +// isValidRepoPath checks whether a valid git repository exists at the given path. +func isValidRepoPath(absolutePath string) bool { + if _, err := os.Stat(filepath.Join(absolutePath, "objects")); err != nil { + return false + } + + return true +} + +// AddWorktreeArgs returns git command arguments for adding a worktree at the +// specified repo +func AddWorktreeArgs(repoPath, worktreeName string) []string { + return []string{"-C", repoPath, "worktree", "add", "--detach", worktreeName} +} + +// AddWorktree creates a worktree in the repository path for tests +func AddWorktree(tb testing.TB, cfg config.Cfg, repoPath string, worktreeName string) { + Exec(tb, cfg, AddWorktreeArgs(repoPath, worktreeName)...) +} + +// FixGitLabTestRepoForCommitGraphs fixes the "gitlab-test.git" repository so that it can be used in +// the context of commit-graphs. The test repository contains the commit ba3343b (Weird commit date, +// 292278994-08-17). As you can already see, this commit has a commit year of 292278994, which is +// not exactly a realistic commit date to have in normal repositories. Unfortunately, this commit +// date causes commit-graphs to become corrupt with the following error that's likely caused by +// an overflow: +// +// commit date for commit ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69 in commit-graph is 15668040695 != 9223372036854775 +// +// This is not a new error, but something that has existed for quite a while already in Git. And +// while the bug can also be easily hit in Gitaly because we do write commit-graphs in pool +// repositories, until now we haven't because we never exercised this. +// +// Unfortunately, we're between a rock and a hard place: this error will be hit when running +// git-fsck(1) to find dangling objects, which we do to rescue objects. git-fsck(1) will by default +// verify the commit-graphs to be consistent even with `--connectivity-only`, which causes the +// error. But while we could in theory just disable the usage of commit-graphs by passing +// `core.commitGraph=0`, the end result would be that the connectivity check itself may become a lot +// slower. +// +// So for now we just bail on this whole topic: it's not a new bug and we can't do much about it +// given it could regress performance. The pool members would be broken in the same way, even though +// less visibly so because we don't git-fsck(1) in "normal" RPCs. But to make our tests work we +// delete the reference for this specific commit so that it doesn't cause our tests to break. +// +// You can easily test whether this bug still exists via the following commands: +// +// $ git clone _build/testrepos/gitlab-test.git +// $ git -C gitlab-test commit-graph write +// $ git -C gitlab-test commit-graph verify +func FixGitLabTestRepoForCommitGraphs(tb testing.TB, cfg config.Cfg, repoPath string) { + Exec(tb, cfg, "-C", repoPath, "update-ref", "-d", "refs/heads/spooky-stuff", "ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repository_suite.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repository_suite.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repository_suite.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repository_suite.go index 9fe27eaaa8..5052795989 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/repository_suite.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/repository_suite.go @@ -5,15 +5,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) // GetRepositoryFunc is used to get a clean test repository for the different implementations of the // Repository interface in the common test suite TestRepository. -type GetRepositoryFunc func(ctx context.Context, t testing.TB, seeded bool) (git.Repository, string) +type GetRepositoryFunc func(ctx context.Context, t testing.TB) (git.Repository, string) // TestRepository tests an implementation of Repository. func TestRepository(t *testing.T, cfg config.Cfg, getRepository GetRepositoryFunc) { @@ -43,6 +43,12 @@ func TestRepository(t *testing.T, cfg config.Cfg, getRepository GetRepositoryFun func testRepositoryResolveRevision(t *testing.T, cfg config.Cfg, getRepository GetRepositoryFunc) { ctx := testhelper.Context(t) + repo, repoPath := getRepository(ctx, t) + + firstParentCommitID := WriteCommit(t, cfg, repoPath, WithMessage("first parent")) + secondParentCommitID := WriteCommit(t, cfg, repoPath, WithMessage("second parent")) + masterCommitID := WriteCommit(t, cfg, repoPath, WithBranch("master"), WithParents(firstParentCommitID, secondParentCommitID)) + for _, tc := range []struct { desc string revision string @@ -51,22 +57,22 @@ func testRepositoryResolveRevision(t *testing.T, cfg config.Cfg, getRepository G { desc: "unqualified master branch", revision: "master", - expected: "1e292f8fedd741b75372e19097c76d327140c312", + expected: masterCommitID, }, { desc: "fully qualified master branch", revision: "refs/heads/master", - expected: "1e292f8fedd741b75372e19097c76d327140c312", + expected: masterCommitID, }, { desc: "typed commit", revision: "refs/heads/master^{commit}", - expected: "1e292f8fedd741b75372e19097c76d327140c312", + expected: masterCommitID, }, { desc: "extended SHA notation", revision: "refs/heads/master^2", - expected: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", + expected: secondParentCommitID, }, { desc: "nonexistent branch", @@ -78,7 +84,6 @@ func testRepositoryResolveRevision(t *testing.T, cfg config.Cfg, getRepository G }, } { t.Run(tc.desc, func(t *testing.T) { - repo, _ := getRepository(ctx, t, true) oid, err := repo.ResolveRevision(ctx, git.Revision(tc.revision)) if tc.expected == "" { require.Equal(t, err, git.ErrReferenceNotFound) @@ -94,9 +99,9 @@ func testRepositoryResolveRevision(t *testing.T, cfg config.Cfg, getRepository G func testRepositoryHasBranches(t *testing.T, cfg config.Cfg, getRepository GetRepositoryFunc) { ctx := testhelper.Context(t) - repo, repoPath := getRepository(ctx, t, false) + repo, repoPath := getRepository(ctx, t) - emptyCommit := text.ChompBytes(Exec(t, cfg, "-C", repoPath, "commit-tree", git.EmptyTreeOID.String())) + emptyCommit := text.ChompBytes(Exec(t, cfg, "-C", repoPath, "commit-tree", DefaultObjectHash.EmptyTreeOID.String())) Exec(t, cfg, "-C", repoPath, "update-ref", "refs/headsbranch", emptyCommit) @@ -112,7 +117,6 @@ func testRepositoryHasBranches(t *testing.T, cfg config.Cfg, getRepository GetRe } func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository GetRepositoryFunc) { - const testOID = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" ctx := testhelper.Context(t) for _, tc := range []struct { @@ -123,8 +127,8 @@ func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository { desc: "default ref", repo: func(t *testing.T) git.Repository { - repo, repoPath := getRepository(ctx, t, false) - oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + repo, repoPath := getRepository(ctx, t) + oid := WriteCommit(t, cfg, repoPath, WithBranch("apple")) WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("main")) return repo }, @@ -133,8 +137,8 @@ func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository { desc: "legacy default ref", repo: func(t *testing.T) git.Repository { - repo, repoPath := getRepository(ctx, t, false) - oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + repo, repoPath := getRepository(ctx, t) + oid := WriteCommit(t, cfg, repoPath, WithBranch("apple")) WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("master")) return repo }, @@ -143,15 +147,15 @@ func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository { desc: "no branches", repo: func(t *testing.T) git.Repository { - repo, _ := getRepository(ctx, t, false) + repo, _ := getRepository(ctx, t) return repo }, }, { desc: "one branch", repo: func(t *testing.T) git.Repository { - repo, repoPath := getRepository(ctx, t, false) - WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + repo, repoPath := getRepository(ctx, t) + WriteCommit(t, cfg, repoPath, WithBranch("apple")) return repo }, expectedName: git.NewReferenceNameFromBranchName("apple"), @@ -159,27 +163,21 @@ func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository { desc: "no default branches", repo: func(t *testing.T) git.Repository { - repo, repoPath := getRepository(ctx, t, false) - oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + repo, repoPath := getRepository(ctx, t) + oid := WriteCommit(t, cfg, repoPath, WithBranch("apple")) WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("banana")) return repo }, expectedName: git.NewReferenceNameFromBranchName("apple"), }, - { - desc: "test repo default", - repo: func(t *testing.T) git.Repository { - repo, _ := getRepository(ctx, t, true) - return repo - }, - expectedName: git.LegacyDefaultRef, - }, { desc: "test repo HEAD set", repo: func(t *testing.T) git.Repository { - repo, repoPath := getRepository(ctx, t, true) - Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/feature", testOID) + repo, repoPath := getRepository(ctx, t) + + WriteCommit(t, cfg, repoPath, WithBranch("feature")) Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/feature") + return repo }, expectedName: git.NewReferenceNameFromBranchName("feature"), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha1.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha1.go new file mode 100644 index 0000000000..4a5d8de33a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha1.go @@ -0,0 +1,12 @@ +//go:build !gitaly_test_sha256 + +package gittest + +import "gitlab.com/gitlab-org/gitaly/v15/internal/git" + +var ( + // DefaultObjectHash is the default hash used for running tests. + DefaultObjectHash = git.ObjectHashSHA1 + + initRepoExtraArgs = []string{} +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha256.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha256.go new file mode 100644 index 0000000000..d571657a93 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/sha256.go @@ -0,0 +1,14 @@ +//go:build gitaly_test_sha256 + +package gittest + +import ( + "gitlab.com/gitlab-org/gitaly/v15/internal/git" +) + +var ( + // DefaultObjectHash is the default hash used for running tests. + DefaultObjectHash = git.ObjectHashSHA256 + + initRepoExtraArgs = []string{"--object-format=sha256"} +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tag.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tag.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tag.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tag.go index de240eb057..a5691b3f4d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tag.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tag.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" ) // WriteTagConfig holds extra options for WriteTag. @@ -25,27 +25,24 @@ type WriteTagConfig struct { // created. Takes either no WriteTagConfig, in which case the default values will be used, or // exactly one. func WriteTag( - t testing.TB, + tb testing.TB, cfg config.Cfg, repoPath string, tagName string, targetRevision git.Revision, optionalConfig ...WriteTagConfig, ) git.ObjectID { - require.Less(t, len(optionalConfig), 2, "only a single config may be passed") + require.Less(tb, len(optionalConfig), 2, "only a single config may be passed") var config WriteTagConfig if len(optionalConfig) == 1 { config = optionalConfig[0] } - committerName := "Scrooge McDuck" - committerEmail := "scrooge@mcduck.com" - args := []string{ "-C", repoPath, - "-c", fmt.Sprintf("user.name=%s", committerName), - "-c", fmt.Sprintf("user.email=%s", committerEmail), + "-c", fmt.Sprintf("user.name=%s", DefaultCommitterName), + "-c", fmt.Sprintf("user.email=%s", DefaultCommitterMail), "tag", } @@ -60,12 +57,12 @@ func WriteTag( } args = append(args, tagName, targetRevision.String()) - ExecOpts(t, cfg, ExecConfig{Stdin: stdin}, args...) + ExecOpts(tb, cfg, ExecConfig{Stdin: stdin}, args...) - tagID := Exec(t, cfg, "-C", repoPath, "show-ref", "-s", tagName) + tagID := Exec(tb, cfg, "-C", repoPath, "show-ref", "-s", tagName) - objectID, err := git.NewObjectIDFromHex(text.ChompBytes(tagID)) - require.NoError(t, err) + objectID, err := DefaultObjectHash.FromHex(text.ChompBytes(tagID)) + require.NoError(tb, err) return objectID } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testdata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testdata.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testdata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testdata.go index 31dd46e9be..18fb6bb373 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/testdata.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testdata.go @@ -1,7 +1,7 @@ package gittest import ( - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testhelper_test.go new file mode 100644 index 0000000000..a477adc669 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/testhelper_test.go @@ -0,0 +1,61 @@ +package gittest + +import ( + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +// setup sets up a test configuration and repository. Ideally we'd use our central test helpers to +// do this, but because of an import cycle we can't. +func setup(tb testing.TB) (config.Cfg, *gitalypb.Repository, string) { + tb.Helper() + + rootDir := testhelper.TempDir(tb) + + ctx := testhelper.Context(tb) + var cfg config.Cfg + + cfg.SocketPath = "it is a stub to bypass Validate method" + cfg.Git.IgnoreGitconfig = true + + cfg.Storages = []config.Storage{ + { + Name: "default", + Path: filepath.Join(rootDir, "storage.d"), + }, + } + require.NoError(tb, os.Mkdir(cfg.Storages[0].Path, 0o755)) + + _, currentFile, _, ok := runtime.Caller(0) + require.True(tb, ok, "could not get caller info") + cfg.Ruby.Dir = filepath.Join(filepath.Dir(currentFile), "../../../ruby") + + cfg.GitlabShell.Dir = filepath.Join(rootDir, "shell.d") + require.NoError(tb, os.Mkdir(cfg.GitlabShell.Dir, 0o755)) + + cfg.BinDir = filepath.Join(rootDir, "bin.d") + require.NoError(tb, os.Mkdir(cfg.BinDir, 0o755)) + + cfg.RuntimeDir = filepath.Join(rootDir, "run.d") + require.NoError(tb, os.Mkdir(cfg.RuntimeDir, 0o700)) + require.NoError(tb, os.Mkdir(cfg.InternalSocketDir(), 0o700)) + + require.NoError(tb, cfg.Validate()) + + repo, repoPath := CreateRepository(ctx, tb, cfg, CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + return cfg, repo, repoPath +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree.go index 8895a414b6..6a45a99b24 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree.go @@ -2,15 +2,14 @@ package gittest import ( "bytes" - "crypto/sha1" "encoding/hex" "fmt" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" ) // TreeEntry represents an entry of a git tree object. @@ -27,8 +26,8 @@ type TreeEntry struct { // RequireTree looks up the given treeish and asserts that its entries match // the given expected entries. Tree entries are checked recursively. -func RequireTree(t testing.TB, cfg config.Cfg, repoPath, treeish string, expectedEntries []TreeEntry) { - t.Helper() +func RequireTree(tb testing.TB, cfg config.Cfg, repoPath, treeish string, expectedEntries []TreeEntry) { + tb.Helper() for i, entry := range expectedEntries { if entry.OID != "" { @@ -36,44 +35,48 @@ func RequireTree(t testing.TB, cfg config.Cfg, repoPath, treeish string, expecte } blob := fmt.Sprintf("blob %d\000%s", len(entry.Content), entry.Content) - hash := sha1.Sum([]byte(blob)) - expectedEntries[i].OID = git.ObjectID(hex.EncodeToString(hash[:])) + + hasher := DefaultObjectHash.Hash() + _, err := hasher.Write([]byte(blob)) + require.NoError(tb, err) + + expectedEntries[i].OID = git.ObjectID(hex.EncodeToString(hasher.Sum(nil))) } var actualEntries []TreeEntry - output := bytes.TrimSpace(Exec(t, cfg, "-C", repoPath, "ls-tree", "-r", treeish)) + output := bytes.TrimSpace(Exec(tb, cfg, "-C", repoPath, "ls-tree", "-r", treeish)) if len(output) > 0 { for _, line := range bytes.Split(output, []byte("\n")) { // Format: SP SP TAB tabSplit := bytes.Split(line, []byte("\t")) - require.Len(t, tabSplit, 2) + require.Len(tb, tabSplit, 2) spaceSplit := bytes.Split(tabSplit[0], []byte(" ")) - require.Len(t, spaceSplit, 3) + require.Len(tb, spaceSplit, 3) path := string(tabSplit[1]) - objectID, err := git.NewObjectIDFromHex(string(spaceSplit[2])) - require.NoError(t, err) + objectID, err := DefaultObjectHash.FromHex(string(spaceSplit[2])) + require.NoError(tb, err) actualEntries = append(actualEntries, TreeEntry{ OID: objectID, Mode: string(spaceSplit[0]), Path: path, - Content: string(Exec(t, cfg, "-C", repoPath, "show", treeish+":"+path)), + Content: string(Exec(tb, cfg, "-C", repoPath, "show", treeish+":"+path)), }) } } - require.Equal(t, expectedEntries, actualEntries) + require.Equal(tb, expectedEntries, actualEntries) } // WriteTree writes a new tree object to the given path. This function does not verify whether OIDs // referred to by tree entries actually exist in the repository. -func WriteTree(t testing.TB, cfg config.Cfg, repoPath string, entries []TreeEntry) git.ObjectID { - t.Helper() +func WriteTree(tb testing.TB, cfg config.Cfg, repoPath string, entries []TreeEntry) git.ObjectID { + tb.Helper() var tree bytes.Buffer for _, entry := range entries { @@ -85,30 +88,32 @@ func WriteTree(t testing.TB, cfg config.Cfg, repoPath string, entries []TreeEntr entryType = "blob" case "040000": entryType = "tree" + case "160000": + entryType = "commit" default: - t.Fatalf("invalid entry type %q", entry.Mode) + tb.Fatalf("invalid entry type %q", entry.Mode) } - require.True(t, len(entry.OID) > 0 || len(entry.Content) > 0, + require.False(tb, len(entry.OID) > 0 && len(entry.Content) > 0, "entry cannot have both OID and content") - require.False(t, len(entry.OID) == 0 && len(entry.Content) == 0, + require.False(tb, len(entry.OID) == 0 && len(entry.Content) == 0, "entry must have either an OID or content") oid := entry.OID if len(entry.Content) > 0 { - oid = WriteBlob(t, cfg, repoPath, []byte(entry.Content)) + oid = WriteBlob(tb, cfg, repoPath, []byte(entry.Content)) } formattedEntry := fmt.Sprintf("%s %s %s\t%s\000", entry.Mode, entryType, oid.String(), entry.Path) _, err := tree.WriteString(formattedEntry) - require.NoError(t, err) + require.NoError(tb, err) } - stdout := ExecOpts(t, cfg, ExecConfig{Stdin: &tree}, + stdout := ExecOpts(tb, cfg, ExecConfig{Stdin: &tree}, "-C", repoPath, "mktree", "-z", "--missing", ) - treeOID, err := git.NewObjectIDFromHex(text.ChompBytes(stdout)) - require.NoError(t, err) + treeOID, err := DefaultObjectHash.FromHex(text.ChompBytes(stdout)) + require.NoError(tb, err) return treeOID } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree_test.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree_test.go index 24b59ab3f4..c136857c6d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/tree_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/tree_test.go @@ -4,13 +4,13 @@ import ( "strings" "testing" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) func TestWriteTree(t *testing.T) { cfg, _, repoPath := setup(t) + differentContentBlobID := WriteBlob(t, cfg, repoPath, []byte("different content")) blobID := WriteBlob(t, cfg, repoPath, []byte("foobar\n")) treeID := WriteTree(t, cfg, repoPath, []TreeEntry{ { @@ -24,7 +24,6 @@ func TestWriteTree(t *testing.T) { desc string entries []TreeEntry expectedEntries []TreeEntry - expectedOID git.ObjectID }{ { desc: "entry with blob OID", @@ -43,7 +42,6 @@ func TestWriteTree(t *testing.T) { Path: "file", }, }, - expectedOID: "54a22f36d78d0ba7964f71ff72c7309edecab857", }, { desc: "entry with blob content", @@ -56,13 +54,12 @@ func TestWriteTree(t *testing.T) { }, expectedEntries: []TreeEntry{ { - OID: "323fae03f4606ea9991df8befbb2fca795e648fa", + OID: blobID, Content: "foobar\n", Mode: "100644", Path: "file", }, }, - expectedOID: "54a22f36d78d0ba7964f71ff72c7309edecab857", }, { desc: "entry with tree OID", @@ -81,7 +78,6 @@ func TestWriteTree(t *testing.T) { Path: "dir/file", }, }, - expectedOID: "c69f8fc9c97fcae2a80ba1578c493171984d810a", }, { desc: "mixed tree and blob entries", @@ -116,29 +112,27 @@ func TestWriteTree(t *testing.T) { Path: "file1", }, { - OID: "9b62abfb7f69b6d5801a232a9e6c332a10c9cafc", + OID: differentContentBlobID, Content: "different content", Mode: "100644", Path: "file2", }, }, - expectedOID: "70a96b29b67eb29344f399c1c4bc0047568e8dba", }, { desc: "two entries with nonexistant objects", entries: []TreeEntry{ { - OID: git.ObjectID(strings.Repeat("1", 40)), + OID: git.ObjectID(strings.Repeat("1", DefaultObjectHash.Hash().Size()*2)), Mode: "100644", Path: "file", }, { - OID: git.ObjectID(strings.Repeat("0", 40)), + OID: DefaultObjectHash.ZeroOID, Mode: "100644", Path: "file", }, }, - expectedOID: "09e7f53dec572807e651fc368d834f9744a5a42c", }, } { t.Run(tc.desc, func(t *testing.T) { @@ -147,8 +141,6 @@ func TestWriteTree(t *testing.T) { if tc.expectedEntries != nil { RequireTree(t, cfg, repoPath, oid.String(), tc.expectedEntries) } - - require.Equal(t, tc.expectedOID, oid) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/user.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/user.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/user.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/user.go index e60efd738e..5e3ddcd891 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest/user.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest/user.go @@ -1,7 +1,7 @@ package gittest import ( - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options.go index 85feeb1a94..c99f87f921 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_options.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options.go @@ -4,14 +4,14 @@ import ( "context" "errors" "fmt" - "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // WithDisabledHooks returns an option that satisfies the requirement to set up @@ -50,7 +50,7 @@ func WithRefTxHook(repo repository.GitRepo) CmdOpt { } // WithPackObjectsHookEnv provides metadata for gitaly-hooks so it can act as a pack-objects hook. -func WithPackObjectsHookEnv(repo *gitalypb.Repository) CmdOpt { +func WithPackObjectsHookEnv(repo *gitalypb.Repository, protocol string) CmdOpt { return func(ctx context.Context, cfg config.Cfg, gitCmdFactory CommandFactory, cc *cmdCfg) error { if !cfg.PackObjectsCache.Enabled { return nil @@ -60,13 +60,26 @@ func WithPackObjectsHookEnv(repo *gitalypb.Repository) CmdOpt { return fmt.Errorf("missing repo: %w", ErrInvalidArg) } - if err := cc.configureHooks(ctx, repo, cfg, gitCmdFactory, nil, PackObjectsHook); err != nil { + userDetails := &UserDetails{ + Protocol: protocol, + UserID: metadata.GetValue(ctx, "user_id"), + Username: metadata.GetValue(ctx, "username"), + } + + if err := cc.configureHooks( + ctx, + repo, + cfg, + gitCmdFactory, + userDetails, + PackObjectsHook, + ); err != nil { return fmt.Errorf("pack-objects hook configuration: %w", err) } cc.globals = append(cc.globals, ConfigPair{ Key: "uploadpack.packObjectsHook", - Value: filepath.Join(cfg.BinDir, "gitaly-hooks"), + Value: cfg.BinaryPath("gitaly-hooks"), }) return nil @@ -81,7 +94,7 @@ func (cc *cmdCfg) configureHooks( repo *gitalypb.Repository, cfg config.Cfg, gitCmdFactory CommandFactory, - receiveHooksPayload *ReceiveHooksPayload, + userDetails *UserDetails, requestedHooks Hook, ) error { if cc.hooksConfigured { @@ -95,7 +108,13 @@ func (cc *cmdCfg) configureHooks( return err } - payload, err := NewHooksPayload(cfg, repo, transaction, receiveHooksPayload, requestedHooks, featureflag.RawFromContext(ctx)).Env() + payload, err := NewHooksPayload( + cfg, + repo, + transaction, + userDetails, + requestedHooks, + featureflag.FromContext(ctx)).Env() if err != nil { return err } @@ -126,7 +145,7 @@ type ReceivePackRequest interface { // git-receive-pack(1). func WithReceivePackHooks(req ReceivePackRequest, protocol string) CmdOpt { return func(ctx context.Context, cfg config.Cfg, gitCmdFactory CommandFactory, cc *cmdCfg) error { - if err := cc.configureHooks(ctx, req.GetRepository(), cfg, gitCmdFactory, &ReceiveHooksPayload{ + if err := cc.configureHooks(ctx, req.GetRepository(), cfg, gitCmdFactory, &UserDetails{ UserID: req.GetGlId(), Username: req.GetGlUsername(), Protocol: protocol, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options_test.go new file mode 100644 index 0000000000..24ebed76b4 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_options_test.go @@ -0,0 +1,87 @@ +//go:build !gitaly_test_sha256 + +package git_test + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + grpcmetadata "google.golang.org/grpc/metadata" +) + +func TestWithRefHook(t *testing.T) { + cfg, repo, _ := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + + opt := git.WithRefTxHook(repo) + subCmd := git.SubCmd{Name: "update-ref", Args: []string{"refs/heads/master", git.ObjectHashSHA1.ZeroOID.String()}} + + for _, tt := range []struct { + name string + fn func() (*command.Command, error) + }{ + { + name: "NewCommand", + fn: func() (*command.Command, error) { + return gittest.NewCommandFactory(t, cfg, git.WithSkipHooks()).New(ctx, repo, subCmd, opt) + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + cmd, err := tt.fn() + require.NoError(t, err) + require.NoError(t, cmd.Wait()) + + var actualEnvVars []string + for _, env := range cmd.Env() { + kv := strings.SplitN(env, "=", 2) + require.Len(t, kv, 2) + key, val := kv[0], kv[1] + + if strings.HasPrefix(key, "GL_") || strings.HasPrefix(key, "GITALY_") { + require.NotEmptyf(t, strings.TrimSpace(val), + "env var %s value should not be empty string", key) + actualEnvVars = append(actualEnvVars, key) + } + } + + require.EqualValues(t, []string{ + "GITALY_HOOKS_PAYLOAD", + "GITALY_LOG_DIR", + }, actualEnvVars) + }) + } +} + +func TestWithPackObjectsHookEnv(t *testing.T) { + cfg, repo, _ := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg.PackObjectsCache.Enabled = true + + userID := "user-123" + username := "username" + protocol := "protocol" + + opt := git.WithPackObjectsHookEnv(repo, protocol) + subCmd := git.SubCmd{Name: "upload-pack", Args: []string{"a/b/c"}} + + ctx = grpcmetadata.AppendToOutgoingContext(ctx, "user_id", userID, "username", username) + ctx = metadata.OutgoingToIncoming(ctx) + + cmd, err := gittest.NewCommandFactory(t, cfg, git.WithSkipHooks()).New(ctx, repo, subCmd, opt) + require.NoError(t, err) + + payload, err := git.HooksPayloadFromEnv(cmd.Env()) + require.NoError(t, err) + + require.Equal(t, userID, payload.UserDetails.UserID) + require.Equal(t, username, payload.UserDetails.Username) + require.Equal(t, protocol, payload.UserDetails.Protocol) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload.go index d12bb0a810..918164f793 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload.go @@ -7,10 +7,10 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/encoding/protojson" ) @@ -47,14 +47,23 @@ const ( ReceivePackHooks = ReferenceTransactionHook | UpdateHook | PreReceiveHook | PostReceiveHook ) +// FeatureFlagWithValue is used as part of the HooksPayload to pass on feature flags with their +// values to gitaly-hooks. +type FeatureFlagWithValue struct { + // Flag is the feature flag. + Flag featureflag.FeatureFlag `json:"flag"` + // Enabled indicates whether the flag is enabled or not. + Enabled bool `json:"enabled"` +} + // HooksPayload holds parameters required for all hooks. type HooksPayload struct { // RequestedHooks is a bitfield of requested Hooks. Hooks which // were not requested will not get executed. RequestedHooks Hook `json:"requested_hooks"` - // FeatureFlags contains feature flags with their values. They are set - // into the outgoing context when calling HookService. - FeatureFlags featureflag.Raw `json:"feature_flags,omitempty"` + // FeatureFlagsWithValue contains feature flags with their values. They are set into the + // outgoing context when calling HookService. + FeatureFlagsWithValue []FeatureFlagWithValue `json:"feature_flags_with_value,omitempty"` // Repo is the repository in which the hook is running. Repo *gitalypb.Repository `json:"-"` @@ -71,15 +80,21 @@ type HooksPayload struct { // it's not set, no transactional voting will happen. Transaction *txinfo.Transaction `json:"transaction"` - // ReceiveHooksPayload contains information required when executing - // git-receive-pack. - ReceiveHooksPayload *ReceiveHooksPayload `json:"receive_hooks_payload"` + // UserDetails contains information required when executing + // git-receive-pack or git-upload-pack + UserDetails *UserDetails `json:"user_details"` + // ReceiveHooksPayload should be identical to UserDetails. + // Since the git2go binary is replaced before the gitaly binary, there + // is a period of time during an upgrade when the gitaly binary is older + // than the corresponding git2go binary. So, we need to keep the + // receive_hooks_payload key for one release before we can remove it. + ReceiveHooksPayload *UserDetails `json:"receive_hooks_payload"` } -// ReceiveHooksPayload contains all information which is required for hooks +// UserDetails contains all information which is required for hooks // executed by git-receive-pack, namely the pre-receive, update or post-receive // hook. -type ReceiveHooksPayload struct { +type UserDetails struct { // Username contains the name of the user who has caused the hook to be executed. Username string `json:"username"` // UserID contains the ID of the user who has caused the hook to be executed. @@ -102,19 +117,27 @@ func NewHooksPayload( cfg config.Cfg, repo *gitalypb.Repository, tx *txinfo.Transaction, - receiveHooksPayload *ReceiveHooksPayload, + userDetails *UserDetails, requestedHooks Hook, - featureFlags featureflag.Raw, + featureFlagsWithValue map[featureflag.FeatureFlag]bool, ) HooksPayload { + flags := make([]FeatureFlagWithValue, 0, len(featureFlagsWithValue)) + for flag, enabled := range featureFlagsWithValue { + flags = append(flags, FeatureFlagWithValue{ + Flag: flag, + Enabled: enabled, + }) + } + return HooksPayload{ - Repo: repo, - RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), - InternalSocketToken: cfg.Auth.Token, - Transaction: tx, - ReceiveHooksPayload: receiveHooksPayload, - RequestedHooks: requestedHooks, - FeatureFlags: featureFlags, + Repo: repo, + RuntimeDir: cfg.RuntimeDir, + InternalSocket: cfg.InternalSocketPath(), + InternalSocketToken: cfg.Auth.Token, + Transaction: tx, + UserDetails: userDetails, + RequestedHooks: requestedHooks, + FeatureFlagsWithValue: flags, } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload_test.go index c1e97e3807..0707dbb215 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/hooks_payload_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/hooks_payload_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git_test import ( @@ -5,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" ) func TestHooksPayload(t *testing.T) { @@ -27,7 +29,9 @@ func TestHooksPayload(t *testing.T) { }) t.Run("roundtrip succeeds", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, nil, git.PreReceiveHook, featureflag.Raw{"flag-key": "flag-value"}).Env() + env, err := git.NewHooksPayload(cfg, repo, nil, nil, git.PreReceiveHook, map[featureflag.FeatureFlag]bool{ + {Name: "flag_key"}: true, + }).Env() require.NoError(t, err) payload, err := git.HooksPayloadFromEnv([]string{ @@ -41,9 +45,14 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocket: cfg.InternalSocketPath(), RequestedHooks: git.PreReceiveHook, - FeatureFlags: featureflag.Raw{"flag-key": "flag-value"}, + FeatureFlagsWithValue: []git.FeatureFlagWithValue{ + { + Flag: featureflag.FeatureFlag{Name: "flag_key"}, + Enabled: true, + }, + }, }, payload) }) @@ -57,7 +66,7 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocket: cfg.InternalSocketPath(), Transaction: &tx, RequestedHooks: git.UpdateHook, }, payload) @@ -75,7 +84,7 @@ func TestHooksPayload(t *testing.T) { }) t.Run("receive hooks payload", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, &git.ReceiveHooksPayload{ + env, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "ssh", @@ -93,9 +102,9 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, - ReceiveHooksPayload: &git.ReceiveHooksPayload{ + UserDetails: &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "ssh", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data.go index 7f99deb8f7..a188f3fdde 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data.go @@ -13,10 +13,10 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data_test.go index a1ac03ebc6..5a8e5f2186 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/clean_stale_data_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/clean_stale_data_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package housekeeping import ( @@ -14,13 +16,13 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" "google.golang.org/grpc/peer" ) @@ -863,13 +865,15 @@ func TestRepositoryManager_CleanStaleData_missingRepo(t *testing.T) { } func TestRepositoryManager_CleanStaleData_unsetConfiguration(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) configPath := filepath.Join(repoPath, "config") - ctx := testhelper.Context(t) - require.NoError(t, os.WriteFile(configPath, []byte( `[core] repositoryformatversion = 0 @@ -921,7 +925,9 @@ func TestRepositoryManager_CleanStaleData_unsetConfigurationTransactional(t *tes ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) gittest.Exec(t, cfg, "-C", repoPath, "config", "http.some.extraHeader", "value") @@ -953,7 +959,9 @@ func TestRepositoryManager_CleanStaleData_pruneEmptyConfigSections(t *testing.T) ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) configPath := filepath.Join(repoPath, "config") @@ -1001,7 +1009,9 @@ func TestPruneEmptyConfigSections(t *testing.T) { ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) configPath := filepath.Join(repoPath, "config") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/commit_graph.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/commit_graph.go new file mode 100644 index 0000000000..351c108224 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/commit_graph.go @@ -0,0 +1,82 @@ +package housekeeping + +import ( + "bytes" + "context" + "errors" + "fmt" + "os" + "path/filepath" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" +) + +// WriteCommitGraphConfig contains configuration that can be passed to WriteCommitGraph to alter its +// default behaviour. +type WriteCommitGraphConfig struct { + // ReplaceChain causes WriteCommitGraph to rewrite the complete commit-graph chain. This is + // a lot more expensive than the default, incremental update of the commit-graph chains but + // may be required in certain cases to fix up commit-graphs. + ReplaceChain bool +} + +// WriteCommitGraphConfigForRepository returns the optimal default-configuration for the given repo. +// By default, the configuration will ask for an incremental commit-graph update. If the preexisting +// commit-graph is missing bloom filters though then the whole commit-graph chain will be rewritten. +func WriteCommitGraphConfigForRepository(ctx context.Context, repo *localrepo.Repo) (WriteCommitGraphConfig, error) { + repoPath, err := repo.Path() + if err != nil { + return WriteCommitGraphConfig{}, err + } + + missingBloomFilters := true + if _, err := os.Stat(filepath.Join(repoPath, stats.CommitGraphRelPath)); err != nil { + if !errors.Is(err, os.ErrNotExist) { + return WriteCommitGraphConfig{}, helper.ErrInternal(fmt.Errorf("statting commit-graph: %w", err)) + } + + if missingBloomFilters, err = stats.IsMissingBloomFilters(repoPath); err != nil { + return WriteCommitGraphConfig{}, helper.ErrInternal(fmt.Errorf("checking for missing bloom-filters: %w", err)) + } + } + + return WriteCommitGraphConfig{ + // If the commit-graph doesn't use bloom filters then an incremental update to the + // commit-graphs will _not_ write bloom filters for the newly added slice. Because + // this is an important optimization for us that speeds up computation of changed + // paths we thus rewrite the complete commit-graph chain if bloom filters do not yet + // exist. + ReplaceChain: missingBloomFilters, + }, nil +} + +// WriteCommitGraph updates the commit-graph in the given repository. The commit-graph is updated +// incrementally, except in the case where it doesn't exist yet or in case it is detected that the +// commit-graph is missing bloom filters. +func WriteCommitGraph(ctx context.Context, repo *localrepo.Repo, cfg WriteCommitGraphConfig) error { + flags := []git.Option{ + git.Flag{Name: "--reachable"}, + git.Flag{Name: "--changed-paths"}, // enables Bloom filters + git.ValueFlag{Name: "--size-multiple", Value: "4"}, + } + + if cfg.ReplaceChain { + flags = append(flags, git.Flag{Name: "--split=replace"}) + } else { + flags = append(flags, git.Flag{Name: "--split"}) + } + + var stderr bytes.Buffer + if err := repo.ExecAndWait(ctx, git.SubSubCmd{ + Name: "commit-graph", + Action: "write", + Flags: flags, + }, git.WithStderr(&stderr)); err != nil { + return helper.ErrInternalf("writing commit-graph: %s: %v", err, stderr.String()) + } + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/manager.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/manager.go index c34aa1330d..62e8b6d183 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/manager.go @@ -5,9 +5,9 @@ import ( "sync" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - gitalycfgprom "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + gitalycfgprom "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" ) // Manager is a housekeeping manager. It is supposed to handle housekeeping tasks for repositories diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool.go new file mode 100644 index 0000000000..732045e098 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool.go @@ -0,0 +1,27 @@ +package housekeeping + +import ( + "regexp" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" +) + +// railsPoolDirRegexp is used to validate object pool directory structure and name as generated by Rails. +var railsPoolDirRegexp = regexp.MustCompile(`^@pools/([0-9a-f]{2})/([0-9a-f]{2})/([0-9a-f]{64})\.git$`) + +// IsRailsPoolRepository returns whether the repository is a pool repository generated by Rails. +func IsRailsPoolRepository(repo repository.GitRepo) bool { + matches := railsPoolDirRegexp.FindStringSubmatch(repo.GetRelativePath()) + if matches == nil || !strings.HasPrefix(matches[3], matches[1]+matches[2]) { + return false + } + + return true +} + +// IsPoolRepository returns whether the repository is an object pool. +func IsPoolRepository(repo repository.GitRepo) bool { + return IsRailsPoolRepository(repo) || praefectutil.IsPoolRepository(repo) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool_test.go new file mode 100644 index 0000000000..daf134505c --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/object_pool_test.go @@ -0,0 +1,62 @@ +package housekeeping + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestIsPoolRepository(t *testing.T) { + for _, tc := range []struct { + desc string + repo *gitalypb.Repository + isPoolPath bool + }{ + { + desc: "rails pool directory", + repo: &gitalypb.Repository{ + RelativePath: gittest.NewObjectPoolName(t), + }, + isPoolPath: true, + }, + { + desc: "praefect pool path", + repo: &gitalypb.Repository{ + RelativePath: praefectutil.DerivePoolPath(1), + }, + isPoolPath: true, + }, + { + desc: "praefect replica path", + repo: &gitalypb.Repository{ + RelativePath: praefectutil.DeriveReplicaPath(1), + }, + }, + { + desc: "missing repository", + }, + { + desc: "empty repository", + repo: &gitalypb.Repository{}, + }, + { + desc: "rails path first to subdirs dont match full hash", + repo: &gitalypb.Repository{ + RelativePath: "@pools/aa/bb/ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.git", + }, + }, + { + desc: "normal repos dont match", + repo: &gitalypb.Repository{ + RelativePath: "@hashed/" + gittest.NewRepositoryName(t, true), + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.isPoolPath, IsPoolRepository(tc.repo)) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects.go index 7f5f13e606..232fec629f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects.go @@ -3,9 +3,10 @@ package housekeeping import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" ) const ( @@ -47,11 +48,7 @@ func RepackObjects(ctx context.Context, repo *localrepo.Repo, cfg RepackObjectsC // details. git.Flag{Name: "-n"}, }, options...), - }, git.WithConfig(GetRepackGitConfig(ctx, cfg.WriteBitmap)...)); err != nil { - return err - } - - if err := WriteCommitGraph(ctx, repo); err != nil { + }, git.WithConfig(GetRepackGitConfig(ctx, repo, cfg.WriteBitmap)...)); err != nil { return err } @@ -61,14 +58,25 @@ func RepackObjects(ctx context.Context, repo *localrepo.Repo, cfg RepackObjectsC } // GetRepackGitConfig returns configuration suitable for Git commands which write new packfiles. -func GetRepackGitConfig(ctx context.Context, bitmap bool) []git.ConfigPair { +func GetRepackGitConfig(ctx context.Context, repo repository.GitRepo, bitmap bool) []git.ConfigPair { config := []git.ConfigPair{ - {Key: "pack.island", Value: "r(e)fs/heads"}, - {Key: "pack.island", Value: "r(e)fs/tags"}, - {Key: "pack.islandCore", Value: "e"}, {Key: "repack.useDeltaIslands", Value: "true"}, } + if IsPoolRepository(repo) { + config = append(config, + git.ConfigPair{Key: "pack.island", Value: git.ObjectPoolRefNamespace + "/he(a)ds"}, + git.ConfigPair{Key: "pack.island", Value: git.ObjectPoolRefNamespace + "/t(a)gs"}, + git.ConfigPair{Key: "pack.islandCore", Value: "a"}, + ) + } else { + config = append(config, + git.ConfigPair{Key: "pack.island", Value: "r(e)fs/heads"}, + git.ConfigPair{Key: "pack.island", Value: "r(e)fs/tags"}, + git.ConfigPair{Key: "pack.islandCore", Value: "e"}, + ) + } + if bitmap { config = append(config, git.ConfigPair{Key: "repack.writeBitmaps", Value: "true"}) config = append(config, git.ConfigPair{Key: "pack.writeBitmapHashCache", Value: "true"}) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects_test.go index feaddcf2e0..33bc89e417 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/objects_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/objects_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package housekeeping import ( @@ -5,11 +7,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func requireObjectCount(t *testing.T, repoPath string, expectedObjects int64) { @@ -35,10 +37,12 @@ func TestRepackObjects(t *testing.T) { cfg := testcfg.Build(t) t.Run("no server info is written", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) - gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithBranch("main")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) requireObjectCount(t, repoPath, 1) requirePackfileCount(t, repoPath, 0) @@ -51,4 +55,18 @@ func TestRepackObjects(t *testing.T) { require.NoFileExists(t, filepath.Join(repoPath, "info", "refs")) require.NoFileExists(t, filepath.Join(repoPath, "objects", "info", "packs")) }) + + testRepoAndPool(t, "delta islands", func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + gittest.TestDeltaIslands(t, cfg, repoPath, repoPath, IsPoolRepository(repoProto), func() error { + return RepackObjects(ctx, repo, RepackObjectsConfig{ + FullRepack: true, + }) + }) + }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository.go index 39257fd965..3ebd4df9aa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository.go @@ -14,10 +14,10 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" ) // OptimizeRepository performs optimizations on the repository. Whether optimizations are performed @@ -85,7 +85,6 @@ func optimizeRepository(ctx context.Context, m *RepositoryManager, repo *localre optimizations["written_bitmap"] = "success" } } - timer.ObserveDuration() timer = prometheus.NewTimer(m.tasksLatency.WithLabelValues("prune")) @@ -106,8 +105,22 @@ func optimizeRepository(ctx context.Context, m *RepositoryManager, repo *localre } else if didPackRefs { optimizations["packed_refs"] = "success" } - timer.ObserveDuration() + + timer = prometheus.NewTimer(m.tasksLatency.WithLabelValues("commit-graph")) + if didWriteCommitGraph, writeCommitGraphCfg, err := writeCommitGraphIfNeeded(ctx, repo, didRepack, didPrune); err != nil { + optimizations["written_commit_graph_full"] = "failure" + optimizations["written_commit_graph_incremental"] = "failure" + return fmt.Errorf("could not write commit-graph: %w", err) + } else if didWriteCommitGraph { + if writeCommitGraphCfg.ReplaceChain { + optimizations["written_commit_graph_full"] = "success" + } else { + optimizations["written_commit_graph_incremental"] = "success" + } + } + timer.ObserveDuration() + totalStatus = "success" return nil @@ -186,26 +199,6 @@ func needsRepacking(repo *localrepo.Repo) (bool, RepackObjectsConfig, error) { }, nil } - missingBloomFilters, err := stats.IsMissingBloomFilters(repoPath) - if err != nil { - return false, RepackObjectsConfig{}, fmt.Errorf("checking for bloom filters: %w", err) - } - - // Bloom filters are part of the commit-graph and allow us to efficiently determine which - // paths have been modified in a given commit without having to look into the object - // database. In the past we didn't compute bloom filters at all, so we want to rewrite the - // whole commit-graph to generate them. - // - // Note that we'll eventually want to move out commit-graph generation from repacking. When - // that happens we should update the commit-graph either if it's missing, when bloom filters - // are missing or when packfiles have been updated. - if missingBloomFilters { - return true, RepackObjectsConfig{ - FullRepack: true, - WriteBitmap: !hasAlternate, - }, nil - } - // Whenever we do an incremental repack we create a new packfile, and as a result Git may // have to look into every one of the packfiles to find objects. This is less efficient the // more packfiles we have, but we cannot repack the whole repository every time either given @@ -215,25 +208,36 @@ func needsRepacking(repo *localrepo.Repo) (bool, RepackObjectsConfig, error) { // relative though: for small repositories it's fine to do full repacks regularly, but for // large repositories we need to be more careful. We thus use a heuristic of "repository // largeness": we take the biggest packfile that exists, and then the maximum allowed number - // of packfiles is `log(largestpackfile_size_in_mb) / log(1.3)`. This gives the following - // allowed number of packfiles: + // of packfiles is `log(largestpackfile_size_in_mb) / log(1.3)` for normal repositories and + // `log(largestpackfile_size_in_mb) / log(10.0)` for pools. This gives the following allowed + // number of packfiles: // - // - No packfile: 5 packfile. This is a special case. - // - 10MB packfile: 8 packfiles. - // - 100MB packfile: 17 packfiles. - // - 500MB packfile: 23 packfiles. - // - 1GB packfile: 26 packfiles. - // - 5GB packfile: 32 packfiles. - // - 10GB packfile: 35 packfiles. - // - 100GB packfile: 43 packfiles. + // ------------------------------------------------------------------------------------- + // | largest packfile size | allowed packfiles for repos | allowed packfiles for pools | + // ------------------------------------------------------------------------------------- + // | none or <10MB | 5 | 2 | + // | 10MB | 8 | 2 | + // | 100MB | 17 | 2 | + // | 500MB | 23 | 2 | + // | 1GB | 26 | 3 | + // | 5GB | 32 | 3 | + // | 10GB | 35 | 4 | + // | 100GB | 43 | 5 | + // ------------------------------------------------------------------------------------- // // The goal is to have a comparatively quick ramp-up of allowed packfiles as the repository // size grows, but then slow down such that we're effectively capped and don't end up with - // an excessive amount of packfiles. + // an excessive amount of packfiles. On the other hand, pool repositories are potentially + // reused as basis for many forks and should thus be packed much more aggressively. // // This is a heuristic and thus imperfect by necessity. We may tune it as we gain experience // with the way it behaves. - if int64(math.Max(5, math.Log(float64(largestPackfileSize))/math.Log(1.3))) < packfileCount { + lowerLimit, log := 5.0, 1.3 + if IsPoolRepository(repo) { + lowerLimit, log = 2.0, 10.0 + } + + if int64(math.Max(lowerLimit, math.Log(float64(largestPackfileSize))/math.Log(log))) <= packfileCount { return true, RepackObjectsConfig{ FullRepack: true, WriteBitmap: !hasAlternate, @@ -354,12 +358,85 @@ func estimateLooseObjectCount(repo *localrepo.Repo, cutoffDate time.Time) (int64 return looseObjects * 256, nil } +// writeCommitGraphIfNeeded writes the commit-graph if required. +func writeCommitGraphIfNeeded(ctx context.Context, repo *localrepo.Repo, didRepack, didPrune bool) (bool, WriteCommitGraphConfig, error) { + needed, cfg, err := needsWriteCommitGraph(ctx, repo, didRepack, didPrune) + if err != nil { + return false, WriteCommitGraphConfig{}, fmt.Errorf("determining whether repo needs commit-graph update: %w", err) + } + if !needed { + return false, WriteCommitGraphConfig{}, nil + } + + if err := WriteCommitGraph(ctx, repo, cfg); err != nil { + return true, cfg, fmt.Errorf("writing commit-graph: %w", err) + } + + return true, cfg, nil +} + +// needsWriteCommitGraph determines whether we need to write the commit-graph. +func needsWriteCommitGraph(ctx context.Context, repo *localrepo.Repo, didRepack, didPrune bool) (bool, WriteCommitGraphConfig, error) { + looseRefs, packedRefsSize, err := countLooseAndPackedRefs(ctx, repo) + if err != nil { + return false, WriteCommitGraphConfig{}, fmt.Errorf("counting refs: %w", err) + } + + // If the repository doesn't have any references at all then there is no point in writing + // commit-graphs given that it would only contain reachable objects, of which there are + // none. + if looseRefs == 0 && packedRefsSize == 0 { + return false, WriteCommitGraphConfig{}, nil + } + + // When we have pruned objects in the repository then it may happen that the commit-graph + // still refers to commits that have now been deleted. While this wouldn't typically cause + // any issues during runtime, it may cause errors when explicitly asking for any commit that + // does exist in the commit-graph, only. Furthermore, it causes git-fsck(1) to report that + // the commit-graph is inconsistent. + // + // To fix this case we will replace the complete commit-chain when we have pruned objects + // from the repository. + if didPrune { + return true, WriteCommitGraphConfig{ + ReplaceChain: true, + }, nil + } + + // When we repacked the repository then chances are high that we have accumulated quite some + // objects since the last time we wrote a commit-graph. + if didRepack { + return true, WriteCommitGraphConfig{}, nil + } + + repoPath, err := repo.Path() + if err != nil { + return false, WriteCommitGraphConfig{}, fmt.Errorf("getting repository path: %w", err) + } + + // Bloom filters are part of the commit-graph and allow us to efficiently determine which + // paths have been modified in a given commit without having to look into the object + // database. In the past we didn't compute bloom filters at all, so we want to rewrite the + // whole commit-graph to generate them. + missingBloomFilters, err := stats.IsMissingBloomFilters(repoPath) + if err != nil { + return false, WriteCommitGraphConfig{}, fmt.Errorf("checking for bloom filters: %w", err) + } + if missingBloomFilters { + return true, WriteCommitGraphConfig{ + ReplaceChain: true, + }, nil + } + + return false, WriteCommitGraphConfig{}, nil +} + // pruneIfNeeded removes objects from the repository which are either unreachable or which are // already part of a packfile. We use a grace period of two weeks. func pruneIfNeeded(ctx context.Context, repo *localrepo.Repo) (bool, error) { // Pool repositories must never prune any objects, or otherwise we may corrupt members of // that pool if they still refer to that object. - if IsPoolPath(repo.GetRelativePath()) { + if IsPoolRepository(repo) { return false, nil } @@ -401,10 +478,12 @@ func pruneIfNeeded(ctx context.Context, repo *localrepo.Repo) (bool, error) { return true, nil } -func packRefsIfNeeded(ctx context.Context, repo *localrepo.Repo) (bool, error) { +// countLooseAndPackedRefs counts the number of loose references that exist in the repository and +// returns the size of the packed-refs file. +func countLooseAndPackedRefs(ctx context.Context, repo *localrepo.Repo) (int64, int64, error) { repoPath, err := repo.Path() if err != nil { - return false, fmt.Errorf("getting repository path: %w", err) + return 0, 0, fmt.Errorf("getting repository path: %w", err) } refsPath := filepath.Join(repoPath, "refs") @@ -420,23 +499,32 @@ func packRefsIfNeeded(ctx context.Context, repo *localrepo.Repo) (bool, error) { return nil }); err != nil { - return false, fmt.Errorf("counting loose refs: %w", err) - } - - // If there aren't any loose refs then there is nothing we need to do. - if looseRefs == 0 { - return false, nil + return 0, 0, fmt.Errorf("counting loose refs: %w", err) } packedRefsSize := int64(0) if stat, err := os.Stat(filepath.Join(repoPath, "packed-refs")); err != nil { if !errors.Is(err, os.ErrNotExist) { - return false, fmt.Errorf("getting packed-refs size: %w", err) + return 0, 0, fmt.Errorf("getting packed-refs size: %w", err) } } else { packedRefsSize = stat.Size() } + return looseRefs, packedRefsSize, nil +} + +func packRefsIfNeeded(ctx context.Context, repo *localrepo.Repo) (bool, error) { + looseRefs, packedRefsSize, err := countLooseAndPackedRefs(ctx, repo) + if err != nil { + return false, fmt.Errorf("counting refs: %w", err) + } + + // If there aren't any loose refs then there is nothing we need to do. + if looseRefs == 0 { + return false, nil + } + // Packing loose references into the packed-refs file scales with the number of references // we're about to write. We thus decide whether we repack refs by weighing the current size // of the packed-refs file against the number of loose references. This is done such that we diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_ext_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_ext_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_ext_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_ext_test.go index 723408ec0d..fa51834aee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_ext_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_ext_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package housekeeping_test import ( @@ -9,13 +11,13 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" ) func TestPruneIfNeeded(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_test.go index 8aad4dd8f5..030ab1eef4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/optimize_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/optimize_repository_test.go @@ -1,10 +1,11 @@ +//go:build !gitaly_test_sha256 + package housekeeping import ( "bytes" "context" "fmt" - "io" "os" "path/filepath" "strings" @@ -15,49 +16,48 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -type infiniteReader struct{} - -func (r infiniteReader) Read(b []byte) (int, error) { - for i := range b { - b[i] = '\000' - } - return len(b), nil -} - func TestNeedsRepacking(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) for _, tc := range []struct { desc string - setup func(t *testing.T) *gitalypb.Repository + setup func(t *testing.T, relativePath string) *gitalypb.Repository expectedErr error expectedNeeded bool expectedConfig RepackObjectsConfig }{ { desc: "empty repo does nothing", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) return repoProto }, }, { desc: "missing bitmap", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) return repoProto }, expectedNeeded: true, @@ -68,8 +68,12 @@ func TestNeedsRepacking(t *testing.T) { }, { desc: "missing bitmap with alternate", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) // Create the alternates file. If it exists, then we shouldn't try // to generate a bitmap. @@ -77,47 +81,56 @@ func TestNeedsRepacking(t *testing.T) { return repoProto }, - expectedNeeded: true, - expectedConfig: RepackObjectsConfig{ - FullRepack: true, - WriteBitmap: false, - }, + // If we have no bitmap in the repository we'd normally want to fully repack + // the repository. But because we have an alternates file we know that the + // repository must not have a bitmap anyway, so we can skip the repack here. + expectedNeeded: false, }, { desc: "missing commit-graph", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) gittest.Exec(t, cfg, "-C", repoPath, "repack", "-Ad", "--write-bitmap-index") return repoProto }, - expectedNeeded: true, - expectedConfig: RepackObjectsConfig{ - FullRepack: true, - WriteBitmap: true, - }, + // The commit-graph used to influence whether we repacked a repository or + // not. That was due to historic reasons only, though, and ultimately does + // not make any sense. + expectedNeeded: false, }, { desc: "commit-graph without bloom filters", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) gittest.Exec(t, cfg, "-C", repoPath, "repack", "-Ad", "--write-bitmap-index") gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write") return repoProto }, - expectedNeeded: true, - expectedConfig: RepackObjectsConfig{ - FullRepack: true, - WriteBitmap: true, - }, + // The commit-graph used to influence whether we repacked a repository or + // not. That was due to historic reasons only, though, and ultimately does + // not make any sense. + expectedNeeded: false, }, { desc: "no repack needed", - setup: func(t *testing.T) *gitalypb.Repository { - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) gittest.Exec(t, cfg, "-C", repoPath, "repack", "-Ad", "--write-bitmap-index") gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--changed-paths", "--split") @@ -131,54 +144,67 @@ func TestNeedsRepacking(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { t.Parallel() - repoProto := tc.setup(t) - repo := localrepo.NewTestRepo(t, cfg, repoProto) + testRepoAndPool(t, tc.desc, func(t *testing.T, relativePath string) { + repoProto := tc.setup(t, relativePath) + repo := localrepo.NewTestRepo(t, cfg, repoProto) - repackNeeded, repackCfg, err := needsRepacking(repo) - require.Equal(t, tc.expectedErr, err) - require.Equal(t, tc.expectedNeeded, repackNeeded) - require.Equal(t, tc.expectedConfig, repackCfg) + repackNeeded, repackCfg, err := needsRepacking(repo) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedNeeded, repackNeeded) + require.Equal(t, tc.expectedConfig, repackCfg) + }) }) } const megaByte = 1024 * 1024 for _, tc := range []struct { - packfileSize int64 - requiredPackfiles int + packfileSize int64 + requiredPackfiles int + requiredPackfilesForPool int }{ { - packfileSize: 1, - requiredPackfiles: 5, + packfileSize: 1, + requiredPackfiles: 5, + requiredPackfilesForPool: 2, }, { - packfileSize: 5 * megaByte, - requiredPackfiles: 6, + packfileSize: 5 * megaByte, + requiredPackfiles: 6, + requiredPackfilesForPool: 2, }, { - packfileSize: 10 * megaByte, - requiredPackfiles: 8, + packfileSize: 10 * megaByte, + requiredPackfiles: 8, + requiredPackfilesForPool: 2, }, { - packfileSize: 50 * megaByte, - requiredPackfiles: 14, + packfileSize: 50 * megaByte, + requiredPackfiles: 14, + requiredPackfilesForPool: 2, }, { - packfileSize: 100 * megaByte, - requiredPackfiles: 17, + packfileSize: 100 * megaByte, + requiredPackfiles: 17, + requiredPackfilesForPool: 2, }, { - packfileSize: 500 * megaByte, - requiredPackfiles: 23, + packfileSize: 500 * megaByte, + requiredPackfiles: 23, + requiredPackfilesForPool: 2, }, { - packfileSize: 1000 * megaByte, - requiredPackfiles: 26, + packfileSize: 1001 * megaByte, + requiredPackfiles: 26, + requiredPackfilesForPool: 3, }, // Let's not go any further than this, we're thrashing the temporary directory. } { - t.Run(fmt.Sprintf("packfile with %d bytes", tc.packfileSize), func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, fmt.Sprintf("packfile with %d bytes", tc.packfileSize), func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) packDir := filepath.Join(repoPath, "objects", "pack") @@ -193,16 +219,19 @@ func TestNeedsRepacking(t *testing.T) { // We first create a single big packfile which is used to determine the // boundary of when we repack. - bigPackfile, err := os.OpenFile(filepath.Join(packDir, "big.pack"), os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o644) - require.NoError(t, err) - defer testhelper.MustClose(t, bigPackfile) - _, err = io.Copy(bigPackfile, io.LimitReader(infiniteReader{}, tc.packfileSize)) - require.NoError(t, err) + bigPackPath := filepath.Join(packDir, "big.pack") + require.NoError(t, os.WriteFile(bigPackPath, nil, 0o644)) + require.NoError(t, os.Truncate(bigPackPath, tc.packfileSize)) + + requiredPackfiles := tc.requiredPackfiles + if IsPoolRepository(repoProto) { + requiredPackfiles = tc.requiredPackfilesForPool + } // And then we create one less packfile than we need to hit the boundary. // This is done to assert that we indeed don't repack before hitting the // boundary. - for i := 0; i < tc.requiredPackfiles-1; i++ { + for i := 0; i < requiredPackfiles-2; i++ { additionalPackfile, err := os.Create(filepath.Join(packDir, fmt.Sprintf("%d.pack", i))) require.NoError(t, err) testhelper.MustClose(t, additionalPackfile) @@ -284,8 +313,11 @@ func TestNeedsRepacking(t *testing.T) { expectedRepack: true, }, } { - t.Run(tc.desc, func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, tc.desc, func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Emulate the existence of a bitmap and a commit-graph with bloom filters. @@ -360,12 +392,15 @@ func TestPackRefsIfNeeded(t *testing.T) { requiredRefs: 99, }, } { - t.Run(fmt.Sprintf("packed-refs with %d bytes", tc.packedRefsSize), func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, fmt.Sprintf("packed-refs with %d bytes", tc.packedRefsSize), func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Write an empty commit such that we can create valid refs. - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, repoPath) looseRefContent := []byte(commitID.String() + "\n") // We first create a single big packfile which is used to determine the @@ -411,8 +446,12 @@ func TestPackRefsIfNeeded(t *testing.T) { func TestEstimateLooseObjectCount(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) t.Run("empty repository", func(t *testing.T) { @@ -491,19 +530,25 @@ func TestEstimateLooseObjectCount(t *testing.T) { } func TestOptimizeRepository(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) + txManager := transaction.NewManager(cfg, backchannel.NewRegistry()) for _, tc := range []struct { - desc string - setup func(t *testing.T) *gitalypb.Repository - expectedErr error - expectedMetrics string + desc string + setup func(t *testing.T, relativePath string) *gitalypb.Repository + expectedErr error + expectedMetrics string + expectedMetricsForPool string }{ { desc: "empty repository does nothing", - setup: func(t *testing.T) *gitalypb.Repository { - repo, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) return repo }, expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository @@ -513,36 +558,76 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 }, { desc: "repository without bitmap repacks objects", - setup: func(t *testing.T) *gitalypb.Repository { - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) return repo }, expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository # TYPE gitaly_housekeeping_tasks_total counter gitaly_housekeeping_tasks_total{housekeeping_task="packed_objects_full", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_incremental", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="written_bitmap", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 `, }, { - desc: "repository without commit-graph repacks objects", - setup: func(t *testing.T) *gitalypb.Repository { - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") + desc: "repository without commit-graph writes commit-graph", + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "-d", "--write-bitmap-index") return repo }, expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository # TYPE gitaly_housekeeping_tasks_total counter +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_full", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 +`, + }, + { + desc: "repository with multiple packfiles packs only for object pool", + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) + + // Note: git-repack(1) without "-d" will _not_ delete the old + // packfile and thus end up with two packfiles. + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--split", "--changed-paths") + + return repo + }, + expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository +# TYPE gitaly_housekeeping_tasks_total counter +gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 +`, + expectedMetricsForPool: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository +# TYPE gitaly_housekeeping_tasks_total counter gitaly_housekeeping_tasks_total{housekeeping_task="packed_objects_full", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="written_bitmap", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_incremental", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 `, }, { desc: "well-packed repository does not optimize", - setup: func(t *testing.T) *gitalypb.Repository { - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "-d", "--write-bitmap-index") gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--split", "--changed-paths") return repo }, @@ -553,9 +638,13 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 }, { desc: "recent loose objects don't get pruned", - setup: func(t *testing.T) *gitalypb.Repository { - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "-d", "--write-bitmap-index") gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--split", "--changed-paths") // The repack won't repack the following objects because they're @@ -578,14 +667,19 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository # TYPE gitaly_housekeeping_tasks_total counter gitaly_housekeeping_tasks_total{housekeeping_task="packed_objects_incremental", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_incremental", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 `, }, { desc: "old loose objects get pruned", - setup: func(t *testing.T) *gitalypb.Repository { - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: relativePath, + }) + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "-d", "--write-bitmap-index") gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--split", "--changed-paths") // The repack won't repack the following objects because they're @@ -605,17 +699,28 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 expectedMetrics: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository # TYPE gitaly_housekeeping_tasks_total counter gitaly_housekeeping_tasks_total{housekeeping_task="packed_objects_incremental", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_full", status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="pruned_objects",status="success"} 1 gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 +`, + // Object pools never prune objects. + expectedMetricsForPool: `# HELP gitaly_housekeeping_tasks_total Total number of housekeeping tasks performed in the repository +# TYPE gitaly_housekeeping_tasks_total counter +gitaly_housekeeping_tasks_total{housekeeping_task="packed_objects_incremental", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="written_commit_graph_incremental", status="success"} 1 +gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 `, }, { desc: "loose refs get packed", - setup: func(t *testing.T) *gitalypb.Repository { - repo, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setup: func(t *testing.T, relativePath string) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) for i := 0; i < 16; i++ { - gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithBranch(fmt.Sprintf("branch-%d", i))) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(fmt.Sprintf("branch-%d", i))) } gittest.Exec(t, cfg, "-C", repoPath, "repack", "-A", "--write-bitmap-index") @@ -630,10 +735,10 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 `, }, } { - t.Run(tc.desc, func(t *testing.T) { + testRepoAndPool(t, tc.desc, func(t *testing.T, relativePath string) { ctx := testhelper.Context(t) - repoProto := tc.setup(t) + repoProto := tc.setup(t, relativePath) repo := localrepo.NewTestRepo(t, cfg, repoProto) manager := NewManager(cfg.Prometheus, txManager) @@ -641,9 +746,14 @@ gitaly_housekeeping_tasks_total{housekeeping_task="total", status="success"} 1 err := manager.OptimizeRepository(ctx, repo) require.Equal(t, tc.expectedErr, err) - assert.NoError(t, testutil.CollectAndCompare( + expectedMetrics := tc.expectedMetrics + if IsPoolRepository(repoProto) && tc.expectedMetricsForPool != "" { + expectedMetrics = tc.expectedMetricsForPool + } + + require.NoError(t, testutil.CollectAndCompare( manager.tasksTotal, - bytes.NewBufferString(tc.expectedMetrics), + bytes.NewBufferString(expectedMetrics), "gitaly_housekeeping_tasks_total", )) }) @@ -657,7 +767,10 @@ func TestOptimizeRepository_ConcurrencyLimit(t *testing.T) { t.Run("subsequent calls get skipped", func(t *testing.T) { reqReceivedCh, ch := make(chan struct{}), make(chan struct{}) - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) manager := &RepositoryManager{ @@ -685,9 +798,15 @@ func TestOptimizeRepository_ConcurrencyLimit(t *testing.T) { t.Run("multiple repositories concurrently", func(t *testing.T) { reqReceivedCh, ch := make(chan struct{}), make(chan struct{}) - repoProtoFirst, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProtoFirst, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) repoFirst := localrepo.NewTestRepo(t, cfg, repoProtoFirst) - repoProtoSecond, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProtoSecond, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) repoSecond := localrepo.NewTestRepo(t, cfg, repoProtoSecond) reposOptimized := make(map[string]struct{}) @@ -724,7 +843,10 @@ func TestOptimizeRepository_ConcurrencyLimit(t *testing.T) { t.Run("serialized optimizations", func(t *testing.T) { reqReceivedCh, ch := make(chan struct{}), make(chan struct{}) - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) var optimizations int @@ -776,8 +898,11 @@ func TestPruneIfNeeded(t *testing.T) { ctx := testhelper.Context(t) cfg := testcfg.Build(t) - t.Run("empty repo does not prune", func(t *testing.T) { - repoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, "empty repo does not prune", func(t *testing.T, relativePath string) { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) didPrune, err := pruneIfNeeded(ctx, repo) @@ -785,8 +910,11 @@ func TestPruneIfNeeded(t *testing.T) { require.False(t, didPrune) }) - t.Run("repo with single object does not prune", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, "repo with single object does not prune", func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) gittest.WriteBlob(t, cfg, repoPath, []byte("something")) @@ -796,8 +924,11 @@ func TestPruneIfNeeded(t *testing.T) { require.False(t, didPrune) }) - t.Run("repo with single 17-prefixed objects does not prune", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, "repo with single 17-prefixed objects does not prune", func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("32")) @@ -808,8 +939,11 @@ func TestPruneIfNeeded(t *testing.T) { require.False(t, didPrune) }) - t.Run("repo with four 17-prefixed objects does not prune", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, "repo with four 17-prefixed objects does not prune", func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) for _, contents := range []string{"32", "119", "334", "782"} { @@ -822,8 +956,11 @@ func TestPruneIfNeeded(t *testing.T) { require.False(t, didPrune) }) - t.Run("repo with five 17-prefixed objects does prune after grace period", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + testRepoAndPool(t, "repo with five 17-prefixed objects does prune after grace period", func(t *testing.T, relativePath string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: relativePath, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) objectPath := func(oid git.ObjectID) string { @@ -864,15 +1001,266 @@ func TestPruneIfNeeded(t *testing.T) { // and thus we would still want to prune here. didPrune, err = pruneIfNeeded(ctx, repo) require.NoError(t, err) - require.True(t, didPrune) - // But this time the objects shouldn't exist anymore because they were older than - // the grace period. - for _, blob := range blobs { - require.NoFileExists(t, objectPath(blob)) + if IsPoolRepository(repoProto) { + // Object pools mustn't ever prune objects. + require.False(t, didPrune) + for _, blob := range append(blobs, recentBlob) { + require.FileExists(t, objectPath(blob)) + } + } else { + require.True(t, didPrune) + + // But this time the objects shouldn't exist anymore because they were older than + // the grace period. + for _, blob := range blobs { + require.NoFileExists(t, objectPath(blob)) + } + + // The recent blob should continue to exist though. + require.FileExists(t, objectPath(recentBlob)) } - - // The recent blob should continue to exist though. - require.FileExists(t, objectPath(recentBlob)) + }) +} + +func TestWriteCommitGraphIfNeeded(t *testing.T) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + for _, tc := range []struct { + desc string + setup func(t *testing.T) (*gitalypb.Repository, string) + didRepack bool + didPrune bool + expectedWrite bool + expectedCfg WriteCommitGraphConfig + expectedCommitGraph bool + }{ + { + desc: "empty repository", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + return gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + }, + didRepack: true, + didPrune: true, + expectedWrite: false, + }, + { + desc: "repository with objects but no refs", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteBlob(t, cfg, repoPath, []byte("something")) + return repoProto, repoPath + }, + didRepack: true, + didPrune: true, + expectedWrite: false, + }, + { + desc: "repository without commit-graph", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + return repoProto, repoPath + }, + expectedWrite: true, + expectedCfg: WriteCommitGraphConfig{ + ReplaceChain: true, + }, + expectedCommitGraph: true, + }, + { + desc: "repository with old-style unsplit commit-graph", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Write a non-split commit-graph with bloom filters. We should + // always rewrite the commit-graphs when we're not using a split + // commit-graph. We make sure to add bloom filters via + // `--changed-paths` given that it would otherwise cause us to + // rewrite the graph regardless of whether the graph is split or not + // if they were missing. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--changed-paths") + + return repoProto, repoPath + }, + expectedWrite: true, + expectedCfg: WriteCommitGraphConfig{ + ReplaceChain: true, + }, + expectedCommitGraph: true, + }, + { + desc: "repository with split commit-graph without bitmap", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Generate a split commit-graph, but don't enable computation of + // changed paths. This should trigger a rewrite so that we can + // recompute all graphs and generate the changed paths. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split") + + return repoProto, repoPath + }, + expectedWrite: true, + expectedCfg: WriteCommitGraphConfig{ + ReplaceChain: true, + }, + expectedCommitGraph: true, + }, + { + desc: "repository with split commit-graph with bitmap without repack", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Write a split commit-graph with bitmaps. This is the state we + // want to be in. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + return repoProto, repoPath + }, + // We use the information about whether we repacked objects as an indicator + // whether something has changed in the repository. If it didn't, then we + // assume no new objects exist and thus we don't rewrite the commit-graph. + didRepack: false, + expectedWrite: false, + expectedCommitGraph: true, + }, + { + desc: "repository with split commit-graph with bitmap with repack", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Write a split commit-graph with bitmaps. This is the state we + // want to be in, so there is no write required if we didn't also + // repack objects. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + return repoProto, repoPath + }, + // When we have a valid commit-graph, but objects have been repacked, we + // assume that there are new objects in the repository. So consequentially, + // we should write the commit-graphs. + didRepack: true, + expectedWrite: true, + expectedCommitGraph: true, + }, + { + desc: "repository with split commit-graph with bitmap with pruned objects", + setup: func(t *testing.T) (*gitalypb.Repository, string) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Write a split commit-graph with bitmaps. This is the state we + // want to be in, so there is no write required if we didn't also + // repack objects. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + return repoProto, repoPath + }, + // When we have a valid commit-graph, but objects have been repacked, we + // assume that there are new objects in the repository. So consequentially, + // we should write the commit-graphs. + didPrune: true, + expectedWrite: true, + expectedCfg: WriteCommitGraphConfig{ + ReplaceChain: true, + }, + expectedCommitGraph: true, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := tc.setup(t) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + didWrite, writeCommitGraphCfg, err := writeCommitGraphIfNeeded(ctx, repo, tc.didRepack, tc.didPrune) + require.NoError(t, err) + require.Equal(t, tc.expectedWrite, didWrite) + require.Equal(t, tc.expectedCfg, writeCommitGraphCfg) + + commitGraphPath := filepath.Join(repoPath, "objects", "info", "commit-graphs", "commit-graph-chain") + if tc.expectedCommitGraph { + require.FileExists(t, commitGraphPath) + } else { + require.NoFileExists(t, commitGraphPath) + } + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "verify") + }) + } + + t.Run("commit-graph with pruned objects", func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + // Write a first commit-graph that contains the root commit, only. + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + // Write a second, incremental commit-graph that contains a commit we're about to + // make unreachable and then prune. + unreachableCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(rootCommitID), gittest.WithBranch("main")) + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split=no-merge", "--changed-paths") + + // Reset the "main" branch back to the initial root commit ID and prune the now + // unreachable second commit. + gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/main", rootCommitID.String()) + gittest.Exec(t, cfg, "-C", repoPath, "prune", "--expire", "now") + + // The commit-graph chain now refers to the pruned commit, and git-commit-graph(1) + // should complain about that. + var stderr bytes.Buffer + verifyCmd := gittest.NewCommand(t, cfg, "-C", repoPath, "commit-graph", "verify") + verifyCmd.Stderr = &stderr + require.EqualError(t, verifyCmd.Run(), "exit status 1") + require.Equal(t, stderr.String(), fmt.Sprintf("error: Could not read %[1]s\nfailed to parse commit %[1]s from object database for commit-graph\n", unreachableCommitID)) + + // Write the commit-graph and pretend that objects have been rewritten, but not + // pruned. + didWrite, writeCommitGraphCfg, err := writeCommitGraphIfNeeded(ctx, repo, true, false) + require.NoError(t, err) + require.True(t, didWrite) + require.Equal(t, WriteCommitGraphConfig{}, writeCommitGraphCfg) + + // When pretending that no objects have been pruned we still observe the same + // failure. + stderr.Reset() + verifyCmd = gittest.NewCommand(t, cfg, "-C", repoPath, "commit-graph", "verify") + verifyCmd.Stderr = &stderr + require.EqualError(t, verifyCmd.Run(), "exit status 1") + require.Equal(t, stderr.String(), fmt.Sprintf("error: Could not read %[1]s\nfailed to parse commit %[1]s from object database for commit-graph\n", unreachableCommitID)) + + // Write the commit-graph a second time, but this time we pretend we have just + // pruned objects. This should cause the commit-graph to be rewritten. + didWrite, writeCommitGraphCfg, err = writeCommitGraphIfNeeded(ctx, repo, false, true) + require.NoError(t, err) + require.True(t, didWrite) + require.Equal(t, WriteCommitGraphConfig{ + ReplaceChain: true, + }, writeCommitGraphCfg) + + // The commit-graph should now have been fixed. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "verify") }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/testhelper_test.go new file mode 100644 index 0000000000..ccb0e1a288 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/testhelper_test.go @@ -0,0 +1,25 @@ +package housekeeping + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func testRepoAndPool(t *testing.T, desc string, testFunc func(t *testing.T, relativePath string)) { + t.Helper() + t.Run(desc, func(t *testing.T) { + t.Run("normal repository", func(t *testing.T) { + testFunc(t, gittest.NewRepositoryName(t, true)) + }) + + t.Run("object pool", func(t *testing.T) { + testFunc(t, gittest.NewObjectPoolName(t)) + }) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees.go index 76ee8cb9cf..22aae27ef3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees.go @@ -12,9 +12,9 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees_test.go index e631e0c2c2..8ee923d2d3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping/worktrees_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping/worktrees_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package housekeeping import ( @@ -6,12 +8,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestCleanupDisconnectedWorktrees_doesNothingWithoutWorktrees(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lfs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lfs.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lfs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lfs.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config.go index ac76ef6b98..56c965ed89 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config.go @@ -7,11 +7,11 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" ) func isExitWithCode(err error, code int) bool { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config_test.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config_test.go index 1f059a8761..43e4d516af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/config_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/config_test.go @@ -8,15 +8,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" "google.golang.org/grpc/peer" ) @@ -78,7 +78,10 @@ func TestRepo_SetConfig(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, + gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := NewTestRepo(t, cfg, repoProto) for _, entry := range tc.preexistingEntries { @@ -95,10 +98,15 @@ func TestRepo_SetConfig(t *testing.T) { require.Equal(t, tc.expectedErr, repo.SetConfig(ctx, tc.key, tc.value, &transaction.MockManager{})) standardEntries := []string{ - "core.repositoryformatversion=0", "core.filemode=true", "core.bare=true", } + if gittest.ObjectHashIsSHA256() { + standardEntries = append(standardEntries, "core.repositoryformatversion=1") + standardEntries = append(standardEntries, "extensions.objectformat=sha256") + } else { + standardEntries = append(standardEntries, "core.repositoryformatversion=0") + } if runtime.GOOS == "darwin" { standardEntries = append(standardEntries, @@ -108,7 +116,7 @@ func TestRepo_SetConfig(t *testing.T) { } output := gittest.Exec(t, cfg, "-C", repoPath, "config", "--list", "--local") - require.Equal(t, + require.ElementsMatch(t, append(standardEntries, tc.expectedEntries...), strings.Split(text.ChompBytes(output), "\n"), ) @@ -116,7 +124,9 @@ func TestRepo_SetConfig(t *testing.T) { } t.Run("transactional", func(t *testing.T) { - repoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := NewTestRepo(t, cfg, repoProto) backchannelPeer := &peer.Peer{ @@ -145,15 +155,11 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { "core.filemode", "core.bare", } - if runtime.GOOS == "darwin" { - standardKeys = []string{ - "core.repositoryformatversion", - "core.filemode", - "core.bare", - "core.ignorecase", - "core.precomposeunicode", - } + standardKeys = append(standardKeys, "core.ignorecase", "core.precomposeunicode") + } + if gittest.ObjectHashIsSHA256() { + standardKeys = append(standardKeys, "extensions.objectformat") } for _, tc := range []struct { @@ -177,7 +183,7 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { "foo.qux": "value2", }, regex: "foo.bar", - expectedKeys: append(standardKeys, "foo.qux"), + expectedKeys: append([]string{"foo.qux"}, standardKeys...), }, { desc: "multiple matches", @@ -195,7 +201,7 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { "foo.qux": "value2", }, regex: "matchme", - expectedKeys: append(standardKeys, "foo.qux"), + expectedKeys: append([]string{"foo.qux"}, standardKeys...), }, { desc: "anchored", @@ -204,7 +210,7 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { "matchme.foo": "value2", }, regex: "^matchme", - expectedKeys: append(standardKeys, "foo.matchme"), + expectedKeys: append([]string{"foo.matchme"}, standardKeys...), }, { desc: "no matches", @@ -227,7 +233,9 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := NewTestRepo(t, cfg, repoProto) for key, value := range tc.addEntries { @@ -244,12 +252,14 @@ func TestRepo_UnsetMatchingConfig(t *testing.T) { require.Equal(t, tc.expectedErr, repo.UnsetMatchingConfig(ctx, tc.regex, &transaction.MockManager{})) output := gittest.Exec(t, cfg, "-C", repoPath, "config", "--list", "--name-only", "--local") - require.Equal(t, tc.expectedKeys, strings.Split(text.ChompBytes(output), "\n")) + require.ElementsMatch(t, tc.expectedKeys, strings.Split(text.ChompBytes(output), "\n")) }) } t.Run("transactional", func(t *testing.T) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := NewTestRepo(t, cfg, repoProto) gittest.Exec(t, cfg, "-C", repoPath, "config", "--add", "some.key", "value") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects.go index e5459d13bf..43198b0e9e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects.go @@ -9,11 +9,11 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // ErrObjectNotFound is returned in case an object could not be found. @@ -47,7 +47,12 @@ func (repo *Repo) WriteBlob(ctx context.Context, path string, content io.Reader) return "", errorWithStderr(err, stderr.Bytes()) } - oid, err := git.NewObjectIDFromHex(text.ChompBytes(stdout.Bytes())) + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return "", fmt.Errorf("detecting object hash: %w", err) + } + + oid, err := objectHash.FromHex(text.ChompBytes(stdout.Bytes())) if err != nil { return "", err } @@ -74,7 +79,7 @@ func (e FormatTagError) Error() string { // because we're just about to run git's own "fsck" check on this. // // However, if someone injected parameters with extra newlines they -// could cause subsequent values to be ignore via a crafted +// could cause subsequent values to be ignored via a crafted // message. This someone could also locally craft a tag locally and // "git push" it. But allowing e.g. someone to provide their own // timestamp here would at best be annoying, and at worst run up @@ -159,7 +164,12 @@ func (repo *Repo) WriteTag( return "", MktagError{tagName: tagName, stderr: stderr.String()} } - tagID, err := git.NewObjectIDFromHex(text.ChompBytes(stdout.Bytes())) + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return "", fmt.Errorf("detecting object hash: %w", err) + } + + tagID, err := objectHash.FromHex(text.ChompBytes(stdout.Bytes())) if err != nil { return "", fmt.Errorf("could not parse tag ID: %w", err) } @@ -226,10 +236,11 @@ func (repo *Repo) ReadCommit(ctx context.Context, revision git.Revision, opts .. opt(&cfg) } - objectReader, err := repo.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := repo.catfileCache.ObjectReader(ctx, repo) if err != nil { return nil, err } + defer cancel() var commit *gitalypb.GitCommit if cfg.withTrailers { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects_test.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects_test.go index e8cd43cd69..6bc6056b13 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/objects_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/objects_test.go @@ -11,12 +11,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/protobuf/types/known/timestamppb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type ReaderFunc func([]byte) (int, error) @@ -26,7 +25,7 @@ func (fn ReaderFunc) Read(b []byte) (int, error) { return fn(b) } func TestRepo_WriteBlob(t *testing.T) { ctx := testhelper.Context(t) - _, repo, repoPath := setupRepo(t, withEmptyRepo()) + _, repo, repoPath := setupRepo(t) for _, tc := range []struct { desc string @@ -101,7 +100,7 @@ func TestFormatTag(t *testing.T) { // internal/gitaly/service/operations/tags_test.go { desc: "basic signature", - objectID: git.ZeroOID, + objectID: gittest.DefaultObjectHash.ZeroOID, objectType: "commit", tagName: []byte("my-tag"), author: &gitalypb.User{ @@ -112,7 +111,7 @@ func TestFormatTag(t *testing.T) { }, { desc: "basic signature", - objectID: git.ZeroOID, + objectID: gittest.DefaultObjectHash.ZeroOID, objectType: "commit", tagName: []byte("my-tag\ninjection"), tagBody: []byte(""), @@ -124,7 +123,7 @@ func TestFormatTag(t *testing.T) { }, { desc: "signature with fixed time", - objectID: git.ZeroOID, + objectID: gittest.DefaultObjectHash.ZeroOID, objectType: "commit", tagName: []byte("my-tag"), tagBody: []byte(""), @@ -155,6 +154,8 @@ func TestRepo_WriteTag(t *testing.T) { cfg, repo, repoPath := setupRepo(t) + commitID := gittest.WriteCommit(t, cfg, repoPath) + for _, tc := range []struct { desc string objectID git.ObjectID @@ -169,7 +170,7 @@ func TestRepo_WriteTag(t *testing.T) { // internal/gitaly/service/operations/tags_test.go { desc: "basic signature", - objectID: "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + objectID: commitID, objectType: "commit", tagName: []byte("my-tag"), tagBody: []byte(""), @@ -180,7 +181,7 @@ func TestRepo_WriteTag(t *testing.T) { }, { desc: "signature with time", - objectID: "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + objectID: commitID, objectType: "commit", tagName: []byte("tag-with-timestamp"), tagBody: []byte(""), @@ -189,15 +190,15 @@ func TestRepo_WriteTag(t *testing.T) { Email: []byte("root@localhost"), }, authorDate: time.Unix(12345, 0).UTC(), - expectedTag: `object c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd + expectedTag: fmt.Sprintf(`object %s type commit tag tag-with-timestamp tagger root 12345 +0000 -`, +`, commitID), }, { desc: "signature with time and timezone", - objectID: "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + objectID: commitID, objectType: "commit", tagName: []byte("tag-with-timezone"), tagBody: []byte(""), @@ -206,11 +207,11 @@ tagger root 12345 +0000 Email: []byte("root@localhost"), }, authorDate: time.Unix(12345, 0).In(time.FixedZone("myzone", -60*60)), - expectedTag: `object c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd + expectedTag: fmt.Sprintf(`object %s type commit tag tag-with-timezone tagger root 12345 -0100 -`, +`, commitID), }, } { t.Run(tc.desc, func(t *testing.T) { @@ -231,7 +232,8 @@ tagger root 12345 -0100 func TestRepo_ReadObject(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("content")) for _, tc := range []struct { desc string @@ -241,14 +243,13 @@ func TestRepo_ReadObject(t *testing.T) { }{ { desc: "invalid object", - oid: git.ZeroOID, - error: InvalidObjectError(git.ZeroOID.String()), + oid: gittest.DefaultObjectHash.ZeroOID, + error: InvalidObjectError(gittest.DefaultObjectHash.ZeroOID.String()), }, { - desc: "valid object", - // README in gitlab-test - oid: "3742e48c1108ced3bf45ac633b34b65ac3f2af04", - content: "Sample repo for testing gitlab features\n", + desc: "valid object", + oid: blobID, + content: "content", }, } { t.Run(tc.desc, func(t *testing.T) { @@ -260,9 +261,48 @@ func TestRepo_ReadObject(t *testing.T) { } func TestRepo_ReadCommit(t *testing.T) { + if gittest.ObjectHashIsSHA256() { + t.Skip("this test is hash-agnostic, but depends on the `git/catfile` package that has not yet been converted") + } + ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + + firstParentID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("first parent")) + secondParentID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("second parent")) + + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "file", Mode: "100644", Content: "content"}, + }) + commitWithoutTrailers := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(firstParentID, secondParentID), + gittest.WithTree(treeID), + gittest.WithMessage("subject\n\nbody\n"), + gittest.WithBranch("main"), + ) + commitWithTrailers := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(commitWithoutTrailers), + gittest.WithTree(treeID), + gittest.WithMessage("with trailers\n\ntrailers\n\nSigned-off-by: John Doe "), + ) + + // We can't use git-commit-tree(1) directly, but have to manually write signed commits. + signedCommit := text.ChompBytes(gittest.ExecOpts(t, cfg, gittest.ExecConfig{ + Stdin: strings.NewReader(fmt.Sprintf( + `tree %s +parent %s +author %[3]s +committer %[3]s +gpgsig -----BEGIN PGP SIGNATURE----- +some faked pgp-signature + -----END PGP SIGNATURE----- + +signed commit subject + +signed commit body +`, treeID, firstParentID, gittest.DefaultCommitterSignature)), + }, "-C", repoPath, "hash-object", "-t", "commit", "-w", "--stdin")) for _, tc := range []struct { desc string @@ -273,118 +313,92 @@ func TestRepo_ReadCommit(t *testing.T) { }{ { desc: "invalid commit", - revision: git.ZeroOID.Revision(), + revision: gittest.DefaultObjectHash.ZeroOID.Revision(), expectedErr: ErrObjectNotFound, }, { desc: "invalid commit with trailers", - revision: git.ZeroOID.Revision(), + revision: gittest.DefaultObjectHash.ZeroOID.Revision(), expectedErr: ErrObjectNotFound, opts: []ReadCommitOpt{WithTrailers()}, }, { desc: "valid commit", - revision: "refs/heads/master", + revision: "refs/heads/main", expectedCommit: &gitalypb.GitCommit{ - Id: "1e292f8fedd741b75372e19097c76d327140c312", - TreeId: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + Id: commitWithoutTrailers.String(), + TreeId: treeID.String(), ParentIds: []string{ - "7975be0116940bf2ad4321f79d02a55c5f7779aa", - "c1c67abbaf91f624347bb3ae96eabe3a1b742478", - }, - Subject: []byte("Merge branch 'cherry-pick-ce369011' into 'master'"), - Body: []byte("Merge branch 'cherry-pick-ce369011' into 'master'\n\nAdd file with a _flattable_ path\n\nSee merge request gitlab-org/gitlab-test!35"), - BodySize: 128, - Author: &gitalypb.CommitAuthor{ - Name: []byte("Drew Blessing"), - Email: []byte("drew@blessing.io"), - Date: ×tamppb.Timestamp{ - Seconds: 1540830087, - }, - Timezone: []byte("+0000"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Drew Blessing"), - Email: []byte("drew@blessing.io"), - Date: ×tamppb.Timestamp{ - Seconds: 1540830087, - }, - Timezone: []byte("+0000"), + firstParentID.String(), + secondParentID.String(), }, + Subject: []byte("subject"), + Body: []byte("subject\n\nbody\n"), + BodySize: 14, + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, }, }, { desc: "trailers do not get parsed without WithTrailers()", - revision: "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + revision: commitWithTrailers.Revision(), expectedCommit: &gitalypb.GitCommit{ - Id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e", - TreeId: "a6973545d42361b28bfba5ced3b75dba5848b955", + Id: commitWithTrailers.String(), + TreeId: treeID.String(), ParentIds: []string{ - "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", + commitWithoutTrailers.String(), }, - Subject: []byte("Add submodule from gitlab.com"), - Body: []byte("Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \n"), - BodySize: 98, - Author: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{ - Seconds: 1393491698, - }, - Timezone: []byte("+0200"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{ - Seconds: 1393491698, - }, - Timezone: []byte("+0200"), - }, - SignatureType: gitalypb.SignatureType_PGP, + Subject: []byte("with trailers"), + Body: []byte("with trailers\n\ntrailers\n\nSigned-off-by: John Doe "), + BodySize: 71, + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, }, }, { desc: "trailers get parsed with WithTrailers()", - revision: "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + revision: commitWithTrailers.Revision(), opts: []ReadCommitOpt{WithTrailers()}, expectedCommit: &gitalypb.GitCommit{ - Id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e", - TreeId: "a6973545d42361b28bfba5ced3b75dba5848b955", + Id: commitWithTrailers.String(), + TreeId: treeID.String(), ParentIds: []string{ - "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", + commitWithoutTrailers.String(), }, - Subject: []byte("Add submodule from gitlab.com"), - Body: []byte("Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \n"), - BodySize: 98, - Author: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{ - Seconds: 1393491698, - }, - Timezone: []byte("+0200"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{ - Seconds: 1393491698, - }, - Timezone: []byte("+0200"), - }, - SignatureType: gitalypb.SignatureType_PGP, + Subject: []byte("with trailers"), + Body: []byte("with trailers\n\ntrailers\n\nSigned-off-by: John Doe "), + BodySize: 71, + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, Trailers: []*gitalypb.CommitTrailer{ { Key: []byte("Signed-off-by"), - Value: []byte("Dmitriy Zaporozhets "), + Value: []byte("John Doe "), }, }, }, }, + { + desc: "with PGP signature", + revision: git.Revision(signedCommit), + opts: []ReadCommitOpt{}, + expectedCommit: &gitalypb.GitCommit{ + Id: signedCommit, + TreeId: treeID.String(), + ParentIds: []string{ + firstParentID.String(), + }, + Subject: []byte("signed commit subject"), + Body: []byte("signed commit subject\n\nsigned commit body\n"), + BodySize: 42, + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, + SignatureType: gitalypb.SignatureType_PGP, + }, + }, { desc: "not a commit", - revision: "refs/heads/master^{tree}", + revision: "refs/heads/main^{tree}", expectedErr: ErrObjectNotFound, }, } { @@ -399,7 +413,10 @@ func TestRepo_ReadCommit(t *testing.T) { func TestRepo_IsAncestor(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + + parentCommitID := gittest.WriteCommit(t, cfg, repoPath) + childCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(parentCommitID)) for _, tc := range []struct { desc string @@ -410,42 +427,42 @@ func TestRepo_IsAncestor(t *testing.T) { }{ { desc: "parent is ancestor", - parent: "HEAD~1", - child: "HEAD", + parent: parentCommitID.Revision(), + child: childCommitID.Revision(), isAncestor: true, }, { desc: "parent is not ancestor", - parent: "HEAD", - child: "HEAD~1", + parent: childCommitID.Revision(), + child: parentCommitID.Revision(), isAncestor: false, }, { desc: "parent is not valid commit", - parent: git.ZeroOID.Revision(), - child: "HEAD", - errorMatcher: func(t testing.TB, err error) { - require.Equal(t, InvalidCommitError(git.ZeroOID), err) + parent: gittest.DefaultObjectHash.ZeroOID.Revision(), + child: childCommitID.Revision(), + errorMatcher: func(tb testing.TB, err error) { + require.Equal(tb, InvalidCommitError(gittest.DefaultObjectHash.ZeroOID), err) }, }, { desc: "child is not valid commit", - parent: "HEAD", - child: git.ZeroOID.Revision(), - errorMatcher: func(t testing.TB, err error) { - require.Equal(t, InvalidCommitError(git.ZeroOID), err) + parent: childCommitID.Revision(), + child: gittest.DefaultObjectHash.ZeroOID.Revision(), + errorMatcher: func(tb testing.TB, err error) { + require.Equal(tb, InvalidCommitError(gittest.DefaultObjectHash.ZeroOID), err) }, }, { desc: "child points to a tree", - parent: "HEAD", - child: "HEAD^{tree}", - errorMatcher: func(t testing.TB, actualErr error) { - treeOID, err := repo.ResolveRevision(ctx, "HEAD^{tree}") - require.NoError(t, err) - require.EqualError(t, actualErr, fmt.Sprintf( - `determine ancestry: exit status 128, stderr: "error: object %s is a tree, not a commit\nfatal: Not a valid commit name HEAD^{tree}\n"`, - treeOID, + parent: childCommitID.Revision(), + child: childCommitID.Revision() + "^{tree}", + errorMatcher: func(tb testing.TB, actualErr error) { + treeOID, err := repo.ResolveRevision(ctx, childCommitID.Revision()+"^{tree}") + require.NoError(tb, err) + require.EqualError(tb, actualErr, fmt.Sprintf( + `determine ancestry: exit status 128, stderr: "error: object %s is a tree, not a commit\nfatal: Not a valid commit name %s^{tree}\n"`, + treeOID, childCommitID, )) }, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths.go index 0c6e32adad..65d0799f62 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths.go @@ -5,8 +5,8 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" ) // Path returns the on-disk path of the repository. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths_test.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths_test.go index 290690a089..6ced8e6125 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/paths_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/paths_test.go @@ -6,21 +6,27 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" ) func TestRepo_Path(t *testing.T) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + t.Run("valid repository", func(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) path, err := repo.Path() @@ -29,7 +35,9 @@ func TestRepo_Path(t *testing.T) { }) t.Run("deleted repository", func(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) require.NoError(t, os.RemoveAll(repoPath)) @@ -39,7 +47,9 @@ func TestRepo_Path(t *testing.T) { }) t.Run("non-git repository", func(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Recreate the repository as a simple empty directory to simulate @@ -53,10 +63,13 @@ func TestRepo_Path(t *testing.T) { } func TestRepo_ObjectDirectoryPath(t *testing.T) { - cfg, repoProto, repoPath := testcfg.BuildWithRepo(t) - locator := config.NewLocator(cfg) - ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + locator := config.NewLocator(cfg) quarantine, err := quarantine.New(ctx, repoProto, locator) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs.go index 5b0f9e4dfc..f76975e281 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs.go @@ -11,10 +11,10 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" ) // HasRevision checks if a revision in the repository exists. This will not @@ -56,8 +56,13 @@ func (repo *Repo) ResolveRevision(ctx context.Context, revision git.Revision) (g return "", err } + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return "", fmt.Errorf("detecting object hash: %w", err) + } + hex := strings.TrimSpace(stdout.String()) - oid, err := git.NewObjectIDFromHex(hex) + oid, err := objectHash.FromHex(hex) if err != nil { return "", fmt.Errorf("unsupported object hash %q: %w", hex, err) } @@ -170,7 +175,7 @@ func (repo *Repo) SetDefaultBranch(ctx context.Context, txManager transaction.Ma return repo.setDefaultBranchWithTransaction(ctx, txManager, reference) } -// setDefaultBranchWithTransaction sets the repostory's HEAD to point to the given reference +// setDefaultBranchWithTransaction sets the repository's HEAD to point to the given reference // using a safe locking file writer and commits the transaction if one exists in the context func (repo *Repo) setDefaultBranchWithTransaction(ctx context.Context, txManager transaction.Manager, reference git.ReferenceName) error { valid, err := git.CheckRefFormat(ctx, repo.gitCmdFactory, reference.String()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs_test.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs_test.go index bd50f13475..deed4ab3b1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/refs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/refs_test.go @@ -7,35 +7,33 @@ import ( "fmt" "os" "path/filepath" + "runtime" + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/peer" ) -const ( - masterOID = git.ObjectID("1e292f8fedd741b75372e19097c76d327140c312") - nonexistentOID = git.ObjectID("ba4f184e126b751d1bffad5897f263108befc780") -) - func TestRepo_ContainsRef(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master")) testcases := []struct { desc string @@ -71,7 +69,8 @@ func TestRepo_ContainsRef(t *testing.T) { func TestRepo_GetReference(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master")) testcases := []struct { desc string @@ -82,7 +81,7 @@ func TestRepo_GetReference(t *testing.T) { { desc: "fully qualified master branch", ref: "refs/heads/master", - expected: git.NewReference("refs/heads/master", masterOID.String()), + expected: git.NewReference("refs/heads/master", commitID.String()), }, { desc: "unqualified master branch fails", @@ -118,17 +117,13 @@ func TestRepo_GetReference(t *testing.T) { func TestRepo_GetReferenceWithAmbiguousRefs(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t, withDisabledHooks()) + cfg, repo, repoPath := setupRepo(t, withDisabledHooks()) - currentOID, err := repo.ResolveRevision(ctx, "refs/heads/master") - require.NoError(t, err) - - prevOID, err := repo.ResolveRevision(ctx, "refs/heads/master~") - require.NoError(t, err) + prevOID := gittest.WriteCommit(t, cfg, repoPath) + currentOID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(prevOID), gittest.WithBranch("master")) for _, ref := range []git.ReferenceName{ "refs/heads/something/master", - "refs/heads/MASTER", "refs/heads/master2", "refs/heads/masterx", "refs/heads/refs/heads/master", @@ -136,7 +131,12 @@ func TestRepo_GetReferenceWithAmbiguousRefs(t *testing.T) { "refs/master", "refs/tags/master", } { - require.NoError(t, repo.UpdateRef(ctx, ref, prevOID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, ref, prevOID, gittest.DefaultObjectHash.ZeroOID)) + } + + // core.ignorecase is default-enabled on macOS, causing 'MASTER' to match 'master' + if runtime.GOOS != "darwin" { + require.NoError(t, repo.UpdateRef(ctx, "refs/heads/MASTER", prevOID, gittest.DefaultObjectHash.ZeroOID)) } ref, err := repo.GetReference(ctx, "refs/heads/master") @@ -150,59 +150,65 @@ func TestRepo_GetReferenceWithAmbiguousRefs(t *testing.T) { func TestRepo_GetReferences(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) - masterBranch, err := repo.GetReference(ctx, "refs/heads/master") + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature")) + gittest.WriteTag(t, cfg, repoPath, "v1.0.0", "refs/heads/main") + + mainReference, err := repo.GetReference(ctx, "refs/heads/main") + require.NoError(t, err) + featureReference, err := repo.GetReference(ctx, "refs/heads/feature") + require.NoError(t, err) + tagReference, err := repo.GetReference(ctx, "refs/tags/v1.0.0") require.NoError(t, err) testcases := []struct { - desc string - patterns []string - match func(t *testing.T, refs []git.Reference) + desc string + patterns []string + expectedRefs []git.Reference }{ { - desc: "master branch", - patterns: []string{"refs/heads/master"}, - match: func(t *testing.T, refs []git.Reference) { - require.Equal(t, []git.Reference{masterBranch}, refs) + desc: "main branch", + patterns: []string{"refs/heads/main"}, + expectedRefs: []git.Reference{ + mainReference, }, }, { desc: "two branches", - patterns: []string{"refs/heads/master", "refs/heads/feature"}, - match: func(t *testing.T, refs []git.Reference) { - featureBranch, err := repo.GetReference(ctx, "refs/heads/feature") - require.NoError(t, err) - - require.Equal(t, []git.Reference{featureBranch, masterBranch}, refs) + patterns: []string{"refs/heads/main", "refs/heads/feature"}, + expectedRefs: []git.Reference{ + featureReference, + mainReference, }, }, { desc: "matching subset is returned", - patterns: []string{"refs/heads/master", "refs/heads/nonexistent"}, - match: func(t *testing.T, refs []git.Reference) { - require.Equal(t, []git.Reference{masterBranch}, refs) + patterns: []string{"refs/heads/main", "refs/heads/nonexistent"}, + expectedRefs: []git.Reference{ + mainReference, }, }, { desc: "all references", - match: func(t *testing.T, refs []git.Reference) { - require.Len(t, refs, 97) + expectedRefs: []git.Reference{ + featureReference, + mainReference, + tagReference, }, }, { desc: "branches", patterns: []string{"refs/heads/"}, - match: func(t *testing.T, refs []git.Reference) { - require.Len(t, refs, 94) + expectedRefs: []git.Reference{ + featureReference, + mainReference, }, }, { desc: "non-existent branch", patterns: []string{"refs/heads/nonexistent"}, - match: func(t *testing.T, refs []git.Reference) { - require.Empty(t, refs) - }, }, } @@ -210,7 +216,7 @@ func TestRepo_GetReferences(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { refs, err := repo.GetReferences(ctx, tc.patterns...) require.NoError(t, err) - tc.match(t, refs) + require.Equal(t, tc.expectedRefs, refs) }) } } @@ -336,21 +342,42 @@ func TestRepo_GetRemoteReferences(t *testing.T) { func TestRepo_GetBranches(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + + mainID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main")) + featureID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature")) + thirdID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("third"), gittest.WithMessage("third")) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithReference("refs/different/namespace")) + gittest.WriteTag(t, cfg, repoPath, "v1.0.0", mainID.Revision()) refs, err := repo.GetBranches(ctx) require.NoError(t, err) - require.Len(t, refs, 94) + require.Equal(t, []git.Reference{ + {Name: "refs/heads/feature", Target: featureID.String()}, + {Name: "refs/heads/main", Target: mainID.String()}, + {Name: "refs/heads/third", Target: thirdID.String()}, + }, refs) } func TestRepo_UpdateRef(t *testing.T) { ctx := testhelper.Context(t) - cfg, repo, _ := setupRepo(t, withDisabledHooks()) + cfg, repo, repoPath := setupRepo(t, withDisabledHooks()) - otherRef, err := repo.GetReference(ctx, "refs/heads/gitaly-test-ref") + // We move this into a function so that we can re-seed the repository for each test. + seedRepo := func(t *testing.T, repoPath string) { + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("other"), gittest.WithMessage("other")) + } + seedRepo(t, repoPath) + + mainCommitID := gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/main") + otherRef, err := repo.GetReference(ctx, "refs/heads/other") require.NoError(t, err) + nonexistentOID := git.ObjectID(strings.Repeat("1", gittest.DefaultObjectHash.EncodedLen())) + testcases := []struct { desc string ref string @@ -359,95 +386,100 @@ func TestRepo_UpdateRef(t *testing.T) { verify func(t *testing.T, repo *Repo, err error) }{ { - desc: "successfully update master", - ref: "refs/heads/master", + desc: "successfully update main", + ref: "refs/heads/main", newValue: git.ObjectID(otherRef.Target), - oldValue: masterOID, + oldValue: mainCommitID, verify: func(t *testing.T, repo *Repo, err error) { require.NoError(t, err) - ref, err := repo.GetReference(ctx, "refs/heads/master") + ref, err := repo.GetReference(ctx, "refs/heads/main") require.NoError(t, err) require.Equal(t, ref.Target, otherRef.Target) }, }, { desc: "update fails with stale oldValue", - ref: "refs/heads/master", + ref: "refs/heads/main", newValue: git.ObjectID(otherRef.Target), oldValue: nonexistentOID, verify: func(t *testing.T, repo *Repo, err error) { require.Error(t, err) - ref, err := repo.GetReference(ctx, "refs/heads/master") + ref, err := repo.GetReference(ctx, "refs/heads/main") require.NoError(t, err) - require.Equal(t, ref.Target, masterOID.String()) + require.Equal(t, ref.Target, mainCommitID.String()) }, }, { desc: "update fails with invalid newValue", - ref: "refs/heads/master", + ref: "refs/heads/main", newValue: nonexistentOID, - oldValue: masterOID, + oldValue: mainCommitID, verify: func(t *testing.T, repo *Repo, err error) { require.Error(t, err) - ref, err := repo.GetReference(ctx, "refs/heads/master") + ref, err := repo.GetReference(ctx, "refs/heads/main") require.NoError(t, err) - require.Equal(t, ref.Target, masterOID.String()) + require.Equal(t, ref.Target, mainCommitID.String()) }, }, { - desc: "successfully update master with empty oldValue", - ref: "refs/heads/master", + desc: "successfully update main with empty oldValue", + ref: "refs/heads/main", newValue: git.ObjectID(otherRef.Target), oldValue: "", verify: func(t *testing.T, repo *Repo, err error) { require.NoError(t, err) - ref, err := repo.GetReference(ctx, "refs/heads/master") + ref, err := repo.GetReference(ctx, "refs/heads/main") require.NoError(t, err) require.Equal(t, ref.Target, otherRef.Target) }, }, { desc: "updating unqualified branch fails", - ref: "master", + ref: "main", newValue: git.ObjectID(otherRef.Target), - oldValue: masterOID, + oldValue: mainCommitID, verify: func(t *testing.T, repo *Repo, err error) { require.Error(t, err) - ref, err := repo.GetReference(ctx, "refs/heads/master") + ref, err := repo.GetReference(ctx, "refs/heads/main") require.NoError(t, err) - require.Equal(t, ref.Target, masterOID.String()) + require.Equal(t, ref.Target, mainCommitID.String()) }, }, { - desc: "deleting master succeeds", - ref: "refs/heads/master", - newValue: git.ZeroOID, - oldValue: masterOID, + desc: "deleting main succeeds", + ref: "refs/heads/main", + newValue: gittest.DefaultObjectHash.ZeroOID, + oldValue: mainCommitID, verify: func(t *testing.T, repo *Repo, err error) { require.NoError(t, err) - _, err = repo.GetReference(ctx, "refs/heads/master") + _, err = repo.GetReference(ctx, "refs/heads/main") require.Error(t, err) }, }, { desc: "creating new branch succeeds", ref: "refs/heads/new", - newValue: masterOID, - oldValue: git.ZeroOID, + newValue: mainCommitID, + oldValue: gittest.DefaultObjectHash.ZeroOID, verify: func(t *testing.T, repo *Repo, err error) { require.NoError(t, err) ref, err := repo.GetReference(ctx, "refs/heads/new") require.NoError(t, err) - require.Equal(t, ref.Target, masterOID.String()) + require.Equal(t, ref.Target, mainCommitID.String()) }, }, } for _, tc := range testcases { t.Run(tc.desc, func(t *testing.T) { - // Re-create repo for each testcase. - repoProto, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + // We need to re-seed the repository every time so that we don't carry over + // the state. + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(repo.locator, repo.gitCmdFactory, repo.catfileCache, repoProto) + seedRepo(t, repoPath) + err := repo.UpdateRef(ctx, git.ReferenceName(tc.ref), tc.newValue, tc.oldValue) tc.verify(t, repo, err) }) @@ -456,7 +488,10 @@ func TestRepo_UpdateRef(t *testing.T) { func TestRepo_SetDefaultBranch(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _ := setupRepo(t) + cfg, repo, repoPath := setupRepo(t) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature")) txManager := transaction.NewTrackingManager() @@ -618,8 +653,8 @@ func TestRepo_SetDefaultBranch_errors(t *testing.T) { func TestGuessHead(t *testing.T) { cfg, repo, repoPath := setupRepo(t) - commit1 := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/master")) - commit2 := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/feature")) + commit1 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main")) + commit2 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature")) for _, tc := range []struct { desc string @@ -636,37 +671,37 @@ func TestGuessHead(t *testing.T) { { desc: "matching default branch", cmds: [][]string{ - {"update-ref", git.DefaultRef.String(), commit1}, - {"update-ref", git.LegacyDefaultRef.String(), commit2}, - {"update-ref", "refs/heads/apple", commit1}, - {"update-ref", "refs/heads/feature", commit1}, - {"update-ref", "refs/heads/zucchini", commit1}, + {"update-ref", git.DefaultRef.String(), commit1.String()}, + {"update-ref", git.LegacyDefaultRef.String(), commit2.String()}, + {"update-ref", "refs/heads/apple", commit1.String()}, + {"update-ref", "refs/heads/feature", commit1.String()}, + {"update-ref", "refs/heads/zucchini", commit1.String()}, }, - head: git.NewReference("HEAD", commit1), + head: git.NewReference("HEAD", commit1.String()), expected: git.DefaultRef, }, { desc: "matching default legacy branch", cmds: [][]string{ - {"update-ref", git.DefaultRef.String(), commit2}, - {"update-ref", git.LegacyDefaultRef.String(), commit1}, - {"update-ref", "refs/heads/apple", commit1}, - {"update-ref", "refs/heads/feature", commit1}, - {"update-ref", "refs/heads/zucchini", commit1}, + {"update-ref", git.DefaultRef.String(), commit2.String()}, + {"update-ref", git.LegacyDefaultRef.String(), commit1.String()}, + {"update-ref", "refs/heads/apple", commit1.String()}, + {"update-ref", "refs/heads/feature", commit1.String()}, + {"update-ref", "refs/heads/zucchini", commit1.String()}, }, - head: git.NewReference("HEAD", commit1), + head: git.NewReference("HEAD", commit1.String()), expected: git.LegacyDefaultRef, }, { desc: "matching other branch", cmds: [][]string{ - {"update-ref", git.DefaultRef.String(), commit2}, - {"update-ref", git.LegacyDefaultRef.String(), commit2}, - {"update-ref", "refs/heads/apple", commit1}, - {"update-ref", "refs/heads/feature", commit1}, - {"update-ref", "refs/heads/zucchini", commit1}, + {"update-ref", git.DefaultRef.String(), commit2.String()}, + {"update-ref", git.LegacyDefaultRef.String(), commit2.String()}, + {"update-ref", "refs/heads/apple", commit1.String()}, + {"update-ref", "refs/heads/feature", commit1.String()}, + {"update-ref", "refs/heads/zucchini", commit1.String()}, }, - head: git.NewReference("HEAD", commit1), + head: git.NewReference("HEAD", commit1.String()), expected: "refs/heads/apple", }, { @@ -674,23 +709,23 @@ func TestGuessHead(t *testing.T) { cmds: [][]string{ {"update-ref", "-d", git.DefaultRef.String()}, {"update-ref", "-d", git.LegacyDefaultRef.String()}, - {"update-ref", "refs/heads/apple", commit1}, - {"update-ref", "refs/heads/feature", commit1}, - {"update-ref", "refs/heads/zucchini", commit1}, + {"update-ref", "refs/heads/apple", commit1.String()}, + {"update-ref", "refs/heads/feature", commit1.String()}, + {"update-ref", "refs/heads/zucchini", commit1.String()}, }, - head: git.NewReference("HEAD", commit1), + head: git.NewReference("HEAD", commit1.String()), expected: "refs/heads/apple", }, { desc: "no match", cmds: [][]string{ - {"update-ref", git.DefaultRef.String(), commit2}, - {"update-ref", git.LegacyDefaultRef.String(), commit2}, - {"update-ref", "refs/heads/apple", commit2}, - {"update-ref", "refs/heads/feature", commit2}, - {"update-ref", "refs/heads/zucchini", commit2}, + {"update-ref", git.DefaultRef.String(), commit2.String()}, + {"update-ref", git.LegacyDefaultRef.String(), commit2.String()}, + {"update-ref", "refs/heads/apple", commit2.String()}, + {"update-ref", "refs/heads/feature", commit2.String()}, + {"update-ref", "refs/heads/zucchini", commit2.String()}, }, - head: git.NewReference("HEAD", commit1), + head: git.NewReference("HEAD", commit1.String()), expectedErr: fmt.Errorf("guess head: %w", git.ErrReferenceNotFound), }, } { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote.go index 16a4d4e366..236ef3363f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote.go @@ -8,8 +8,8 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // FetchOptsTags controls what tags needs to be imported on fetch. @@ -81,6 +81,11 @@ func (repo *Repo) FetchRemote(ctx context.Context, remoteName string, opts Fetch commandOptions := []git.CmdOpt{ git.WithEnv(opts.Env...), git.WithStderr(opts.Stderr), + git.WithConfig(git.ConfigPair{ + // Git is so kind to point out that we asked it to not show forced updates + // by default, so we need to ask it not to do that. + Key: "advice.fetchShowForcedUpdates", Value: "false", + }), } if opts.DisableTransactions { commandOptions = append(commandOptions, git.WithDisabledHooks()) @@ -128,14 +133,6 @@ func (repo *Repo) FetchInternal( commandOptions := []git.CmdOpt{ git.WithEnv(opts.Env...), git.WithStderr(opts.Stderr), - // We've observed performance issues when fetching into big repositories part of an - // object pool. The root cause of this seems to be the connectivity check, which by - // default will also include references of any alternates. Given that object pools - // often have hundreds of thousands of references, this is quite expensive to - // compute. Below config entry will disable listing of alternate refs: they - // shouldn't even be included in the negotiation phase, so they aren't going to - // matter in the connectivity check either. - git.WithConfig(git.ConfigPair{Key: "core.alternateRefsCommand", Value: "exit 0 #"}), git.WithInternalFetchWithSidechannel( &gitalypb.SSHUploadPackWithSidechannelRequest{ Repository: remoteRepo, @@ -143,6 +140,11 @@ func (repo *Repo) FetchInternal( GitProtocol: git.ProtocolV2, }, ), + git.WithConfig(git.ConfigPair{ + // Git is so kind to point out that we asked it to not show forced updates + // by default, so we need to ask it not to do that. + Key: "advice.fetchShowForcedUpdates", Value: "false", + }), } if opts.DisableTransactions { @@ -196,6 +198,13 @@ func (opts FetchOpts) buildFlags() []git.Option { flags = append(flags, git.Flag{Name: "--atomic"}) } + // Even if we ask Git to not print any output and to force-update branches it will still + // compute whether branches have been force-updated only to discard that information again. + // Let's ask it not to given that this check can be quite expensive. + if !opts.Verbose && opts.Force { + flags = append(flags, git.Flag{Name: "--no-show-forced-updates"}) + } + return flags } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_extra_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_extra_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_extra_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_extra_test.go index 7f4afd3502..dafd7e8ae2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_extra_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_extra_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package localrepo_test import ( @@ -6,17 +8,17 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -25,7 +27,7 @@ func TestRepo_FetchInternal(t *testing.T) { ctx := testhelper.Context(t) cfg := testcfg.Build(t) - gitCmdFactory, readGitProtocol := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) cfg.SocketPath = testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterSSHServiceServer(srv, ssh.NewServer( @@ -36,8 +38,7 @@ func TestRepo_FetchInternal(t *testing.T) { gitalypb.RegisterHookServiceServer(srv, hook.NewServer( deps.GetHookManager(), deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - )) + deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( deps.GetCfg(), deps.GetRubyServer(), @@ -49,24 +50,19 @@ func TestRepo_FetchInternal(t *testing.T) { deps.GetGit2goExecutor(), deps.GetHousekeepingManager(), )) - }, testserver.WithGitCommandFactory(gitCmdFactory)) + }, testserver.WithGitCommandFactory(protocolDetectingFactory)) - remoteRepoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - remoteRepo := localrepo.NewTestRepo(t, cfg, remoteRepoProto) testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) - remoteOID, err := remoteRepo.ResolveRevision(ctx, git.Revision("refs/heads/master")) - require.NoError(t, err) - - tagV100OID, err := remoteRepo.ResolveRevision(ctx, git.Revision("refs/tags/v1.0.0")) - require.NoError(t, err) - - tagV110OID, err := remoteRepo.ResolveRevision(ctx, git.Revision("refs/tags/v1.1.0")) - require.NoError(t, err) + remoteRepoProto, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg) + remoteOID := gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("master")) + tagV100OID := gittest.WriteTag(t, cfg, remoteRepoPath, "v1.0.0", remoteOID.Revision(), gittest.WriteTagConfig{ + Message: "v1.0.0", + }) + tagV110OID := gittest.WriteTag(t, cfg, remoteRepoPath, "v1.1.0", remoteOID.Revision(), gittest.WriteTagConfig{ + Message: "v1.1.0", + }) t.Run("refspec with tag", func(t *testing.T) { ctx := testhelper.MergeIncomingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) @@ -95,7 +91,7 @@ func TestRepo_FetchInternal(t *testing.T) { require.NoDirExists(t, filepath.Join(repoPath, "objects/info/commit-graphs")) // Assert that we're using the expected Git protocol version, which is protocol v2. - require.Equal(t, "GIT_PROTOCOL=version=2\n", readGitProtocol()) + require.Equal(t, "GIT_PROTOCOL=version=2\n", protocolDetectingFactory.ReadProtocol(t)) require.NoFileExists(t, filepath.Join(repoPath, "FETCH_HEAD")) }) @@ -204,14 +200,12 @@ func TestRepo_FetchInternal(t *testing.T) { t.Run("pruning", func(t *testing.T) { ctx := testhelper.MergeIncomingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) - repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Create a local reference. Given that it doesn't exist on the remote side, it // would get pruned if we pass `--prune`. - require.NoError(t, repo.UpdateRef(ctx, "refs/heads/prune-me", remoteOID, git.ZeroOID)) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("prune-me")) // By default, refs are not pruned. require.NoError(t, repo.FetchInternal( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_test.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_test.go index ba92591046..00208b4612 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/remote_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/remote_test.go @@ -10,12 +10,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestRepo_FetchRemote(t *testing.T) { @@ -28,12 +28,20 @@ func TestRepo_FetchRemote(t *testing.T) { defer catfileCache.Stop() locator := config.NewLocator(cfg) + _, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + commitID := gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("main")) + tagID := gittest.WriteTag(t, cfg, remoteRepoPath, "v1.0.0", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", + }) + initBareWithRemote := func(t *testing.T, remote string) (*Repo, string) { t.Helper() - _, remoteRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - - clientRepo, clientRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + clientRepo, clientRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) cmd := gittest.NewCommand(t, cfg, "-C", clientRepoPath, "remote", "add", remote, remoteRepoPath) err := cmd.Run() @@ -53,7 +61,9 @@ func TestRepo_FetchRemote(t *testing.T) { }) t.Run("unknown remote", func(t *testing.T) { - repoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, repoProto) var stderr bytes.Buffer @@ -68,26 +78,27 @@ func TestRepo_FetchRemote(t *testing.T) { var stderr bytes.Buffer require.NoError(t, repo.FetchRemote(ctx, "origin", FetchOpts{Stderr: &stderr})) - require.Empty(t, stderr.String(), "it should not produce output as it is called with --quite flag by default") + require.Empty(t, stderr.String(), "it should not produce output as it is called with --quiet flag by default") refs, err := repo.GetReferences(ctx) require.NoError(t, err) - require.Contains(t, refs, git.Reference{Name: "refs/remotes/origin/'test'", Target: "e56497bb5f03a90a51293fc6d516788730953899"}) - require.Contains(t, refs, git.Reference{Name: "refs/tags/v1.1.0", Target: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b"}) + require.Contains(t, refs, git.Reference{Name: "refs/remotes/origin/main", Target: commitID.String()}) + require.Contains(t, refs, git.Reference{Name: "refs/tags/v1.0.0", Target: tagID.String()}) - sha, err := repo.ResolveRevision(ctx, git.Revision("refs/remotes/origin/master^{commit}")) + fetchedCommitID, err := repo.ResolveRevision(ctx, git.Revision("refs/remotes/origin/main^{commit}")) require.NoError(t, err, "the object from remote should exists in local after fetch done") - require.Equal(t, git.ObjectID("1e292f8fedd741b75372e19097c76d327140c312"), sha) + require.Equal(t, commitID, fetchedCommitID) require.NoFileExists(t, filepath.Join(repoPath, "FETCH_HEAD")) }) t.Run("with env", func(t *testing.T) { - _, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - testRepo, testRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, testRepo) - gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", sourceRepoPath) + gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", remoteRepoPath) var stderr bytes.Buffer require.NoError(t, repo.FetchRemote(ctx, "source", FetchOpts{Stderr: &stderr, Env: []string{"GIT_TRACE=1"}})) @@ -95,11 +106,12 @@ func TestRepo_FetchRemote(t *testing.T) { }) t.Run("with disabled transactions", func(t *testing.T) { - _, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - testRepo, testRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, testRepo) - gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", sourceRepoPath) + gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", remoteRepoPath) var stderr bytes.Buffer require.NoError(t, repo.FetchRemote(ctx, "source", FetchOpts{ @@ -111,16 +123,18 @@ func TestRepo_FetchRemote(t *testing.T) { }) t.Run("with globals", func(t *testing.T) { - _, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - testRepo, testRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, testRepo) - gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", sourceRepoPath) + gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", remoteRepoPath) require.NoError(t, repo.FetchRemote(ctx, "source", FetchOpts{})) - gittest.Exec(t, cfg, "-C", testRepoPath, "branch", "--track", "testing-fetch-prune", "refs/remotes/source/markdown") - gittest.Exec(t, cfg, "-C", sourceRepoPath, "branch", "-D", "markdown") + // Write a commit into the remote's reference namespace that doesn't exist in the + // remote and that would thus be pruned. + gittest.WriteCommit(t, cfg, testRepoPath, gittest.WithReference("refs/remotes/source/markdown")) require.NoError(t, repo.FetchRemote( ctx, @@ -138,16 +152,17 @@ func TestRepo_FetchRemote(t *testing.T) { }) t.Run("with prune", func(t *testing.T) { - _, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - testRepo, testRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, testRepo) - gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", sourceRepoPath) + gittest.Exec(t, cfg, "-C", testRepoPath, "remote", "add", "source", remoteRepoPath) require.NoError(t, repo.FetchRemote(ctx, "source", FetchOpts{})) - - gittest.Exec(t, cfg, "-C", testRepoPath, "branch", "--track", "testing-fetch-prune", "refs/remotes/source/markdown") - gittest.Exec(t, cfg, "-C", sourceRepoPath, "branch", "-D", "markdown") + // Write a commit into the remote's reference namespace that doesn't exist in the + // remote and that would thus be pruned. + gittest.WriteCommit(t, cfg, testRepoPath, gittest.WithReference("refs/remotes/source/markdown")) require.NoError(t, repo.FetchRemote(ctx, "source", FetchOpts{Prune: true})) @@ -184,15 +199,41 @@ func TestRepo_FetchRemote(t *testing.T) { require.Contains(t, err.Error(), "fatal: 'doesnotexist' does not appear to be a git repository") require.IsType(t, err, ErrFetchFailed{}) }) + + t.Run("generates reverse index", func(t *testing.T) { + repo, repoPath := initBareWithRemote(t, "origin") + + // The repository has no objects yet, so there shouldn't be any packfile either. + packfiles, err := filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.pack")) + require.NoError(t, err) + require.Empty(t, packfiles) + + // Same goes for reverse indices, naturally. + reverseIndices, err := filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.rev")) + require.NoError(t, err) + require.Empty(t, reverseIndices) + + require.NoError(t, repo.FetchRemote(ctx, "origin", FetchOpts{})) + + // After the fetch we should end up with a single packfile. + packfiles, err = filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.pack")) + require.NoError(t, err) + require.Len(t, packfiles, 1) + + // And furthermore, that packfile should have a reverse index. + reverseIndices, err = filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.rev")) + require.NoError(t, err) + require.Len(t, reverseIndices, 1) + }) } // captureGitSSHCommand creates a new intercepting command factory which captures the -// GIT_SSH_COMMAND environment variable. The returned function can be used to read the variables's +// GIT_SSH_COMMAND environment variable. The returned function can be used to read the variable's // value. -func captureGitSSHCommand(ctx context.Context, t testing.TB, cfg config.Cfg) (git.CommandFactory, func() ([]byte, error)) { - envPath := filepath.Join(testhelper.TempDir(t), "GIT_SSH_PATH") +func captureGitSSHCommand(ctx context.Context, tb testing.TB, cfg config.Cfg) (git.CommandFactory, func() ([]byte, error)) { + envPath := filepath.Join(testhelper.TempDir(tb), "GIT_SSH_PATH") - gitCmdFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + gitCmdFactory := gittest.NewInterceptingCommandFactory(ctx, tb, cfg, func(execEnv git.ExecutionEnvironment) string { return fmt.Sprintf( `#!/usr/bin/env bash if test -z "${GIT_SSH_COMMAND+x}" @@ -213,37 +254,46 @@ func captureGitSSHCommand(ctx context.Context, t testing.TB, cfg config.Cfg) (gi func TestRepo_Push(t *testing.T) { ctx := testhelper.Context(t) - cfg, sourceRepoPb, _ := testcfg.BuildWithRepo(t) + cfg := testcfg.Build(t) gitCmdFactory, readSSHCommand := captureGitSSHCommand(ctx, t, cfg) catfileCache := catfile.NewCache(cfg) t.Cleanup(catfileCache.Stop) locator := config.NewLocator(cfg) - sourceRepo := New(locator, gitCmdFactory, catfileCache, sourceRepoPb) + sourceRepoProto, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + sourceRepo := New(locator, gitCmdFactory, catfileCache, sourceRepoProto) + gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithBranch("master")) + gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithBranch("feature")) - setupPushRepo := func(t testing.TB) (*Repo, string, []git.ConfigPair) { - repoProto, repopath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setupPushRepo := func(tb testing.TB) (*Repo, string, []git.ConfigPair) { + repoProto, repopath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) return New(locator, gitCmdFactory, catfileCache, repoProto), repopath, nil } - setupDivergedRepo := func(t testing.TB) (*Repo, string, []git.ConfigPair) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setupDivergedRepo := func(tb testing.TB) (*Repo, string, []git.ConfigPair) { + repoProto, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := New(locator, gitCmdFactory, catfileCache, repoProto) - // set up master as a divergin ref in push repo + // set up master as a diverging ref in push repo sourceMaster, err := sourceRepo.GetReference(ctx, "refs/heads/master") - require.NoError(t, err) + require.NoError(tb, err) - require.NoError(t, sourceRepo.Push(ctx, repoPath, []string{"refs/*"}, PushOptions{})) - divergedMaster := gittest.WriteCommit(t, cfg, repoPath, + require.NoError(tb, sourceRepo.Push(ctx, repoPath, []string{"refs/*"}, PushOptions{})) + divergedMaster := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch("master"), gittest.WithParents(git.ObjectID(sourceMaster.Target)), ) master, err := repo.GetReference(ctx, "refs/heads/master") - require.NoError(t, err) - require.Equal(t, master.Target, divergedMaster.String()) + require.NoError(tb, err) + require.Equal(tb, master.Target, divergedMaster.String()) return repo, repoPath, nil } @@ -301,8 +351,10 @@ func TestRepo_Push(t *testing.T) { }, { desc: "invalid remote", - setupPushRepo: func(t testing.TB) (*Repo, string, []git.ConfigPair) { - repoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setupPushRepo: func(tb testing.TB) (*Repo, string, []git.ConfigPair) { + repoProto, _ := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) return New(locator, gitCmdFactory, catfileCache, repoProto), "", nil }, refspecs: []string{"refs/heads/master"}, @@ -310,8 +362,10 @@ func TestRepo_Push(t *testing.T) { }, { desc: "in-memory remote", - setupPushRepo: func(testing.TB) (*Repo, string, []git.ConfigPair) { - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + setupPushRepo: func(tb testing.TB) (*Repo, string, []git.ConfigPair) { + repoProto, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) return New(locator, gitCmdFactory, catfileCache, repoProto), "inmemory", []git.ConfigPair{ {Key: "remote.inmemory.url", Value: repoPath}, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo.go new file mode 100644 index 0000000000..ccd4db37e2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo.go @@ -0,0 +1,235 @@ +package localrepo + +import ( + "bytes" + "context" + "errors" + "fmt" + "io/fs" + "os" + "strconv" + "strings" + "sync" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// Repo represents a local Git repository. +type Repo struct { + repository.GitRepo + locator storage.Locator + gitCmdFactory git.CommandFactory + catfileCache catfile.Cache + + detectObjectHashOnce sync.Once + objectHash git.ObjectHash + objectHashErr error +} + +// New creates a new Repo from its protobuf representation. +func New(locator storage.Locator, gitCmdFactory git.CommandFactory, catfileCache catfile.Cache, repo repository.GitRepo) *Repo { + return &Repo{ + GitRepo: repo, + locator: locator, + gitCmdFactory: gitCmdFactory, + catfileCache: catfileCache, + } +} + +// NewTestRepo constructs a Repo. It is intended as a helper function for tests which assembles +// dependencies ad-hoc from the given config. +func NewTestRepo(tb testing.TB, cfg config.Cfg, repo repository.GitRepo, factoryOpts ...git.ExecCommandFactoryOption) *Repo { + tb.Helper() + + if cfg.SocketPath != testcfg.UnconfiguredSocketPath { + repo = gittest.RewrittenRepository(testhelper.Context(tb), tb, cfg, &gitalypb.Repository{ + StorageName: repo.GetStorageName(), + RelativePath: repo.GetRelativePath(), + GitObjectDirectory: repo.GetGitObjectDirectory(), + GitAlternateObjectDirectories: repo.GetGitAlternateObjectDirectories(), + }) + } + + gitCmdFactory, cleanup, err := git.NewExecCommandFactory(cfg, factoryOpts...) + tb.Cleanup(cleanup) + require.NoError(tb, err) + + catfileCache := catfile.NewCache(cfg) + tb.Cleanup(catfileCache.Stop) + + locator := config.NewLocator(cfg) + + return New(locator, gitCmdFactory, catfileCache, repo) +} + +// Exec creates a git command with the given args and Repo, executed in the +// Repo. It validates the arguments in the command before executing. +func (repo *Repo) Exec(ctx context.Context, cmd git.Cmd, opts ...git.CmdOpt) (*command.Command, error) { + return repo.gitCmdFactory.New(ctx, repo, cmd, opts...) +} + +// ExecAndWait is similar to Exec, but waits for the command to exit before +// returning. +func (repo *Repo) ExecAndWait(ctx context.Context, cmd git.Cmd, opts ...git.CmdOpt) error { + command, err := repo.Exec(ctx, cmd, opts...) + if err != nil { + return err + } + + return command.Wait() +} + +// GitVersion returns the Git version in use. +func (repo *Repo) GitVersion(ctx context.Context) (git.Version, error) { + return repo.gitCmdFactory.GitVersion(ctx) +} + +func errorWithStderr(err error, stderr []byte) error { + if len(stderr) == 0 { + return err + } + return fmt.Errorf("%w, stderr: %q", err, stderr) +} + +// repoSizeConfig can be used to pass in different options to +// git rev-list in determining the size of a repository. +type repoSizeConfig struct { + // ExcludeRefs is a list of ref glob patterns to exclude from the size + // calculation. + ExcludeRefs []string + // ExcludeAlternates will exclude objects in the alternates directory + // from being counted towards the total size of the repository. + ExcludeAlternates bool +} + +// RepoSizeOption is an option which can be passed to Size +type RepoSizeOption func(*repoSizeConfig) + +// WithExcludeRefs is an option for Size that excludes certain refs from the size +// calculation. The format must be a glob pattern. +// see https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---excludeltglob-patterngt +func WithExcludeRefs(excludeRefs ...string) RepoSizeOption { + return func(cfg *repoSizeConfig) { + cfg.ExcludeRefs = excludeRefs + } +} + +// WithoutAlternates will exclude any objects in the alternate objects directory +func WithoutAlternates() RepoSizeOption { + return func(cfg *repoSizeConfig) { + cfg.ExcludeAlternates = true + } +} + +// Size calculates the size of all reachable objects in bytes +func (repo *Repo) Size(ctx context.Context, opts ...RepoSizeOption) (int64, error) { + var stdout bytes.Buffer + + var cfg repoSizeConfig + for _, opt := range opts { + opt(&cfg) + } + + var options []git.Option + for _, refToExclude := range cfg.ExcludeRefs { + options = append( + options, + git.Flag{Name: fmt.Sprintf("--exclude=%s", refToExclude)}, + ) + } + + if cfg.ExcludeAlternates { + alternatesPath, err := repo.InfoAlternatesPath() + if err != nil { + return 0, fmt.Errorf("getting alternates path: %w", err) + } + + // when excluding alternatives we need to be careful with using the bitmap index. If + // the repository is indeed linked to an alternative object directory, then we know + // that only the linked-to object directory will have bitmaps. Consequentially, this + // bitmap will only ever cover objects that are part of the alternate repository and + // can thus by definition not contain any objects that are only part of the repo + // that is linking to it. Unfortunately, this case causes us to run into an edge + // case in Git where the command takes significantly longer to compute the disk size + // when using bitmaps compared to when not using bitmaps. + // + // To work around this case we thus don't use a bitmap index in case we find that + // the repository has an alternates file. + if _, err := os.Stat(alternatesPath); err != nil && errors.Is(err, fs.ErrNotExist) { + // The alternates file does not exist. We can thus use the bitmap index and + // don't have to specify `--not --alternate-refs` given that there aren't + // any anyway. + options = append(options, git.Flag{Name: "--use-bitmap-index"}) + } else { + // We either have a bitmap index or we have run into any error that is not + // `fs.ErrNotExist`. In that case we don't use a bitmap index, but will + // exclude objects reachable from alternate refs. + options = append(options, + git.Flag{Name: "--not"}, + git.Flag{Name: "--alternate-refs"}, + git.Flag{Name: "--not"}, + ) + } + } else { + // If we don't exclude objects reachable from alternate refs we can always enable + // use of the bitmap index. + options = append(options, git.Flag{Name: "--use-bitmap-index"}) + } + + options = append(options, + git.Flag{Name: "--all"}, + git.Flag{Name: "--objects"}, + git.Flag{Name: "--disk-usage"}, + ) + + if err := repo.ExecAndWait(ctx, + git.SubCmd{ + Name: "rev-list", + Flags: options, + }, + git.WithStdout(&stdout), + ); err != nil { + return -1, err + } + + size, err := strconv.ParseInt(strings.TrimSuffix(stdout.String(), "\n"), 10, 64) + if err != nil { + return -1, err + } + + return size, nil +} + +// StorageTempDir returns the temporary dir for the storage where the repo is on. +// When this directory does not exist yet, it's being created. +func (repo *Repo) StorageTempDir() (string, error) { + tempPath, err := repo.locator.TempDir(repo.GetStorageName()) + if err != nil { + return "", err + } + + if err := os.MkdirAll(tempPath, 0o755); err != nil { + return "", err + } + + return tempPath, nil +} + +// ObjectHash detects the object hash used by this particular repository. +func (repo *Repo) ObjectHash(ctx context.Context) (git.ObjectHash, error) { + repo.detectObjectHashOnce.Do(func() { + repo.objectHash, repo.objectHashErr = git.DetectObjectHash(ctx, repo) + }) + return repo.objectHash, repo.objectHashErr +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo_test.go new file mode 100644 index 0000000000..7f26136f26 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/repo_test.go @@ -0,0 +1,427 @@ +package localrepo + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestRepo(t *testing.T) { + cfg := testcfg.Build(t) + + gittest.TestRepository(t, cfg, func(ctx context.Context, tb testing.TB) (git.Repository, string) { + tb.Helper() + + repoProto, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gitCmdFactory := gittest.NewCommandFactory(tb, cfg) + catfileCache := catfile.NewCache(cfg) + tb.Cleanup(catfileCache.Stop) + return New(config.NewLocator(cfg), gitCmdFactory, catfileCache, repoProto), repoPath + }) +} + +func TestSize(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + + ctx := testhelper.Context(t) + + commandArgFile := filepath.Join(testhelper.TempDir(t), "args") + interceptingFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf(`#!/bin/bash + echo "$@" >%q + exec %q "$@" + `, commandArgFile, execEnv.BinaryPath) + }) + + hashDependentSize := func(sha1Size, sha256Size int64) int64 { + if gittest.ObjectHashIsSHA256() { + return sha256Size + } + return sha1Size + } + + testCases := []struct { + desc string + setup func(t *testing.T) *gitalypb.Repository + opts []RepoSizeOption + expectedSize int64 + expectedUseBitmap bool + }{ + { + desc: "empty repository", + expectedSize: 0, + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + return repoProto + }, + expectedUseBitmap: true, + }, + { + desc: "referenced commit", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + gittest.WithBranch("main"), + ) + + return repoProto + }, + expectedSize: hashDependentSize(203, 230), + expectedUseBitmap: true, + }, + { + desc: "unreferenced commit", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + ) + + return repoProto + }, + expectedSize: 0, + expectedUseBitmap: true, + }, + { + desc: "modification to blob without repack", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + ) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1001)}, + ), + gittest.WithMessage("modification"), + gittest.WithBranch("main"), + ) + + return repoProto + }, + expectedSize: hashDependentSize(439, 510), + expectedUseBitmap: true, + }, + { + desc: "modification to blob after repack", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + ) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "file", Mode: "100644", Content: strings.Repeat("a", 1001)}, + ), + gittest.WithMessage("modification"), + gittest.WithBranch("main"), + ) + + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-a", "-d") + + return repoProto + }, + expectedSize: hashDependentSize(398, 465), + expectedUseBitmap: true, + }, + { + desc: "excluded single ref", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + gittest.WithBranch("exclude-me"), + ) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("x", 2000)}, + ), + gittest.WithBranch("include-me"), + ) + + return repoProto + }, + opts: []RepoSizeOption{ + WithExcludeRefs("refs/heads/exclude-me"), + }, + expectedSize: hashDependentSize(217, 245), + expectedUseBitmap: true, + }, + { + desc: "excluded everything", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + gittest.WithBranch("exclude-me"), + ) + + return repoProto + }, + opts: []RepoSizeOption{ + WithExcludeRefs("refs/heads/*"), + }, + expectedSize: 0, + expectedUseBitmap: true, + }, + { + desc: "repo with alternate", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + _, poolPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + require.NoError(t, os.WriteFile( + filepath.Join(repoPath, "objects", "info", "alternates"), + []byte(filepath.Join(poolPath, "objects")), + os.ModePerm, + )) + + for _, path := range []string{repoPath, poolPath} { + gittest.WriteCommit(t, cfg, path, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + gittest.WithBranch("main"), + ) + } + + return repoProto + }, + // While both repositories have the same contents, we should still return + // the actual repository's size because we don't exclude the alternate. + expectedSize: hashDependentSize(207, 234), + // Even though we have an alternate, we should still use bitmap indices + // given that we don't use `--not --alternate-refs`. + expectedUseBitmap: true, + }, + { + desc: "exclude alternate with identical contents", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + _, poolPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + require.NoError(t, os.WriteFile( + filepath.Join(repoPath, "objects", "info", "alternates"), + []byte(filepath.Join(poolPath, "objects")), + os.ModePerm, + )) + + // We write the same object into both repositories, so we should + // exclude it from our size calculations. + for _, path := range []string{repoPath, poolPath} { + gittest.WriteCommit(t, cfg, path, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + gittest.WithBranch("main"), + ) + } + + return repoProto + }, + opts: []RepoSizeOption{ + WithoutAlternates(), + }, + expectedSize: 0, + expectedUseBitmap: false, + }, + { + desc: "exclude alternate with additional contents", + setup: func(t *testing.T) *gitalypb.Repository { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + _, poolPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + require.NoError(t, os.WriteFile( + filepath.Join(repoPath, "objects", "info", "alternates"), + []byte(filepath.Join(poolPath, "objects")), + os.ModePerm, + )) + + for i, path := range []string{repoPath, poolPath} { + // We first write one blob into the repo that is the same + // across both repositories. + rootCommitID := gittest.WriteCommit(t, cfg, path, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: strings.Repeat("a", 1000)}, + ), + ) + + // But this time we also write a second commit into each of + // the repositories that is not the same to simulate history + // that has diverged. + gittest.WriteCommit(t, cfg, path, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "1kbblob", Mode: "100644", Content: fmt.Sprintf("%d", i)}, + ), + gittest.WithBranch("main"), + ) + } + + return repoProto + }, + opts: []RepoSizeOption{ + WithoutAlternates(), + }, + expectedSize: hashDependentSize(224, 268), + expectedUseBitmap: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + require.NoError(t, os.RemoveAll(commandArgFile)) + + repoProto := tc.setup(t) + repo := New(config.NewLocator(cfg), interceptingFactory, catfileCache, repoProto) + + size, err := repo.Size(ctx, tc.opts...) + require.NoError(t, err) + require.Equal(t, tc.expectedSize, size) + + commandArgs := text.ChompBytes(testhelper.MustReadFile(t, commandArgFile)) + if tc.expectedUseBitmap { + require.Contains(t, commandArgs, "--use-bitmap-index") + } else { + require.NotContains(t, commandArgs, "--use-bitmap-index") + } + }) + } +} + +func TestRepo_StorageTempDir(t *testing.T) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + locator := config.NewLocator(cfg) + + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := New(locator, gitCmdFactory, catfileCache, repoProto) + + expected, err := locator.TempDir(cfg.Storages[0].Name) + require.NoError(t, err) + require.NoDirExists(t, expected) + + tempPath, err := repo.StorageTempDir() + require.NoError(t, err) + require.DirExists(t, expected) + require.Equal(t, expected, tempPath) +} + +func TestRepo_ObjectHash(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + locator := config.NewLocator(cfg) + + outputFile := filepath.Join(testhelper.TempDir(t), "output") + + // We create an intercepting command factory that detects when we run our object hash + // detection logic and, if so, writes a sentinel value into our output file. Like this we + // can test how often the logic runs. + gitCmdFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf(`#!/bin/sh + ( echo "$@" | grep --silent -- '--show-object-format' ) && echo detection-logic >>%q + exec %q "$@"`, outputFile, execEnv.BinaryPath) + }) + + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := New(locator, gitCmdFactory, catfileCache, repoProto) + + objectHash, err := repo.ObjectHash(ctx) + require.NoError(t, err) + require.Equal(t, gittest.DefaultObjectHash.EmptyTreeOID, objectHash.EmptyTreeOID) + + // We should see that the detection logic has been executed once. + require.Equal(t, "detection-logic\n", string(testhelper.MustReadFile(t, outputFile))) + + // Verify that running this a second time continues to return the object hash alright + // regardless of the cache. + objectHash, err = repo.ObjectHash(ctx) + require.NoError(t, err) + require.Equal(t, gittest.DefaultObjectHash.EmptyTreeOID, objectHash.EmptyTreeOID) + + // But the detection logic should not have been executed a second time. + require.Equal(t, "detection-logic\n", string(testhelper.MustReadFile(t, outputFile))) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/testhelper_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/testhelper_test.go index 5e03d70de9..5bc11b2af2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo/testhelper_test.go @@ -3,13 +3,12 @@ package localrepo import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestMain(m *testing.M) { @@ -17,21 +16,12 @@ func TestMain(m *testing.M) { } type setupRepoConfig struct { - // emptyRepo will cause `setupRepo()` to create a new, empty repository instead of - // cloning our test repository. - emptyRepo bool // disableHooks will disable the use of hooks. disableHooks bool } type setupRepoOption func(*setupRepoConfig) -func withEmptyRepo() setupRepoOption { - return func(cfg *setupRepoConfig) { - cfg.emptyRepo = true - } -} - func withDisabledHooks() setupRepoOption { return func(cfg *setupRepoConfig) { cfg.disableHooks = true @@ -46,6 +36,7 @@ func setupRepo(t *testing.T, opts ...setupRepoOption) (config.Cfg, *Repo, string opt(&setupRepoCfg) } + ctx := testhelper.Context(t) cfg := testcfg.Build(t) var commandFactoryOpts []git.ExecCommandFactoryOption @@ -53,13 +44,9 @@ func setupRepo(t *testing.T, opts ...setupRepoOption) (config.Cfg, *Repo, string commandFactoryOpts = append(commandFactoryOpts, git.WithSkipHooks()) } - var repoProto *gitalypb.Repository - var repoPath string - if setupRepoCfg.emptyRepo { - repoProto, repoPath = gittest.InitRepo(t, cfg, cfg.Storages[0]) - } else { - repoProto, repoPath = gittest.CloneRepo(t, cfg, cfg.Storages[0]) - } + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) gitCmdFactory := gittest.NewCommandFactory(t, cfg, commandFactoryOpts...) catfileCache := catfile.NewCache(cfg) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/last_commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/last_commit.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/last_commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/last_commit.go index 077850dde6..de2d484d06 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/last_commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/last_commit.go @@ -4,12 +4,12 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // LastCommitForPath returns the last commit which modified path. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/parser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/parser.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/parser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/parser.go index f176fe1407..173bcc37b1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/log/parser.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/log/parser.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // IsNotFound tests if an error is a "not found" error. @@ -23,10 +23,10 @@ type Parser struct { } // NewParser returns a new Parser -func NewParser(ctx context.Context, catfileCache catfile.Cache, repo git.RepositoryExecutor, src io.Reader) (*Parser, error) { - objectReader, err := catfileCache.ObjectReader(ctx, repo) +func NewParser(ctx context.Context, catfileCache catfile.Cache, repo git.RepositoryExecutor, src io.Reader) (*Parser, func(), error) { + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) if err != nil { - return nil, err + return nil, nil, err } parser := &Parser{ @@ -34,7 +34,7 @@ func NewParser(ctx context.Context, catfileCache catfile.Cache, repo git.Reposit objectReader: objectReader, } - return parser, nil + return parser, cancel, nil } // Parse parses a single git log line. It returns true if successful, false if it finished diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/entries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/entries.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/entries.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/entries.go index 4a729fec0a..89167d9b45 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/entries.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/entries.go @@ -1,6 +1,6 @@ package lstree -import "gitlab.com/gitlab-org/gitaly/v14/internal/git" +import "gitlab.com/gitlab-org/gitaly/v15/internal/git" // ObjectType is an Enum for the type of object of // the ls-tree entry, which can be can be tree, blob or commit diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries.go index ab27d6f5d0..24156c7a7c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries.go @@ -8,8 +8,8 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" ) var ( @@ -60,7 +60,12 @@ func ListEntries( return nil, fmt.Errorf("spawning git-ls-tree: %w", err) } - parser := NewParser(cmd) + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return nil, fmt.Errorf("detecting object hash: %w", err) + } + + parser := NewParser(cmd, objectHash) var entries []*Entry for { entry, err := parser.NextEntry() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries_test.go index 152aa18a10..2d78f9c34c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/list_entries_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/list_entries_test.go @@ -4,18 +4,22 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestListEntries(t *testing.T) { + t.Parallel() + cfg := testcfg.Build(t) ctx := testhelper.Context(t) - repoProto, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("blob contents")) @@ -149,8 +153,8 @@ func TestListEntries(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { results, err := ListEntries(ctx, repo, tc.treeish, tc.cfg) - require.Equal(t, tc.expectedResults, results) require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResults, results) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser.go index 13fe2de666..7c1a58adb7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/parser.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser.go @@ -6,7 +6,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // ErrParse is returned when the parse of an entry was unsuccessful @@ -14,13 +14,15 @@ var ErrParse = errors.New("failed to parse git ls-tree response") // Parser holds the necessary state for parsing the ls-tree output type Parser struct { - reader *bufio.Reader + reader *bufio.Reader + objectHash git.ObjectHash } // NewParser returns a new Parser -func NewParser(src io.Reader) *Parser { +func NewParser(src io.Reader, objectHash git.ObjectHash) *Parser { return &Parser{ - reader: bufio.NewReader(src), + reader: bufio.NewReader(src), + objectHash: objectHash, } } @@ -61,7 +63,7 @@ func (p *Parser) NextEntry() (*Entry, error) { return nil, err } - objectID, err := git.NewObjectIDFromHex(string(treeEntryID)) + objectID, err := p.objectHash.FromHex(string(treeEntryID)) if err != nil { return nil, err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser_test.go new file mode 100644 index 0000000000..3df2145cb6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/parser_test.go @@ -0,0 +1,89 @@ +package lstree + +import ( + "bytes" + "io" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestParser(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + gitignoreBlobID := gittest.WriteBlob(t, cfg, repoPath, []byte("gitignore")) + gitmodulesBlobID := gittest.WriteBlob(t, cfg, repoPath, []byte("gitmodules")) + submoduleCommitID := gittest.WriteCommit(t, cfg, repoPath) + + regularEntriesTreeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: ".gitignore", Mode: "100644", OID: gitignoreBlobID}, + {Path: ".gitmodules", Mode: "100644", OID: gitmodulesBlobID}, + {Path: "entry with space", Mode: "040000", OID: gittest.DefaultObjectHash.EmptyTreeOID}, + {Path: "gitlab-shell", Mode: "160000", OID: submoduleCommitID}, + }) + + for _, tc := range []struct { + desc string + treeID git.ObjectID + expectedEntries Entries + }{ + { + desc: "regular entries", + treeID: regularEntriesTreeID, + expectedEntries: Entries{ + { + Mode: []byte("100644"), + Type: Blob, + ObjectID: gitignoreBlobID, + Path: ".gitignore", + }, + { + Mode: []byte("100644"), + Type: Blob, + ObjectID: gitmodulesBlobID, + Path: ".gitmodules", + }, + { + Mode: []byte("040000"), + Type: Tree, + ObjectID: gittest.DefaultObjectHash.EmptyTreeOID, + Path: "entry with space", + }, + { + Mode: []byte("160000"), + Type: Submodule, + ObjectID: submoduleCommitID, + Path: "gitlab-shell", + }, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + treeData := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-z", tc.treeID.String()) + + parser := NewParser(bytes.NewReader(treeData), gittest.DefaultObjectHash) + parsedEntries := Entries{} + for { + entry, err := parser.NextEntry() + if err == io.EOF { + break + } + + require.NoError(t, err) + parsedEntries = append(parsedEntries, *entry) + } + + require.Equal(t, tc.expectedEntries, parsedEntries) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/testhelper_test.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/testhelper_test.go index 484c397e6f..619a988000 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree/testhelper_test.go @@ -3,7 +3,7 @@ package lstree import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/object.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/object.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id.go new file mode 100644 index 0000000000..2826215d3c --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id.go @@ -0,0 +1,125 @@ +package git + +import ( + "bytes" + "context" + "crypto/sha1" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "hash" + "regexp" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +var ( + // ObjectHashSHA1 is the implementation of an object ID via SHA1. + ObjectHashSHA1 = ObjectHash{ + regexp: regexp.MustCompile(`\A[0-9a-f]{40}\z`), + Hash: sha1.New, + EmptyTreeOID: ObjectID("4b825dc642cb6eb9a060e54bf8d69288fbee4904"), + ZeroOID: ObjectID("0000000000000000000000000000000000000000"), + } + + // ObjectHashSHA256 is the implementation of an object ID via SHA256. + ObjectHashSHA256 = ObjectHash{ + regexp: regexp.MustCompile(`\A[0-9a-f]{64}\z`), + Hash: sha256.New, + EmptyTreeOID: ObjectID("6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321"), + ZeroOID: ObjectID("0000000000000000000000000000000000000000000000000000000000000000"), + } + + // ErrInvalidObjectID is returned in case an object ID's string + // representation is not a valid one. + ErrInvalidObjectID = errors.New("invalid object ID") +) + +// ObjectHash is a hash-function specific implementation of an object ID. +type ObjectHash struct { + regexp *regexp.Regexp + // Hash is the hashing function used to hash objects. + Hash func() hash.Hash + // EmptyTreeOID is the object ID of the tree object that has no directory entries. + EmptyTreeOID ObjectID + // ZeroOID is the special value that Git uses to signal a ref or object does not exist + ZeroOID ObjectID +} + +// DetectObjectHash detects the object-hash used by the given repository. +func DetectObjectHash(ctx context.Context, repoExecutor RepositoryExecutor) (ObjectHash, error) { + var stdout, stderr bytes.Buffer + + if err := repoExecutor.ExecAndWait(ctx, SubCmd{ + Name: "rev-parse", + Flags: []Option{ + Flag{"--show-object-format"}, + }, + }, WithStdout(&stdout), WithStderr(&stderr)); err != nil { + return ObjectHash{}, fmt.Errorf("reading object format: %w, stderr: %q", err, stderr.String()) + } + + objectFormat := text.ChompBytes(stdout.Bytes()) + switch objectFormat { + case "sha1": + return ObjectHashSHA1, nil + case "sha256": + return ObjectHashSHA256, nil + default: + return ObjectHash{}, fmt.Errorf("unknown object format: %q", objectFormat) + } +} + +// EncodedLen returns the length of the hex-encoded string of a full object ID. +func (h ObjectHash) EncodedLen() int { + return hex.EncodedLen(h.Hash().Size()) +} + +// FromHex constructs a new ObjectID from the given hex representation of the object ID. Returns +// ErrInvalidObjectID if the given object ID is not valid. +func (h ObjectHash) FromHex(hex string) (ObjectID, error) { + if err := h.ValidateHex(hex); err != nil { + return "", err + } + + return ObjectID(hex), nil +} + +// ValidateHex checks if `hex` is a syntactically correct object ID for the given hash. Abbreviated +// object IDs are not deemed to be valid. Returns an `ErrInvalidObjectID` if the `hex` is not valid. +func (h ObjectHash) ValidateHex(hex string) error { + if h.regexp.MatchString(hex) { + return nil + } + + return fmt.Errorf("%w: %q", ErrInvalidObjectID, hex) +} + +// IsZeroOID checks whether the given object ID is the all-zeroes object ID for the given hash. +func (h ObjectHash) IsZeroOID(oid ObjectID) bool { + return string(oid) == string(h.ZeroOID) +} + +// ObjectID represents an object ID. +type ObjectID string + +// String returns the hex representation of the ObjectID. +func (oid ObjectID) String() string { + return string(oid) +} + +// Bytes returns the byte representation of the ObjectID. +func (oid ObjectID) Bytes() ([]byte, error) { + decoded, err := hex.DecodeString(string(oid)) + if err != nil { + return nil, err + } + return decoded, nil +} + +// Revision returns a revision of the ObjectID. This directly returns the hex +// representation as every object ID is a valid revision. +func (oid ObjectID) Revision() Revision { + return Revision(oid.String()) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id_test.go new file mode 100644 index 0000000000..6597daf990 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/object_id_test.go @@ -0,0 +1,351 @@ +//go:build !gitaly_test_sha256 + +package git_test + +import ( + "bytes" + "encoding/hex" + "fmt" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestDetectObjectHash(t *testing.T) { + cfg := testcfg.Build(t) + ctx := testhelper.Context(t) + + for _, tc := range []struct { + desc string + setup func(t *testing.T) *gitalypb.Repository + expectedErr error + expectedHash git.ObjectHash + }{ + { + desc: "defaults to SHA1", + setup: func(t *testing.T) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + ObjectFormat: "sha1", + }) + + // Verify that the repo doesn't explicitly mention it's using SHA1 + // as object hash. + content := testhelper.MustReadFile(t, filepath.Join(repoPath, "config")) + require.NotContains(t, text.ChompBytes(content), "sha1") + + return repo + }, + expectedHash: git.ObjectHashSHA1, + }, + { + desc: "explicitly set to SHA1", + setup: func(t *testing.T) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + ObjectFormat: "sha1", + }) + + // Explicitly set the object format to SHA1. Note that setting the + // object format explicitly requires the repository format version + // to be at least `1`. + gittest.Exec(t, cfg, "-C", repoPath, "config", "core.repositoryFormatVersion", "1") + gittest.Exec(t, cfg, "-C", repoPath, "config", "extensions.objectFormat", "sha1") + + return repo + }, + expectedHash: git.ObjectHashSHA1, + }, + { + desc: "explicitly set to SHA256", + setup: func(t *testing.T) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + ObjectFormat: "sha256", + }) + + require.Equal(t, + "sha256", + text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "config", "extensions.objectFormat")), + ) + + return repo + }, + expectedHash: git.ObjectHashSHA256, + }, + { + desc: "invalid repository configuration", + setup: func(t *testing.T) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + ObjectFormat: "sha1", + }) + + gittest.Exec(t, cfg, "-C", repoPath, "config", "extensions.objectFormat", "sha1") + + return repo + }, + expectedErr: fmt.Errorf( + "reading object format: exit status 128, stderr: %q", + "fatal: repo version is 0, but v1-only extension found:\n\tobjectformat\n", + ), + }, + { + desc: "unknown hash", + setup: func(t *testing.T) *gitalypb.Repository { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + // Explicitly set the object format to something unknown. + gittest.Exec(t, cfg, "-C", repoPath, "config", "extensions.objectFormat", "blake2") + + return repo + }, + expectedErr: fmt.Errorf( + "reading object format: exit status 128, stderr: \"error: invalid value for 'extensions.objectformat'", + ), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto := tc.setup(t) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + hash, err := git.DetectObjectHash(ctx, repo) + if tc.expectedErr != nil { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr.Error()) + } else { + require.NoError(t, err) + } + + // Function pointers cannot be compared, so we need to unset them. + hash.Hash = nil + tc.expectedHash.Hash = nil + + require.Equal(t, tc.expectedHash, hash) + }) + } +} + +func TestObjectHash_ValidateHex(t *testing.T) { + for _, hash := range []struct { + desc string + hash git.ObjectHash + validHex string + }{ + { + desc: "SHA1", + hash: git.ObjectHashSHA1, + validHex: "356e7793f9654d51dfb27312a1464062bceb9fa3", + }, + { + desc: "SHA256", + hash: git.ObjectHashSHA256, + validHex: "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f", + }, + } { + t.Run(hash.desc, func(t *testing.T) { + for _, tc := range []struct { + desc string + hex string + valid bool + }{ + { + desc: "valid object ID", + hex: hash.validHex, + valid: true, + }, + { + desc: "object ID with non-hex characters fails", + hex: "x" + hash.validHex[1:], + valid: false, + }, + { + desc: "object ID with upper-case letters fails", + hex: strings.ToUpper(hash.validHex), + valid: false, + }, + { + desc: "too short object ID fails", + hex: hash.validHex[:len(hash.validHex)-1], + valid: false, + }, + { + desc: "too long object ID fails", + hex: hash.validHex + "3", + valid: false, + }, + { + desc: "empty string fails", + hex: "", + valid: false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + err := hash.hash.ValidateHex(tc.hex) + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + require.EqualError(t, err, fmt.Sprintf("invalid object ID: %q", tc.hex)) + } + }) + } + }) + } +} + +func TestObjectHash_FromHex(t *testing.T) { + for _, hash := range []struct { + desc string + hash git.ObjectHash + validHex string + }{ + { + desc: "SHA1", + hash: git.ObjectHashSHA1, + validHex: "356e7793f9654d51dfb27312a1464062bceb9fa3", + }, + { + desc: "SHA256", + hash: git.ObjectHashSHA256, + validHex: "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f", + }, + } { + t.Run(hash.desc, func(t *testing.T) { + for _, tc := range []struct { + desc string + hex string + valid bool + }{ + { + desc: "valid object ID", + hex: hash.validHex, + valid: true, + }, + { + desc: "object ID with non-hex characters fails", + hex: "x" + hash.validHex[1:], + valid: false, + }, + { + desc: "object ID with upper-case letters fails", + hex: strings.ToUpper(hash.validHex), + valid: false, + }, + { + desc: "too short object ID fails", + hex: hash.validHex[:len(hash.validHex)-1], + valid: false, + }, + { + desc: "too long object ID fails", + hex: hash.validHex + "3", + valid: false, + }, + { + desc: "empty string fails", + hex: "", + valid: false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + oid, err := hash.hash.FromHex(tc.hex) + if tc.valid { + require.NoError(t, err) + require.Equal(t, tc.hex, oid.String()) + } else { + require.Error(t, err) + } + }) + } + }) + } +} + +func TestObjectHash_EncodedLen(t *testing.T) { + t.Parallel() + require.Equal(t, 40, git.ObjectHashSHA1.EncodedLen()) + require.Equal(t, 64, git.ObjectHashSHA256.EncodedLen()) +} + +func TestObjectID_Bytes(t *testing.T) { + for _, tc := range []struct { + desc string + oid git.ObjectID + expectedBytes []byte + expectedErr error + }{ + { + desc: "zero OID", + oid: git.ObjectHashSHA1.ZeroOID, + expectedBytes: bytes.Repeat([]byte{0}, 20), + }, + { + desc: "valid object ID", + oid: git.ObjectID(strings.Repeat("8", 40)), + expectedBytes: bytes.Repeat([]byte{0x88}, 20), + }, + { + desc: "invalid object ID", + oid: git.ObjectID(strings.Repeat("8", 39) + "x"), + expectedErr: hex.InvalidByteError('x'), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + actualBytes, err := tc.oid.Bytes() + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedBytes, actualBytes) + }) + } +} + +func TestObjectHash_IsZeroOID(t *testing.T) { + for _, hash := range []struct { + desc string + hash git.ObjectHash + validHex string + }{ + { + desc: "SHA1", + hash: git.ObjectHashSHA1, + }, + { + desc: "SHA256", + hash: git.ObjectHashSHA256, + }, + } { + t.Run(hash.desc, func(t *testing.T) { + for _, tc := range []struct { + desc string + oid git.ObjectID + isZero bool + }{ + { + desc: "zero object ID", + oid: hash.hash.ZeroOID, + isZero: true, + }, + { + desc: "zero object ID", + oid: hash.hash.EmptyTreeOID, + isZero: false, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.isZero, hash.hash.IsZeroOID(tc.oid)) + }) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone.go index 780afb5466..45a48f8644 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/clone.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone.go @@ -1,22 +1,25 @@ package objectpool import ( + "bytes" "context" + "fmt" "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" ) // clone a repository to a pool, without setting the alternates, is not the -// resposibility of this function. +// responsibility of this function. func (o *ObjectPool) clone(ctx context.Context, repo *localrepo.Repo) error { repoPath, err := repo.Path() if err != nil { return err } + var stderr bytes.Buffer cmd, err := o.gitCmdFactory.NewWithoutRepo(ctx, git.SubCmd{ Name: "clone", @@ -28,12 +31,17 @@ func (o *ObjectPool) clone(ctx context.Context, repo *localrepo.Repo) error { Args: []string{repoPath, o.FullPath()}, }, git.WithRefTxHook(repo), + git.WithStderr(&stderr), ) if err != nil { - return err + return fmt.Errorf("spawning clone: %w", err) } - return cmd.Wait() + if err := cmd.Wait(); err != nil { + return fmt.Errorf("cloning to pool: %w, stderr: %q", err, stderr.String()) + } + + return nil } func (o *ObjectPool) removeHooksDir() error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone_test.go new file mode 100644 index 0000000000..4c6d5b0c00 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/clone_test.go @@ -0,0 +1,90 @@ +//go:build !gitaly_test_sha256 + +package objectpool + +import ( + "bytes" + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestClone_successful(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, pool, repoProto := setupObjectPool(t, ctx) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + require.NoError(t, pool.clone(ctx, repo)) + + require.DirExists(t, pool.FullPath()) + require.DirExists(t, filepath.Join(pool.FullPath(), "objects")) +} + +func TestClone_existingPool(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, pool, repoProto := setupObjectPool(t, ctx) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + // The first time around cloning should succeed, but ... + require.NoError(t, pool.clone(ctx, repo)) + + // ... when we try to clone the same pool a second time we should get an error because the + // destination exists already. + require.EqualError(t, pool.clone(ctx, repo), fmt.Sprintf( + "cloning to pool: exit status 128, stderr: \"fatal: destination path '%s' already exists and is not an empty directory.\\n\"", + pool.FullPath(), + )) +} + +func TestClone_fsck(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, pool, repoProto := setupObjectPool(t, ctx) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + repoPath, err := repo.Path() + require.NoError(t, err) + + // Write a tree into the repository that's known-broken. + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Content: "content", Path: "dup", Mode: "100644"}, + {Content: "content", Path: "dup", Mode: "100644"}, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(), + gittest.WithBranch("main"), + gittest.WithTree(treeID), + ) + + // While git-clone(1) would normally complain about the broken tree we have just cloned, we + // don't expect the clone to fail. This is because we know that the tree is already in one + // of our repositories that we have locally, so raising an error now doesn't make a whole + // lot of sense in the first place. + // + // Note: this works because we use `git clone --local`, which only creates a copy of the + // repository without performing consistency checks. + require.NoError(t, pool.clone(ctx, repo)) + + // Verify that the broken tree is indeed in the pool repository and that it is reported as + // broken by git-fsck(1). + var stderr bytes.Buffer + fsckCmd := gittest.NewCommand(t, cfg, "-C", pool.FullPath(), "fsck") + fsckCmd.Stderr = &stderr + + require.EqualError(t, fsckCmd.Run(), "exit status 1") + require.Equal(t, fmt.Sprintf("error in tree %s: duplicateEntries: contains duplicate file entries\n", treeID), stderr.String()) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch.go new file mode 100644 index 0000000000..0b399dc130 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch.go @@ -0,0 +1,374 @@ +package objectpool + +import ( + "bufio" + "bytes" + "context" + "fmt" + "io" + "path/filepath" + "strconv" + "strings" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" +) + +var objectPoolRefspec = fmt.Sprintf("+refs/*:%s/*", git.ObjectPoolRefNamespace) + +// FetchFromOrigin initializes the pool and fetches the objects from its origin repository +func (o *ObjectPool) FetchFromOrigin(ctx context.Context, origin *localrepo.Repo) error { + if err := o.Init(ctx); err != nil { + return fmt.Errorf("initializing object pool: %w", err) + } + + originPath, err := origin.Path() + if err != nil { + return fmt.Errorf("computing origin repo's path: %w", err) + } + + if err := o.housekeepingManager.CleanStaleData(ctx, o.Repo); err != nil { + return fmt.Errorf("cleaning stale data: %w", err) + } + + if err := o.logStats(ctx, "before fetch"); err != nil { + return fmt.Errorf("computing stats before fetch: %w", err) + } + + // Ideally we wouldn't want to prune old references at all so that we can keep alive all + // objects without having to create loads of dangling references. But unfortunately keeping + // around old refs can lead to D/F conflicts between old references that have since + // been deleted in the pool and new references that have been added in the pool member we're + // fetching from. E.g. if we have the old reference `refs/heads/branch` and the pool member + // has replaced that since with a new reference `refs/heads/branch/conflict` then + // the fetch would now always fail because of that conflict. + // + // Due to the lack of an alternative to resolve that conflict we are thus forced to enable + // pruning. This isn't too bad given that we know to keep alive the old objects via dangling + // refs anyway, but I'd sleep easier if we didn't have to do this. + // + // Note that we need to perform the pruning separately from the fetch: if the fetch is using + // `--atomic` and `--prune` together then it still wouldn't be able to recover from the D/F + // conflict. So we first to a preliminary prune that only prunes refs without fetching + // objects yet to avoid that scenario. + if featureflag.FetchIntoObjectPoolPruneRefs.IsEnabled(ctx) { + if err := o.pruneReferences(ctx, origin); err != nil { + return fmt.Errorf("pruning references: %w", err) + } + } + + var stderr bytes.Buffer + if err := o.Repo.ExecAndWait(ctx, + git.SubCmd{ + Name: "fetch", + Flags: []git.Option{ + git.Flag{Name: "--quiet"}, + git.Flag{Name: "--atomic"}, + // We already fetch tags via our refspec, so we don't + // want to fetch them a second time via Git's default + // tag refspec. + git.Flag{Name: "--no-tags"}, + // We don't need FETCH_HEAD, and it can potentially be hundreds of + // megabytes when doing a mirror-sync of repos with huge numbers of + // references. + git.Flag{Name: "--no-write-fetch-head"}, + // Disable showing forced updates, which may take a considerable + // amount of time to compute. We don't display any output anyway, + // which makes this computation kind of moot. + git.Flag{Name: "--no-show-forced-updates"}, + }, + Args: []string{originPath, objectPoolRefspec}, + }, + git.WithRefTxHook(o.Repo), + git.WithStderr(&stderr), + git.WithConfig(git.ConfigPair{ + // Git is so kind to point out that we asked it to not show forced updates + // by default, so we need to ask it not to do that. + Key: "advice.fetchShowForcedUpdates", Value: "false", + }), + ); err != nil { + return fmt.Errorf("fetch into object pool: %w, stderr: %q", err, + stderr.String()) + } + + if err := o.rescueDanglingObjects(ctx); err != nil { + return fmt.Errorf("rescuing dangling objects: %w", err) + } + + if err := o.logStats(ctx, "after fetch"); err != nil { + return fmt.Errorf("computing stats after fetch: %w", err) + } + + if err := o.housekeepingManager.OptimizeRepository(ctx, o.Repo); err != nil { + return fmt.Errorf("optimizing pool repo: %w", err) + } + + return nil +} + +// pruneReferences prunes any references that have been deleted in the origin repository. +func (o *ObjectPool) pruneReferences(ctx context.Context, origin *localrepo.Repo) error { + originPath, err := origin.Path() + if err != nil { + return fmt.Errorf("computing origin repo's path: %w", err) + } + + // Ideally, we'd just use `git remote prune` directly. But unfortunately, this command does + // not support atomic updates, but will instead use a separate reference transaction for + // updating the packed-refs file and for updating each of the loose references. This can be + // really expensive in case we are about to prune a lot of references given that every time, + // the reference-transaction hook needs to vote on the deletion and reach quorum. + // + // Instead we ask for a dry-run, parse the output and queue up every reference into a + // git-update-ref(1) process. While ugly, it works around the performance issues. + prune, err := o.Repo.Exec(ctx, + git.SubSubCmd{ + Name: "remote", + Action: "prune", + Args: []string{"origin"}, + Flags: []git.Option{ + git.Flag{Name: "--dry-run"}, + }, + }, + git.WithConfig(git.ConfigPair{Key: "remote.origin.url", Value: originPath}), + git.WithConfig(git.ConfigPair{Key: "remote.origin.fetch", Value: objectPoolRefspec}), + // This is a dry-run, only, so we don't have to enable hooks. + git.WithDisabledHooks(), + ) + if err != nil { + return fmt.Errorf("spawning prune: %w", err) + } + + updater, err := updateref.New(ctx, o.Repo) + if err != nil { + return fmt.Errorf("spawning updater: %w", err) + } + + // We need to manually compute a vote because all deletions we queue up here are + // force-deletions. We are forced to filter out force-deletions because these may also + // happen when evicting references from the packed-refs file. + voteHash := voting.NewVoteHash() + + scanner := bufio.NewScanner(prune) + for scanner.Scan() { + line := scanner.Bytes() + + // We need to skip the first two lines that represent the header of git-remote(1)'s + // output. While we should ideally just use a state machine here, it doesn't feel + // worth it given that the output is comparatively simple and given that the pruned + // branches are distinguished by a special prefix. + switch { + case bytes.Equal(line, []byte("Pruning origin")): + continue + case bytes.HasPrefix(line, []byte("URL: ")): + continue + case bytes.HasPrefix(line, []byte(" * [would prune] ")): + // The references announced by git-remote(1) only have the remote's name as + // prefix, which is "origin". We thus have to reassemble the complete name + // of every reference here. + deletedRef := "refs/remotes/" + string(bytes.TrimPrefix(line, []byte(" * [would prune] "))) + + if _, err := io.Copy(voteHash, strings.NewReader(fmt.Sprintf("%[1]s %[1]s %s\n", git.ObjectHashSHA1.ZeroOID, deletedRef))); err != nil { + return fmt.Errorf("hashing reference deletion: %w", err) + } + + if err := updater.Delete(git.ReferenceName(deletedRef)); err != nil { + return fmt.Errorf("queueing ref for deletion: %w", err) + } + default: + return fmt.Errorf("unexpected line: %q", line) + } + } + + if err := scanner.Err(); err != nil { + return fmt.Errorf("scanning deleted refs: %w", err) + } + + if err := prune.Wait(); err != nil { + return fmt.Errorf("waiting for prune: %w", err) + } + + vote, err := voteHash.Vote() + if err != nil { + return fmt.Errorf("computing vote: %w", err) + } + + // Prepare references so that they're locked and cannot be written by any concurrent + // processes. This also verifies that we can indeed delete the references. + if err := updater.Prepare(); err != nil { + return fmt.Errorf("preparing deletion of references: %w", err) + } + + // Vote on the references we're about to delete. + if err := transaction.VoteOnContext(ctx, o.txManager, vote, voting.Prepared); err != nil { + return fmt.Errorf("preparational vote on pruned references: %w", err) + } + + // Commit the pruned references to disk so that the change gets applied. + if err := updater.Commit(); err != nil { + return fmt.Errorf("deleting references: %w", err) + } + + // And then confirm that we actually deleted the references. + if err := transaction.VoteOnContext(ctx, o.txManager, vote, voting.Committed); err != nil { + return fmt.Errorf("preparational vote on pruned references: %w", err) + } + + return nil +} + +const danglingObjectNamespace = "refs/dangling/" + +// rescueDanglingObjects creates refs for all dangling objects if finds +// with `git fsck`, which converts those objects from "dangling" to +// "not-dangling". This guards against any object ever being deleted from +// a pool repository. This is a defense in depth against accidental use +// of `git prune`, which could remove Git objects that a pool member +// relies on. There is currently no way for us to reliably determine if +// an object is still used anywhere, so the only safe thing to do is to +// assume that every object _is_ used. +func (o *ObjectPool) rescueDanglingObjects(ctx context.Context) error { + fsck, err := o.Repo.Exec(ctx, git.SubCmd{ + Name: "fsck", + Flags: []git.Option{git.Flag{Name: "--connectivity-only"}, git.Flag{Name: "--dangling"}}, + }) + if err != nil { + return err + } + + updater, err := updateref.New(ctx, o.Repo, updateref.WithDisabledTransactions()) + if err != nil { + return err + } + + scanner := bufio.NewScanner(fsck) + for scanner.Scan() { + split := strings.SplitN(scanner.Text(), " ", 3) + if len(split) != 3 { + continue + } + + if split[0] != "dangling" { + continue + } + + danglingObjectID, err := git.ObjectHashSHA1.FromHex(split[2]) + if err != nil { + return fmt.Errorf("parsing object ID %q: %w", split[2], err) + } + + ref := git.ReferenceName(danglingObjectNamespace + split[2]) + if err := updater.Create(ref, danglingObjectID); err != nil { + return err + } + } + + if err := scanner.Err(); err != nil { + return err + } + + if err := fsck.Wait(); err != nil { + return fmt.Errorf("git fsck: %v", err) + } + + return updater.Commit() +} + +func (o *ObjectPool) logStats(ctx context.Context, when string) error { + fields := logrus.Fields{ + "when": when, + } + + for key, dir := range map[string]string{ + "poolObjectsSize": "objects", + "poolRefsSize": "refs", + } { + var err error + fields[key], err = sizeDir(ctx, filepath.Join(o.FullPath(), dir)) + if err != nil { + return err + } + } + + forEachRef, err := o.Repo.Exec(ctx, git.SubCmd{ + Name: "for-each-ref", + Flags: []git.Option{git.Flag{Name: "--format=%(objecttype)%00%(refname)"}}, + Args: []string{"refs/"}, + }) + if err != nil { + return err + } + + danglingRefsByType := make(map[string]int) + normalRefsByType := make(map[string]int) + + scanner := bufio.NewScanner(forEachRef) + for scanner.Scan() { + line := bytes.SplitN(scanner.Bytes(), []byte{0}, 2) + if len(line) != 2 { + continue + } + + objectType := string(line[0]) + refname := string(line[1]) + + if strings.HasPrefix(refname, danglingObjectNamespace) { + danglingRefsByType[objectType]++ + } else { + normalRefsByType[objectType]++ + } + } + + if err := scanner.Err(); err != nil { + return err + } + if err := forEachRef.Wait(); err != nil { + return err + } + + for _, key := range []string{"blob", "commit", "tag", "tree"} { + fields["dangling."+key+".ref"] = danglingRefsByType[key] + fields["normal."+key+".ref"] = normalRefsByType[key] + } + + ctxlogrus.Extract(ctx).WithFields(fields).Info("pool dangling ref stats") + + return nil +} + +func sizeDir(ctx context.Context, dir string) (int64, error) { + // du -k reports size in KB + cmd, err := command.New(ctx, []string{"du", "-sk", dir}) + if err != nil { + return 0, err + } + + sizeLine, err := io.ReadAll(cmd) + if err != nil { + return 0, err + } + + if err := cmd.Wait(); err != nil { + return 0, err + } + + sizeParts := bytes.Split(sizeLine, []byte("\t")) + if len(sizeParts) != 2 { + return 0, fmt.Errorf("malformed du output: %q", sizeLine) + } + + size, err := strconv.ParseInt(string(sizeParts[0]), 10, 0) + if err != nil { + return 0, err + } + + // Convert KB to B + return size * 1024, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch_test.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch_test.go index 299b92868f..0a03970ecb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/fetch_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/fetch_test.go @@ -1,23 +1,33 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( + "context" "fmt" "os" "path/filepath" + "strconv" "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) -func TestFetchFromOriginDangling(t *testing.T) { - ctx := testhelper.Context(t) +func TestFetchFromOrigin_dangling(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginDangling) +} + +func testFetchFromOriginDangling(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, repoProto := setupObjectPool(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -86,8 +96,13 @@ func TestFetchFromOriginDangling(t *testing.T) { require.NoFileExists(t, filepath.Join(pool.FullPath(), "objects", "info", "packs")) } -func TestFetchFromOriginFsck(t *testing.T) { - ctx := testhelper.Context(t) +func TestFetchFromOrigin_fsck(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginFsck) +} + +func testFetchFromOriginFsck(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, repoProto := setupObjectPool(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -110,31 +125,38 @@ func TestFetchFromOriginFsck(t *testing.T) { require.Contains(t, err.Error(), "duplicateEntries: contains duplicate file entries") } -func TestFetchFromOriginDeltaIslands(t *testing.T) { - ctx := testhelper.Context(t) +func TestFetchFromOrigin_deltaIslands(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginDeltaIslands) +} + +func testFetchFromOriginDeltaIslands(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, repoProto := setupObjectPool(t, ctx) + repo := localrepo.NewTestRepo(t, cfg, repoProto) - repoPath := filepath.Join(cfg.Storages[0].Path, repo.GetRelativePath()) + repoPath, err := repo.Path() + require.NoError(t, err) require.NoError(t, pool.FetchFromOrigin(ctx, repo), "seed pool") require.NoError(t, pool.Link(ctx, repo)) - gittest.TestDeltaIslands(t, cfg, repoPath, func() error { - // This should create a new packfile with good delta chains in the pool - if err := pool.FetchFromOrigin(ctx, repo); err != nil { - return err - } - - // Make sure the old packfile, with bad delta chains, is deleted from the source repo - gittest.Exec(t, cfg, "-C", repoPath, "repack", "-ald") - - return nil + // The setup of delta islands is done in the normal repository, and thus we pass `false` + // for `isPoolRepo`. Verification whether we correctly handle repacking though happens in + // the pool repository. + gittest.TestDeltaIslands(t, cfg, repoPath, pool.FullPath(), false, func() error { + return pool.FetchFromOrigin(ctx, repo) }) } -func TestFetchFromOriginBitmapHashCache(t *testing.T) { - ctx := testhelper.Context(t) +func TestFetchFromOrigin_bitmapHashCache(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginBitmapHashCache) +} + +func testFetchFromOriginBitmapHashCache(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, repoProto := setupObjectPool(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -158,8 +180,13 @@ func TestFetchFromOriginBitmapHashCache(t *testing.T) { gittest.TestBitmapHasHashcache(t, bitmap) } -func TestFetchFromOriginRefUpdates(t *testing.T) { - ctx := testhelper.Context(t) +func TestFetchFromOrigin_refUpdates(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginRefUpdates) +} + +func testFetchFromOriginRefUpdates(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, repoProto := setupObjectPool(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -184,11 +211,18 @@ func TestFetchFromOriginRefUpdates(t *testing.T) { "tags/v1.1.0": "646ece5cfed840eca0a4feb21bcd6a81bb19bda3", } - for ref, newOid := range newRefs { - require.NotEqual(t, newOid, oldRefs[ref], "sanity check of new refs") + // Create a bunch of additional references. This is to trigger OptimizeRepository to indeed + // repack the loose references as we expect it to in this test. It's debatable whether we + // should test this at all here given that this is business of the housekeeping package. But + // it's easy enough to do, so it doesn't hurt. + for i := 0; i < 32; i++ { + newRefs[fmt.Sprintf("heads/branch-%d", i)] = gittest.WriteCommit(t, cfg, repoPath, + gittest.WithMessage(strconv.Itoa(i)), + ).String() } for ref, oid := range newRefs { + require.NotEqual(t, oid, oldRefs[ref], "sanity check of new refs") gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "refs/"+ref, oid) require.Equal(t, oid, resolveRef(t, cfg, repoPath, "refs/"+ref), "look up %q in source after update", ref) } @@ -204,16 +238,23 @@ func TestFetchFromOriginRefUpdates(t *testing.T) { } func TestFetchFromOrigin_refs(t *testing.T) { - ctx := testhelper.Context(t) + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchFromOriginRefs) +} + +func testFetchFromOriginRefs(t *testing.T, ctx context.Context) { + t.Parallel() cfg, pool, _ := setupObjectPool(t, ctx) poolPath := pool.FullPath() // Init the source repo with a bunch of refs. - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithTreeEntries()) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries()) for _, ref := range []string{"refs/heads/master", "refs/environments/1", "refs/tags/lightweight-tag"} { gittest.Exec(t, cfg, "-C", repoPath, "update-ref", ref, commitID.String()) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link.go index 3527aad333..647959d6ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link.go @@ -8,9 +8,9 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" ) // Link will link the given repository to the object pool. This is done by writing the object pool's diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link_test.go index d959c8b182..146ff8f06d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/link_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/link_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -7,12 +9,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" "google.golang.org/grpc/peer" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/path.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/path.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/path.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool.go index a243f670f7..fb140416a0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool.go @@ -10,12 +10,12 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" ) type errString string @@ -25,7 +25,7 @@ func (err errString) Error() string { return string(err) } // ErrInvalidPoolDir is returned when the object pool relative path is malformed. const ErrInvalidPoolDir errString = "invalid object pool directory" -// ObjectPool are a way to dedup objects between repositories, where the objects +// ObjectPool are a way to de-dupe objects between repositories, where the objects // live in a pool in a distinct repository which is used as an alternate object // store for other repositories. type ObjectPool struct { @@ -57,10 +57,6 @@ func NewObjectPool( return nil, err } - if !housekeeping.IsPoolPath(relativePath) { - return nil, ErrInvalidPoolDir - } - pool := &ObjectPool{ gitCmdFactory: gitCmdFactory, txManager: txManager, @@ -71,6 +67,10 @@ func NewObjectPool( } pool.Repo = localrepo.New(locator, gitCmdFactory, catfileCache, pool) + if !housekeeping.IsPoolRepository(pool) { + return nil, ErrInvalidPoolDir + } + return pool, nil } @@ -128,7 +128,7 @@ func (o *ObjectPool) Remove(ctx context.Context) (err error) { return os.RemoveAll(o.FullPath()) } -// Init will intiailize an empty pool repository +// Init will initialize an empty pool repository // if one already exists, it will do nothing func (o *ObjectPool) Init(ctx context.Context) (err error) { targetDir := o.FullPath() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool_test.go index 9b2d8375b1..f257feb6a8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/pool_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/pool_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -8,11 +10,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestNewObjectPool(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/proto.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/proto.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/proto.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/proto.go index b85c11b00c..87f861d938 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/proto.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/proto.go @@ -1,12 +1,12 @@ package objectpool import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // FromProto returns an object pool object from a git repository object diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/testhelper_test.go similarity index 53% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/testhelper_test.go index 7e5d844339..1fb791db9d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -5,16 +7,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestMain(m *testing.M) { @@ -24,7 +26,10 @@ func TestMain(m *testing.M) { func setupObjectPool(t *testing.T, ctx context.Context) (config.Cfg, *ObjectPool, *gitalypb.Repository) { t.Helper() - cfg, repo, _ := testcfg.BuildWithRepo(t) + cfg, repo, repoPath := testcfg.BuildWithRepo(t) + + gittest.FixGitLabTestRepoForCommitGraphs(t, cfg, repoPath) + gitCommandFactory := gittest.NewCommandFactory(t, cfg, git.WithSkipHooks()) catfileCache := catfile.NewCache(cfg) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/bitmap.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/bitmap.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/bitmap.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/bitmap.go index c97b34e7d3..cadfa3f877 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/bitmap.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/bitmap.go @@ -11,7 +11,7 @@ import ( "math/big" "os" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitio" ) // IndexBitmap is the in-memory representation of a .bitmap file. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/index.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/index.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/index.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/index.go index 85191c5912..2fcf985ebb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/index.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/index.go @@ -10,13 +10,12 @@ import ( "io" "math" "os" - "os/exec" "regexp" "sort" "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" ) const sumSize = sha1.Size @@ -93,7 +92,7 @@ func ReadIndex(idxPath string) (*Index, error) { return nil, err } - showIndex, err := command.New(ctx, exec.Command("git", "show-index"), f, nil, nil) + showIndex, err := command.New(ctx, []string{"git", "show-index"}, command.WithStdin(f)) if err != nil { return nil, err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/object.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/object.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/object.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/object.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/packfile.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/packfile.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/packfile.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/packfile.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/packfile_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/packfile_test.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/packfile_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/packfile_test.go index ecf56563bc..7f5cfdd319 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile/packfile_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile/packfile_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package packfile_test import ( @@ -5,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/packfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/packfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pkt_line_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pkt_line_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pkt_line_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pkt_line_test.go index e3192a0112..1c9b56aaa8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pkt_line_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pkt_line_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package pktline import ( @@ -332,3 +334,58 @@ func TestEachSidebandPacket(t *testing.T) { }) } } + +func TestPayload(t *testing.T) { + for _, tc := range []struct { + desc string + input string + expectedErr string + expectedPayload []byte + }{ + { + desc: "packet too small", + input: "123", + expectedErr: "packet too small", + }, + { + desc: "invalid length prefix", + input: "something", + expectedErr: "parsing length header \"some\": strconv.ParseUint: parsing \"some\": invalid syntax", + }, + { + desc: "flush packet", + input: "0000", + expectedErr: "flush packets do not have a payload", + }, + { + desc: "packet with trailing bytes", + input: "0005atrailing", + expectedErr: "packet length 13 does not match header length 5", + }, + { + desc: "packet with missing bytes", + input: "0006a", + expectedErr: "packet length 5 does not match header length 6", + }, + { + desc: "empty packet", + input: "0004", + expectedPayload: []byte{}, + }, + { + desc: "packet with data", + input: "0068" + strings.Repeat("x", 100), + expectedPayload: bytes.Repeat([]byte("x"), 100), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + payload, err := Payload([]byte(tc.input)) + if tc.expectedErr == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tc.expectedErr) + } + require.Equal(t, tc.expectedPayload, payload) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pktline.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pktline.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pktline.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pktline.go index e97531fa3c..3cdeaf4e93 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/pktline.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/pktline.go @@ -39,6 +39,30 @@ func Data(pkt []byte) []byte { return pkt[4:] } +// Payload returns the pktline's data. It verifies that the length header matches what we expect as +// data. +func Payload(pkt []byte) ([]byte, error) { + if len(pkt) < 4 { + return nil, fmt.Errorf("packet too small") + } + + if IsFlush(pkt) { + return nil, fmt.Errorf("flush packets do not have a payload") + } + + lengthHeader := string(pkt[:4]) + length, err := strconv.ParseUint(lengthHeader, 16, 16) + if err != nil { + return nil, fmt.Errorf("parsing length header %q: %w", lengthHeader, err) + } + + if uint64(len(pkt)) != length { + return nil, fmt.Errorf("packet length %d does not match header length %d", len(pkt), length) + } + + return pkt[4:], nil +} + // IsFlush detects the special flush packet '0000' func IsFlush(pkt []byte) bool { return bytes.Equal(pkt, PktFlush()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor.go index f14be68816..9b371a85f4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor.go @@ -7,7 +7,7 @@ import ( "os" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" ) // ReadMonitor monitors an io.Reader, waiting for a specified packet. If the @@ -40,27 +40,22 @@ type ReadMonitor struct { // to the pipe. The stream will be monitored for a pktline-formatted packet // matching pkt. If it isn't seen within the timeout, cancelFn will be called. // -// Resources will be freed when the context is done, but you should close the -// returned *os.File earlier if possible. -func NewReadMonitor(ctx context.Context, r io.Reader) (*os.File, *ReadMonitor, error) { +// The returned function will release allocated resources. You must make sure to call this +// function. +func NewReadMonitor(ctx context.Context, r io.Reader) (*os.File, *ReadMonitor, func(), error) { pr, pw, err := os.Pipe() if err != nil { - return nil, nil, err + return nil, nil, nil, err } - // Ensure all resources are closed once the context is done - go func() { - <-ctx.Done() - - pr.Close() - pw.Close() - }() - return pr, &ReadMonitor{ - pr: pr, - pw: pw, - underlying: r, - }, nil + pr: pr, + pw: pw, + underlying: r, + }, func() { + pr.Close() + pw.Close() + }, nil } // Monitor should be called at most once. It scans the stream, looking for the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor_test.go index d813520f44..12f94d00ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline/read_monitor_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline/read_monitor_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package pktline import ( @@ -10,8 +12,8 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestReadMonitorTimeout(t *testing.T) { @@ -24,7 +26,7 @@ func TestReadMonitorTimeout(t *testing.T) { waitPipeR, // this pipe reader lets us block the multi reader ) - r, monitor, err := NewReadMonitor(ctx, in) + r, monitor, cleanup, err := NewReadMonitor(ctx, in) require.NoError(t, err) timeoutTicker := helper.NewManualTicker() @@ -41,6 +43,8 @@ func TestReadMonitorTimeout(t *testing.T) { require.Equal(t, ctx.Err(), context.Canceled) require.True(t, elapsed < time.Second, "Expected context to be cancelled quickly, but it was not") + cleanup() + // Verify that pipe is closed _, err = io.ReadAll(r) require.Error(t, err) @@ -61,8 +65,9 @@ func TestReadMonitorSuccess(t *testing.T) { strings.NewReader(postTimeoutPayload), ) - r, monitor, err := NewReadMonitor(ctx, in) + r, monitor, cleanup, err := NewReadMonitor(ctx, in) require.NoError(t, err) + defer cleanup() timeoutTicker := helper.NewManualTicker() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol.go index eadf949252..e4bfbfc2f7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol.go @@ -8,8 +8,8 @@ import ( grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol_test.go index 41e92d7c22..140b998ec0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/protocol_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/protocol_test.go @@ -1,10 +1,12 @@ +//go:build !gitaly_test_sha256 + package git import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) type fakeProtocolMessage struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine.go index 7638a606e7..c11bc1fe8e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine.go @@ -9,10 +9,10 @@ import ( "sort" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine_test.go index c6a0ce9685..161426bf84 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/quarantine_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/quarantine_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package quarantine import ( @@ -8,12 +10,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // entry represents a filesystem entry. An entry represents a dir if children is a non-nil map. @@ -51,7 +53,7 @@ func TestQuarantine_lifecycle(t *testing.T) { require.NoError(t, err) require.Equal(t, repo, quarantine.repo) - require.Equal(t, &gitalypb.Repository{ + testhelper.ProtoEqual(t, &gitalypb.Repository{ StorageName: repo.StorageName, RelativePath: repo.RelativePath, GitObjectDirectory: relativeQuarantinePath, @@ -86,7 +88,11 @@ func TestQuarantine_Migrate(t *testing.T) { t.Run("no changes", func(t *testing.T) { ctx := testhelper.Context(t) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, + gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) oldContents := listEntries(t, repoPath) @@ -101,7 +107,10 @@ func TestQuarantine_Migrate(t *testing.T) { t.Run("simple change", func(t *testing.T) { ctx := testhelper.Context(t) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) oldContents := listEntries(t, repoPath) require.NotContains(t, oldContents, "objects/file") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/testhelper_test.go index 38d896d427..6bd4836d7d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package quarantine import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff/rawdiff.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff/rawdiff.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff/rawdiff.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff/rawdiff.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff/rawdiff_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff/rawdiff_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff/rawdiff_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff/rawdiff_test.go index 4b984d8589..33ce6422da 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff/rawdiff_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff/rawdiff_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package rawdiff import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference.go index 8f2c34981f..225231188b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference.go @@ -5,18 +5,53 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" +) + +// InternalReferenceType is the type of an internal reference. +type InternalReferenceType int + +const ( + // InternalReferenceTypeHidden indicates that a reference should never be advertised or + // writeable. + InternalReferenceTypeHidden = InternalReferenceType(iota + 1) + // InternalReferenceTypeReadonly indicates that a reference should be advertised, but not + // writeable. + InternalReferenceTypeReadonly ) // InternalRefPrefixes is an array of all reference prefixes which are used internally by GitLab. // These need special treatment in some cases, e.g. to restrict writing to them. -var InternalRefPrefixes = [...]string{ - "refs/environments/", - "refs/keep-around/", - "refs/merge-requests/", - "refs/pipelines/", +var InternalRefPrefixes = map[string]InternalReferenceType{ + // Environments may be interesting to the user in case they want to figure out what exact + // reference an environment has been constructed from. + "refs/environments/": InternalReferenceTypeReadonly, + + // Keep-around references are only used internally to keep alive objects, and thus they + // shouldn't be exposed to the user. + "refs/keep-around/": InternalReferenceTypeHidden, + + // Merge request references should be readable by the user so that they can still fetch the + // changes of specific merge requests. + "refs/merge-requests/": InternalReferenceTypeReadonly, + + // Pipelines may be interesting to the user in case they want to figure out what exact + // reference a specific pipeline has been running with. + "refs/pipelines/": InternalReferenceTypeReadonly, + + // Remote references shouldn't typically exist in repositories nowadays anymore, and there + // is no reason to expose them to the user. + "refs/remotes/": InternalReferenceTypeHidden, + + // Temporary references are used internally by Rails for various operations and should not + // be exposed to the user. + "refs/tmp/": InternalReferenceTypeHidden, } +// ObjectPoolRefNamespace is the namespace used for the references of the primary pool member part +// of an object pool. +const ObjectPoolRefNamespace = "refs/remotes/origin" + // Revision represents anything that resolves to either a commit, multiple // commits or to an object different than a commit. This could be e.g. // "master", "master^{commit}", an object hash or similar. See gitrevisions(1) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference_test.go index 9a22e79fe2..f17493bf31 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/reference_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/reference_test.go @@ -1,13 +1,15 @@ +//go:build !gitaly_test_sha256 + package git_test import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestCheckRefFormat(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/helper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/helper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/helper_test.go index 619ff5b165..b34495dafe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/helper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/helper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package remoterepo import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository.go index c31248f650..fb3fe0273b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -52,7 +52,7 @@ func (rr *Repo) ResolveRevision(ctx context.Context, revision git.Revision) (git return "", git.ErrReferenceNotFound } - oid, err := git.NewObjectIDFromHex(oidHex) + oid, err := git.ObjectHashSHA1.FromHex(oidHex) if err != nil { return "", err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository_test.go index a6f5e4e8ca..f7b3f53453 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo/repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo/repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package remoterepo_test import ( @@ -5,19 +7,19 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -53,23 +55,16 @@ func TestRepository(t *testing.T) { pool := client.NewPool() defer pool.Close() - gittest.TestRepository(t, cfg, func(ctx context.Context, t testing.TB, seeded bool) (git.Repository, string) { - t.Helper() - - seed := "" - if seeded { - seed = gittest.SeedGitLabTest - } + gittest.TestRepository(t, cfg, func(ctx context.Context, tb testing.TB) (git.Repository, string) { + tb.Helper() ctx, err := storage.InjectGitalyServers(ctx, "default", cfg.SocketPath, cfg.Auth.Token) - require.NoError(t, err) + require.NoError(tb, err) - pbRepo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: seed, - }) + repoProto, repoPath := gittest.CreateRepository(ctx, tb, cfg) - repo, err := remoterepo.New(metadata.OutgoingToIncoming(ctx), pbRepo, pool) - require.NoError(t, err) + repo, err := remoterepo.New(metadata.OutgoingToIncoming(ctx), repoProto, pool) + require.NoError(tb, err) return repo, repoPath }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/repository.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/repository.go index ee48e2320d..8f969bdf52 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/repository.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // DefaultBranch is the default reference written to HEAD when a repository is created @@ -55,4 +55,5 @@ type RepositoryExecutor interface { Exec(ctx context.Context, cmd Cmd, opts ...CmdOpt) (*command.Command, error) ExecAndWait(ctx context.Context, cmd Cmd, opts ...CmdOpt) error GitVersion(ctx context.Context) (Version, error) + ObjectHash(ctx context.Context) (ObjectHash, error) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/repository/repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/repository/repository.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/repository/repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/repository/repository.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/proto.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/proto.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision.go index 97dac733b3..89d1e05d45 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/proto.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision.go @@ -3,14 +3,8 @@ package git import ( "bytes" "fmt" - "time" ) -// FallbackTimeValue is the value returned by `SafeTimeParse` in case it -// encounters a parse error. It's the maximum time value possible in golang. -// See https://gitlab.com/gitlab-org/gitaly/issues/556#note_40289573 -var FallbackTimeValue = time.Unix(1<<63-62135596801, 999999999) - func validateRevision(revision []byte, allowEmpty bool) error { if !allowEmpty && len(revision) == 0 { return fmt.Errorf("empty revision") @@ -18,7 +12,7 @@ func validateRevision(revision []byte, allowEmpty bool) error { if bytes.HasPrefix(revision, []byte("-")) { return fmt.Errorf("revision can't start with '-'") } - if bytes.Contains(revision, []byte(" ")) { + if bytes.ContainsAny(revision, " \t\n\r") { return fmt.Errorf("revision can't contain whitespace") } if bytes.Contains(revision, []byte("\x00")) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision_test.go new file mode 100644 index 0000000000..edd574d5c4 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/revision_test.go @@ -0,0 +1,79 @@ +//go:build !gitaly_test_sha256 + +package git + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidateRevision(t *testing.T) { + for _, tc := range []struct { + desc string + revision string + expectedErr error + }{ + { + desc: "empty revision", + revision: "", + expectedErr: fmt.Errorf("empty revision"), + }, + { + desc: "valid revision", + revision: "foo/bar", + }, + { + desc: "leading dash", + revision: "-foo/bar", + expectedErr: fmt.Errorf("revision can't start with '-'"), + }, + { + desc: "intermediate dash", + revision: "foo-bar", + }, + { + desc: "space", + revision: "foo bar", + expectedErr: fmt.Errorf("revision can't contain whitespace"), + }, + { + desc: "newline", + revision: "foo\nbar", + expectedErr: fmt.Errorf("revision can't contain whitespace"), + }, + { + desc: "tab", + revision: "foo\tbar", + expectedErr: fmt.Errorf("revision can't contain whitespace"), + }, + { + desc: "carriage-return", + revision: "foo\rbar", + expectedErr: fmt.Errorf("revision can't contain whitespace"), + }, + { + desc: "NUL-byte", + revision: "foo\x00bar", + expectedErr: fmt.Errorf("revision can't contain NUL"), + }, + { + desc: "colon", + revision: "foo/bar:baz", + expectedErr: fmt.Errorf("revision can't contain ':'"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.expectedErr, ValidateRevision([]byte(tc.revision))) + + // `ValidateRevision()` and `ValidateRevisionAllowEmpty()` behave the same, + // except in the case where the revision is empty. In that case, the latter + // does not return an error. + if tc.revision == "" { + tc.expectedErr = nil + } + require.Equal(t, tc.expectedErr, ValidateRevisionAllowEmpty([]byte(tc.revision))) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config.go new file mode 100644 index 0000000000..ad126e447f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config.go @@ -0,0 +1,112 @@ +package smudge + +import ( + "encoding/json" + "errors" + "fmt" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" +) + +// ConfigEnvironmentKey is the key that gitaly-lfs-smudge expects the configuration to exist at. The +// value of this environment variable should be the JSON-encoded `Config` struct. +const ConfigEnvironmentKey = "GITALY_LFS_SMUDGE_CONFIG" + +// DriverType determines the type of the smudge filter. +type DriverType int + +const ( + // DriverTypeFilter indicates that the smudge filter is to be run once per object. This is + // the current default but will be phased out eventually in favor of DriverTypeProcess. + DriverTypeFilter = DriverType(0) + // DriverTypeProcess is a long-running smudge filter that can process multiple objects in + // one session. See gitattributes(5), "Long Running Filter Process". + DriverTypeProcess = DriverType(1) +) + +// Config is the configuration used to run gitaly-lfs-smudge. It must be injected via environment +// variables. +type Config struct { + // GlRepository is the GitLab repository identifier that is required so that we can query + // the corresponding Rails' repository for the respective LFS contents. + GlRepository string `json:"gl_repository"` + // Gitlab contains configuration so that we can connect to Rails in order to retrieve LFS + // contents. + Gitlab config.Gitlab `json:"gitlab"` + // TLS contains configuration for setting up a TLS-encrypted connection to Rails. + TLS config.TLS `json:"tls"` + // DriverType is the type of the smudge driver that should be used. + DriverType DriverType `json:"driver_type"` +} + +// ConfigFromEnvironment loads the Config structure from the set of given environment variables. +func ConfigFromEnvironment(environment []string) (Config, error) { + var cfg Config + + // If ConfigEnvironmentKey is set, then we use that instead of the separate environment + // variables queried for below. This has been newly introduced in v15.1, so the fallback + // to the old environment variables can be removed with v15.2. + if encodedCfg := env.ExtractValue(environment, ConfigEnvironmentKey); encodedCfg != "" { + if err := json.Unmarshal([]byte(encodedCfg), &cfg); err != nil { + return Config{}, fmt.Errorf("unable to unmarshal config: %w", err) + } + + return cfg, nil + } + + cfg.GlRepository = env.ExtractValue(environment, "GL_REPOSITORY") + if cfg.GlRepository == "" { + return Config{}, fmt.Errorf("error loading project: GL_REPOSITORY is not defined") + } + + u := env.ExtractValue(environment, "GL_INTERNAL_CONFIG") + if u == "" { + return Config{}, fmt.Errorf("unable to retrieve GL_INTERNAL_CONFIG") + } + + if err := json.Unmarshal([]byte(u), &cfg.Gitlab); err != nil { + return Config{}, fmt.Errorf("unable to unmarshal GL_INTERNAL_CONFIG: %w", err) + } + + u = env.ExtractValue(environment, "GITALY_TLS") + if u == "" { + return Config{}, errors.New("unable to retrieve GITALY_TLS") + } + + if err := json.Unmarshal([]byte(u), &cfg.TLS); err != nil { + return Config{}, fmt.Errorf("unable to unmarshal GITALY_TLS: %w", err) + } + + return cfg, nil +} + +// Environment encodes the given configuration as an environment variable that can be injected into +// `gitaly-lfs-smudge`. +func (c Config) Environment() (string, error) { + marshalled, err := json.Marshal(c) + if err != nil { + return "", fmt.Errorf("marshalling configuration: %w", err) + } + + return fmt.Sprintf("%s=%s", ConfigEnvironmentKey, marshalled), nil +} + +// GitConfiguration returns the Git configuration required to run the smudge filter. +func (c Config) GitConfiguration(cfg config.Cfg) (git.ConfigPair, error) { + switch c.DriverType { + case DriverTypeFilter: + return git.ConfigPair{ + Key: "filter.lfs.smudge", + Value: cfg.BinaryPath("gitaly-lfs-smudge"), + }, nil + case DriverTypeProcess: + return git.ConfigPair{ + Key: "filter.lfs.process", + Value: cfg.BinaryPath("gitaly-lfs-smudge"), + }, nil + default: + return git.ConfigPair{}, fmt.Errorf("unknown driver type: %v", c.DriverType) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config_test.go new file mode 100644 index 0000000000..1a146959ff --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge/config_test.go @@ -0,0 +1,173 @@ +//go:build !gitaly_test_sha256 + +package smudge + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" +) + +func TestConfigFromEnvironment(t *testing.T) { + gitlabCfg := config.Gitlab{ + URL: "https://example.com", + RelativeURLRoot: "gitlab", + HTTPSettings: config.HTTPSettings{ + ReadTimeout: 1, + User: "user", + Password: "correcthorsebatterystaple", + CAFile: "/ca/file", + CAPath: "/ca/path", + }, + SecretFile: "/secret/path", + } + + tlsCfg := config.TLS{ + CertPath: "/cert/path", + KeyPath: "/key/path", + } + + fullCfg := Config{ + GlRepository: "repo", + Gitlab: gitlabCfg, + TLS: tlsCfg, + } + + marshalledGitlabCfg, err := json.Marshal(gitlabCfg) + require.NoError(t, err) + + marshalledTLSCfg, err := json.Marshal(tlsCfg) + require.NoError(t, err) + + marshalledFullCfg, err := json.Marshal(fullCfg) + require.NoError(t, err) + + for _, tc := range []struct { + desc string + environment []string + expectedErr string + expectedCfg Config + }{ + { + desc: "empty environment", + expectedErr: "error loading project: GL_REPOSITORY is not defined", + }, + { + desc: "successful via separate envvars", + environment: []string{ + "GL_REPOSITORY=repo", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_TLS=" + string(marshalledTLSCfg), + }, + expectedCfg: Config{ + GlRepository: "repo", + Gitlab: gitlabCfg, + TLS: tlsCfg, + }, + }, + { + desc: "successful via single envvar", + environment: []string{ + "GITALY_LFS_SMUDGE_CONFIG=" + string(marshalledFullCfg), + "GL_REPOSITORY=garbage", + "GL_INTERNAL_CONFIG=garbage", + "GITALY_TLS=garbage", + }, + expectedCfg: fullCfg, + }, + { + desc: "single envvar overrides separate envvars", + environment: []string{ + "GITALY_LFS_SMUDGE_CONFIG=" + string(marshalledFullCfg), + }, + expectedCfg: fullCfg, + }, + { + desc: "invalid full config", + environment: []string{ + "GITALY_LFS_SMUDGE_CONFIG=invalid", + }, + expectedErr: "unable to unmarshal config: invalid character 'i' looking for beginning of value", + }, + { + desc: "missing GlRepository", + environment: []string{ + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_TLS=" + string(marshalledTLSCfg), + }, + expectedErr: "error loading project: GL_REPOSITORY is not defined", + }, + { + desc: "missing Gitlab config", + environment: []string{ + "GL_REPOSITORY=repo", + "GITALY_TLS=" + string(marshalledTLSCfg), + }, + expectedErr: "unable to retrieve GL_INTERNAL_CONFIG", + }, + { + desc: "invalid Gitlab config", + environment: []string{ + "GL_REPOSITORY=repo", + "GL_INTERNAL_CONFIG=invalid", + "GITALY_TLS=" + string(marshalledTLSCfg), + }, + expectedErr: "unable to unmarshal GL_INTERNAL_CONFIG: invalid character 'i' looking for beginning of value", + }, + { + desc: "missing TLS config", + environment: []string{ + "GL_REPOSITORY=repo", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + }, + expectedErr: "unable to retrieve GITALY_TLS", + }, + { + desc: "invalid TLS config", + environment: []string{ + "GL_REPOSITORY=repo", + "GL_INTERNAL_CONFIG=" + string(marshalledGitlabCfg), + "GITALY_TLS=invalid", + }, + expectedErr: "unable to unmarshal GITALY_TLS: invalid character 'i' looking for beginning of value", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + cfg, err := ConfigFromEnvironment(tc.environment) + if tc.expectedErr == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tc.expectedErr) + } + require.Equal(t, tc.expectedCfg, cfg) + }) + } +} + +func TestConfig_Environment(t *testing.T) { + cfg := Config{ + GlRepository: "repo", + Gitlab: config.Gitlab{ + URL: "https://example.com", + RelativeURLRoot: "gitlab", + HTTPSettings: config.HTTPSettings{ + ReadTimeout: 1, + User: "user", + Password: "correcthorsebatterystaple", + CAFile: "/ca/file", + CAPath: "/ca/path", + }, + SecretFile: "/secret/path", + }, + TLS: config.TLS{ + CertPath: "/cert/path", + KeyPath: "/key/path", + }, + } + + env, err := cfg.Environment() + require.NoError(t, err) + require.Equal(t, `GITALY_LFS_SMUDGE_CONFIG={"gl_repository":"repo","gitlab":{"url":"https://example.com","relative_url_root":"gitlab","http_settings":{"read_timeout":1,"user":"user","password":"correcthorsebatterystaple","ca_file":"/ca/file","ca_path":"/ca/path"},"secret_file":"/secret/path"},"tls":{"cert_path":"/cert/path","key_path":"/key/path"},"driver_type":0}`, env) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/ssh.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/ssh.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/ssh.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/ssh.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/ssh_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/ssh_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/ssh_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/ssh_test.go index a349c1c741..c7e7d6aa1f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/ssh_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/ssh_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( @@ -6,7 +8,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestBuildSSHInvocation(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/staticargs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/staticargs.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/staticargs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/staticargs.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/commit_graph.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/commit_graph.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/commit_graph.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/commit_graph.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/commit_graph_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/commit_graph_test.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/commit_graph_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/commit_graph_test.go index 2d52a74b28..f6a38e104d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/commit_graph_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/commit_graph_test.go @@ -1,11 +1,14 @@ +//go:build !gitaly_test_sha256 + package stats import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestIsMissingBloomFilters(t *testing.T) { @@ -32,8 +35,13 @@ func TestIsMissingBloomFilters(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - _, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) if len(tc.args) > 0 { gittest.Exec(t, cfg, append([]string{"-C", repoPath}, tc.args...)...) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/fetch_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/fetch_pack.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/fetch_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/fetch_pack.go index 45ab298e90..071f41384a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/fetch_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/fetch_pack.go @@ -7,7 +7,7 @@ import ( "io" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) // FetchPack is used to parse the response body of a git-fetch-pack(1) request. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git.go index de58955792..5ec5dace05 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // LogObjectsInfo read statistics of the git repo objects diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git_test.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git_test.go index 4d64fe405b..70faf4f26a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/git_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/git_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -10,20 +12,26 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestLogObjectInfo(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repo1, repoPath1 := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - repo2, repoPath2 := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - ctx := testhelper.Context(t) + repo1, repoPath1 := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) + repo2, repoPath2 := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) requireLog := func(entries []*logrus.Entry) map[string]interface{} { for _, entry := range entries { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_clone.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_clone.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_clone.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_clone.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_clone_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_clone_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_clone_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_clone_test.go index fa42d82ded..4e9886b77c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_clone_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_clone_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -8,9 +10,9 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestClone(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_fetch_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_fetch_pack.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_fetch_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_fetch_pack.go index a688e7c19b..07089d5b18 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_fetch_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_fetch_pack.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) // HTTPFetchPack is a FetchPack obtained via a clone of a target repository via HTTP. It contains diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push.go index 00bc970627..58020ea2ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push.go @@ -5,7 +5,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) // HTTPPush hosts information about a typical HTTP-based push. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push_test.go index 197afaa79e..f35bec39fb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_push_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_push_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -11,12 +13,12 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestPerformHTTPPush(t *testing.T) { @@ -40,7 +42,10 @@ func TestPerformHTTPPush(t *testing.T) { { desc: "single revision", preparePush: func(t *testing.T, cfg config.Cfg) ([]PushCommand, io.Reader) { - _, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) commit := gittest.WriteCommit(t, cfg, repoPath) revisions := strings.NewReader(commit.String()) @@ -49,7 +54,7 @@ func TestPerformHTTPPush(t *testing.T) { ) return []PushCommand{ - {OldOID: git.ZeroOID, NewOID: commit, Reference: "refs/heads/foobar"}, + {OldOID: git.ObjectHashSHA1.ZeroOID, NewOID: commit, Reference: "refs/heads/foobar"}, }, bytes.NewReader(pack) }, expectedTimings: []string{ @@ -74,7 +79,10 @@ func TestPerformHTTPPush(t *testing.T) { { desc: "many revisions", preparePush: func(t *testing.T, cfg config.Cfg) ([]PushCommand, io.Reader) { - _, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) commands := make([]PushCommand, 1000) commits := make([]string, len(commands)) @@ -82,7 +90,7 @@ func TestPerformHTTPPush(t *testing.T) { commit := gittest.WriteCommit(t, cfg, repoPath) commits[i] = commit.String() commands[i] = PushCommand{ - OldOID: git.ZeroOID, + OldOID: git.ObjectHashSHA1.ZeroOID, NewOID: commit, Reference: git.ReferenceName(fmt.Sprintf("refs/heads/branch-%d", i)), } @@ -121,7 +129,7 @@ func TestPerformHTTPPush(t *testing.T) { oldOID := git.ObjectID(text.ChompBytes(commit)) return []PushCommand{ - {OldOID: oldOID, NewOID: git.ZeroOID, Reference: "refs/heads/feature"}, + {OldOID: oldOID, NewOID: git.ObjectHashSHA1.ZeroOID, Reference: "refs/heads/feature"}, }, nil }, expectedTimings: []string{ @@ -149,7 +157,7 @@ func TestPerformHTTPPush(t *testing.T) { oldOID := git.ObjectID(strings.Repeat("1", 40)) return []PushCommand{ - {OldOID: oldOID, NewOID: git.ZeroOID, Reference: "refs/heads/master"}, + {OldOID: oldOID, NewOID: git.ObjectHashSHA1.ZeroOID, Reference: "refs/heads/master"}, }, nil }, expectedErr: fmt.Errorf("parsing packfile response: %w", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_reference_discovery.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_reference_discovery.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_reference_discovery.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_reference_discovery.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_send_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_send_pack.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_send_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_send_pack.go index 7c4b7e9f9f..71c8eff387 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/http_send_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/http_send_pack.go @@ -9,7 +9,7 @@ import ( "net/http" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) // ResponseBody returns how long it took to receive the last bytes of the response body. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation.go index 7e3fa5a062..ca152d70e7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation.go @@ -7,11 +7,11 @@ import ( "strings" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type PackfileNegotiation struct { // Total size of all pktlines' data PayloadSize int64 @@ -31,7 +31,7 @@ type PackfileNegotiation struct { Filter string } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func ParsePackfileNegotiation(body io.Reader) (PackfileNegotiation, error) { n := PackfileNegotiation{} return n, n.Parse(body) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation_test.go index 8fce4ec3df..a08e16472f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/packfile_negotiation_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/packfile_negotiation_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -6,7 +8,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile.go index a9a2ced15c..68d4e09913 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile.go @@ -10,8 +10,8 @@ import ( "strconv" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // HasBitmap returns whether or not the repository contains an object bitmap. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile_test.go index 582ae558b1..dff0ede487 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/profile_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/profile_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -7,17 +9,19 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestRepositoryProfile(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - testRepo, testRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) - ctx := testhelper.Context(t) + testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) hasBitmap, err := HasBitmap(testRepoPath) require.NoError(t, err) @@ -49,7 +53,6 @@ func TestRepositoryProfile(t *testing.T) { gittest.WithTreeEntries(gittest.TreeEntry{ Mode: "100644", Path: "blob", OID: git.ObjectID(blobID), }), - gittest.WithParents(), ) gittest.Exec(t, cfg, "-C", testRepoPath, "update-ref", "refs/heads/"+blobID, commitID.String()) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery.go index ec2e384235..1a0b1e624d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" ) // Reference as used by the reference discovery protocol diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery_test.go index 53edbc37f6..5b529249a1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/reference_discovery_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/reference_discovery_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -5,7 +7,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" ) func TestSingleRefParses(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack.go index 53271377fc..97ba3e9d07 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack.go @@ -7,7 +7,7 @@ import ( "io" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) // SendPack is used to parse the response body of a git-send-pack(1) request. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack_test.go index 6dd126e85c..eda2d06cc4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/send_pack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/send_pack_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package stats import ( @@ -7,7 +9,7 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" ) func TestSendPack_Parse(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/testhelper_test.go index b842dc9498..06a7926456 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/stats/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/stats/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package stats import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/no-alternates/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/no-alternates/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/no-alternates/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/no-alternates/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo0/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo0/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo0/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo0/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo1/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo1/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo1/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo1/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo2/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo2/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo2/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo2/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo3/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo3/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo3/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo3/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo4/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo4/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo4/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo4/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo5/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo5/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo5/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo5/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo6/objects/info/alternates b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo6/objects/info/alternates similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repo6/objects/info/alternates rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repo6/objects/info/alternates diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repoB/objects/.gitkeep b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repoB/objects/.gitkeep similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/testdata/objdirs/repoB/objects/.gitkeep rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testdata/objdirs/repoB/objects/.gitkeep diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testhelper_test.go new file mode 100644 index 0000000000..21a27883e0 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/testhelper_test.go @@ -0,0 +1,22 @@ +//go:build !gitaly_test_sha256 + +package git + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func newCommandFactory(tb testing.TB, cfg config.Cfg, opts ...ExecCommandFactoryOption) *ExecCommandFactory { + gitCmdFactory, cleanup, err := NewExecCommandFactory(cfg, opts...) + require.NoError(tb, err) + tb.Cleanup(cleanup) + return gitCmdFactory +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser.go index 8e138f2543..64e97cf968 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser.go @@ -3,7 +3,7 @@ package trailerparser import ( "bytes" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -33,7 +33,7 @@ const ( // Where \0 is a NULL byte. The input should not end in a NULL byte. // // Trailers must be separated with a null byte, as their values can include any -// other separater character. NULL bytes however are not allowed in commit +// other separator character. NULL bytes however are not allowed in commit // messages, and thus can't occur in trailers. // // The key-value separator must be a colon, as this is the separator the Git CLI diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser_test.go index 092b65cafe..b7c0a22262 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser/trailerparser_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser/trailerparser_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package trailerparser import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/tree_entry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/tree_entry.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/tree_entry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/tree_entry.go index b5fe8c3a1a..f051ae76ee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/tree_entry.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/tree_entry.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strconv" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // NewTreeEntry is a helper to construct a gitalypb.TreeEntry from the provided parameters. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks.go index c2f859e173..f7d82a3d57 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks.go @@ -7,18 +7,18 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // UpdaterWithHooks updates a ref with Git hooks. @@ -30,15 +30,16 @@ type UpdaterWithHooks struct { catfileCache catfile.Cache } -// HookError contains an error message when executing a hook. -type HookError struct { - err error - stdout string - stderr string +// CustomHookError contains an error message when executing a custom hook. +type CustomHookError struct { + err error + hookType git.Hook + stdout string + stderr string } // Error returns an error message. -func (e HookError) Error() string { +func (e CustomHookError) Error() string { // If custom hooks write the "GitLab: " or "GL-HOOK-ERR: " prefix to either their stderr or // their stdout, then this prefix is taken as a hint by Rails to print the error as-is in // the web interface. We must thus make sure to not modify these custom hook error messages @@ -50,31 +51,64 @@ func (e HookError) Error() string { // // Eventually, we should find a solution which allows us to bubble up the error in hook // package such that we can also make proper use of structured errors for custom hooks. - var customHookError hook.CustomHookError - if errors.As(e.err, &customHookError) { - if len(strings.TrimSpace(e.stderr)) > 0 { - return e.stderr - } - if len(strings.TrimSpace(e.stdout)) > 0 { - return e.stdout - } - } else { - if len(strings.TrimSpace(e.stderr)) > 0 { - return fmt.Sprintf("%v, stderr: %q", e.err.Error(), e.stderr) - } - if len(strings.TrimSpace(e.stdout)) > 0 { - return fmt.Sprintf("%v, stdout: %q", e.err.Error(), e.stdout) - } + if len(strings.TrimSpace(e.stderr)) > 0 { + return e.stderr + } + if len(strings.TrimSpace(e.stdout)) > 0 { + return e.stdout } return e.err.Error() } +// Proto returns the Protobuf representation of this error. +func (e CustomHookError) Proto() *gitalypb.CustomHookError { + hookType := gitalypb.CustomHookError_HOOK_TYPE_UNSPECIFIED + switch e.hookType { + case git.PreReceiveHook: + hookType = gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE + case git.UpdateHook: + hookType = gitalypb.CustomHookError_HOOK_TYPE_UPDATE + case git.PostReceiveHook: + hookType = gitalypb.CustomHookError_HOOK_TYPE_POSTRECEIVE + } + + return &gitalypb.CustomHookError{ + HookType: hookType, + Stdout: []byte(e.stdout), + Stderr: []byte(e.stderr), + } +} + // Unwrap will return the embedded error. -func (e HookError) Unwrap() error { +func (e CustomHookError) Unwrap() error { return e.err } +// wrapHookError wraps errors returned by the hook manager into either a CustomHookError if it +// returned a `hook.CustomHookError`, or alternatively return the error with stderr or stdout +// appended to the message. +func wrapHookError(err error, hookType git.Hook, stdout, stderr string) error { + var customHookErr hook.CustomHookError + if errors.As(err, &customHookErr) { + return CustomHookError{ + err: err, + hookType: hookType, + stdout: stdout, + stderr: stderr, + } + } + + if len(strings.TrimSpace(stderr)) > 0 { + return fmt.Errorf("%w, stderr: %q", err, stderr) + } + if len(strings.TrimSpace(stdout)) > 0 { + return fmt.Errorf("%w, stdout: %q", err, stdout) + } + + return err +} + // Error reports an error in git update-ref type Error struct { // Reference is the name of the reference that would have been updated. @@ -112,7 +146,7 @@ func NewUpdaterWithHooks( // repository. func (u *UpdaterWithHooks) UpdateReference( ctx context.Context, - repo *gitalypb.Repository, + repoProto *gitalypb.Repository, user *gitalypb.User, quarantineDir *quarantine.Dir, reference git.ReferenceName, @@ -123,22 +157,29 @@ func (u *UpdaterWithHooks) UpdateReference( if tx, err := txinfo.TransactionFromContext(ctx); err == nil { transaction = &tx } else if !errors.Is(err, txinfo.ErrTransactionNotFound) { - return err + return fmt.Errorf("getting transaction: %w", err) + } + + repo := u.localrepo(repoProto) + + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return fmt.Errorf("detecting object hash: %w", err) } if reference == "" { - return helper.ErrInternalf("UpdateReference: got no reference") + return fmt.Errorf("reference cannot be empty") } - if err := git.ValidateObjectID(oldrev.String()); err != nil { - return helper.ErrInternalf("UpdateReference: got invalid old value: %w", err) + if err := objectHash.ValidateHex(oldrev.String()); err != nil { + return fmt.Errorf("validating old value: %w", err) } - if err := git.ValidateObjectID(newrev.String()); err != nil { - return helper.ErrInternalf("UpdateReference: got invalid new value: %w", err) + if err := objectHash.ValidateHex(newrev.String()); err != nil { + return fmt.Errorf("validating new value: %w", err) } changes := fmt.Sprintf("%s %s %s\n", oldrev, newrev, reference) - receiveHooksPayload := git.ReceiveHooksPayload{ + receiveHooksPayload := git.UserDetails{ UserID: user.GetGlId(), Username: user.GetGlUsername(), Protocol: "web", @@ -149,19 +190,19 @@ func (u *UpdaterWithHooks) UpdateReference( // repository, which carries information about the quarantined object directory. This is // then subsequently passed to Rails, which can use the quarantine directory to more // efficiently query which objects are new. - quarantinedRepo := repo + quarantinedRepo := repoProto if quarantineDir != nil { quarantinedRepo = quarantineDir.QuarantinedRepo() } - hooksPayload, err := git.NewHooksPayload(u.cfg, quarantinedRepo, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.RawFromContext(ctx)).Env() + hooksPayload, err := git.NewHooksPayload(u.cfg, quarantinedRepo, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() if err != nil { - return err + return fmt.Errorf("constructing hooks payload: %w", err) } var stdout, stderr bytes.Buffer if err := u.hookManager.PreReceiveHook(ctx, quarantinedRepo, pushOptions, []string{hooksPayload}, strings.NewReader(changes), &stdout, &stderr); err != nil { - return HookError{err: err, stdout: stdout.String(), stderr: stderr.String()} + return fmt.Errorf("running pre-receive hooks: %w", wrapHookError(err, git.PreReceiveHook, stdout.String(), stderr.String())) } // Now that Rails has told us that the change is okay via the pre-receive hook, we can @@ -176,14 +217,14 @@ func (u *UpdaterWithHooks) UpdateReference( // We only need to update the hooks payload to the unquarantined repo in case we // had a quarantine environment. Otherwise, the initial hooks payload is for the // real repository anyway. - hooksPayload, err = git.NewHooksPayload(u.cfg, repo, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.RawFromContext(ctx)).Env() + hooksPayload, err = git.NewHooksPayload(u.cfg, repoProto, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() if err != nil { - return err + return fmt.Errorf("constructing quarantined hooks payload: %w", err) } } if err := u.hookManager.UpdateHook(ctx, quarantinedRepo, reference.String(), oldrev.String(), newrev.String(), []string{hooksPayload}, &stdout, &stderr); err != nil { - return HookError{err: err, stdout: stdout.String(), stderr: stderr.String()} + return fmt.Errorf("running update hooks: %w", wrapHookError(err, git.UpdateHook, stdout.String(), stderr.String())) } // We are already manually invoking the reference-transaction hook, so there is no need to @@ -196,12 +237,12 @@ func (u *UpdaterWithHooks) UpdateReference( // is packed, which is obviously a bad thing as Gitaly nodes may be differently packed. We // thus continue to manually drive the reference-transaction hook here, which doesn't have // this problem. - updater, err := New(ctx, u.localrepo(repo), WithDisabledTransactions()) + updater, err := New(ctx, repo, WithDisabledTransactions()) if err != nil { return fmt.Errorf("creating updater: %w", err) } - if err := updater.Update(reference, newrev.String(), oldrev.String()); err != nil { + if err := updater.Update(reference, newrev, oldrev); err != nil { return fmt.Errorf("queueing ref update: %w", err) } @@ -219,7 +260,7 @@ func (u *UpdaterWithHooks) UpdateReference( defer func() { _ = updater.Cancel() }() if err := u.hookManager.ReferenceTransactionHook(ctx, hook.ReferenceTransactionPrepared, []string{hooksPayload}, strings.NewReader(changes)); err != nil { - return HookError{err: err, stdout: stdout.String(), stderr: stderr.String()} + return fmt.Errorf("executing preparatory reference-transaction hook: %w", err) } if err := updater.Commit(); err != nil { @@ -231,11 +272,27 @@ func (u *UpdaterWithHooks) UpdateReference( } if err := u.hookManager.ReferenceTransactionHook(ctx, hook.ReferenceTransactionCommitted, []string{hooksPayload}, strings.NewReader(changes)); err != nil { - return HookError{err: err} + return fmt.Errorf("executing committing reference-transaction hook: %w", err) } - if err := u.hookManager.PostReceiveHook(ctx, repo, pushOptions, []string{hooksPayload}, strings.NewReader(changes), &stdout, &stderr); err != nil { - return HookError{err: err, stdout: stdout.String(), stderr: stderr.String()} + if err := u.hookManager.PostReceiveHook(ctx, repoProto, pushOptions, []string{hooksPayload}, strings.NewReader(changes), &stdout, &stderr); err != nil { + // CustomHook errors are returned in case a custom hook has returned an error code. + // The post-receive hook has special semantics though. Quoting githooks(5): + // + // This hook does not affect the outcome of git receive-pack, as it is called + // after the real work is done. + // + // This means that even if the hook returns an error, then that error should not + // impact whatever git-receive-pack(1) has been doing. And given that we emulate + // behaviour of this command here, we need to behave the same. + var customHookErr hook.CustomHookError + if errors.As(err, &customHookErr) { + // Only log the error when we've got a custom-hook error, but otherwise + // ignore it and continue with whatever we have been doing. + ctxlogrus.Extract(ctx).WithError(err).Error("custom post-receive hook returned an error") + } else { + return fmt.Errorf("running post-receive hooks: %w", wrapHookError(err, git.PostReceiveHook, stdout.String(), stderr.String())) + } } return nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks_test.go index cbc037d326..b47db59fe4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/update_with_hooks_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/update_with_hooks_test.go @@ -9,116 +9,121 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) func TestUpdaterWithHooks_UpdateReference_invalidParameters(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) - cfg, repo, _ := testcfg.BuildWithRepo(t) + revA := git.ObjectID(strings.Repeat("a", gittest.DefaultObjectHash.EncodedLen())) + revB := git.ObjectID(strings.Repeat("b", gittest.DefaultObjectHash.EncodedLen())) - user := &gitalypb.User{ - GlId: "1234", - GlUsername: "Username", - Name: []byte("Name"), - Email: []byte("mail@example.com"), - } - - revA, revB := git.ObjectID(strings.Repeat("a", 40)), git.ObjectID(strings.Repeat("b", 40)) - - updater := updateref.NewUpdaterWithHooks(cfg, nil, &hook.MockManager{}, nil, nil) + updater := updateref.NewUpdaterWithHooks(cfg, nil, &hook.MockManager{}, gitCmdFactory, nil) testCases := []struct { desc string ref git.ReferenceName newRev, oldRev git.ObjectID - expectedErr string + expectedErr error }{ { desc: "missing reference", oldRev: revA, newRev: revB, - expectedErr: "got no reference", + expectedErr: fmt.Errorf("reference cannot be empty"), }, { desc: "missing old rev", ref: "refs/heads/master", newRev: revB, - expectedErr: "got invalid old value", + expectedErr: fmt.Errorf("validating old value: %w", fmt.Errorf("%w: %q", git.ErrInvalidObjectID, "")), }, { desc: "missing new rev", ref: "refs/heads/master", oldRev: revB, - expectedErr: "got invalid new value", + expectedErr: fmt.Errorf("validating new value: %w", fmt.Errorf("%w: %q", git.ErrInvalidObjectID, "")), }, { desc: "invalid old rev", ref: "refs/heads/master", newRev: revA, oldRev: "foobar", - expectedErr: "got invalid old value", + expectedErr: fmt.Errorf("validating old value: %w", fmt.Errorf("%w: %q", git.ErrInvalidObjectID, "foobar")), }, { desc: "invalid new rev", ref: "refs/heads/master", newRev: "foobar", oldRev: revB, - expectedErr: "got invalid new value", + expectedErr: fmt.Errorf("validating new value: %w", fmt.Errorf("%w: %q", git.ErrInvalidObjectID, "foobar")), }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - err := updater.UpdateReference(ctx, repo, user, nil, tc.ref, tc.newRev, tc.oldRev) - require.Contains(t, err.Error(), tc.expectedErr) + err := updater.UpdateReference(ctx, repo, gittest.TestUser, nil, tc.ref, tc.newRev, tc.oldRev) + require.Equal(t, tc.expectedErr, err) }) } } func TestUpdaterWithHooks_UpdateReference(t *testing.T) { - ctx := testhelper.Context(t) + t.Parallel() - cfg, repo, repoPath := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) // We need to set up a separate "real" hook service here, as it will be used in // git-update-ref(1) spawned by `updateRefWithHooks()` testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) }) - user := &gitalypb.User{ - GlId: "1234", - GlUsername: "Username", - Name: []byte("Name"), - Email: []byte("mail@example.com"), - } + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) - oldRev := "1e292f8fedd741b75372e19097c76d327140c312" + requirePayload := func(t *testing.T, env []string) { + require.Len(t, env, 1) - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.ReceiveHooksPayload{ - UserID: "1234", - Username: "Username", - Protocol: "web", - }, git.ReceivePackHooks, featureflag.RawFromContext(ctx)).Env() - require.NoError(t, err) + expectedPayload := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ + UserID: gittest.TestUser.GlId, + Username: gittest.TestUser.GlUsername, + Protocol: "web", + }, git.ReceivePackHooks, featureflag.FromContext(ctx)) - expectedEnv := []string{ - payload, + actualPayload, err := git.HooksPayloadFromEnv(env) + require.NoError(t, err) + + // Flags aren't sorted, so we just verify they contain the same elements. + require.ElementsMatch(t, expectedPayload.FeatureFlagsWithValue, actualPayload.FeatureFlagsWithValue) + expectedPayload.FeatureFlagsWithValue = nil + actualPayload.FeatureFlagsWithValue = nil + + require.Equal(t, expectedPayload, actualPayload) } referenceTransactionCalls := 0 @@ -136,30 +141,30 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { preReceive: func(t *testing.T, ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, stdin io.Reader, stdout, stderr io.Writer) error { changes, err := io.ReadAll(stdin) require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s %s refs/heads/master\n", oldRev, git.ZeroOID.String()), string(changes)) + require.Equal(t, fmt.Sprintf("%s %s refs/heads/main\n", commitID, gittest.DefaultObjectHash.ZeroOID.String()), string(changes)) require.Empty(t, pushOptions) - require.Equal(t, env, expectedEnv) + requirePayload(t, env) return nil }, update: func(t *testing.T, ctx context.Context, repo *gitalypb.Repository, ref, oldValue, newValue string, env []string, stdout, stderr io.Writer) error { - require.Equal(t, "refs/heads/master", ref) - require.Equal(t, oldRev, oldValue) - require.Equal(t, newValue, git.ZeroOID.String()) - require.Equal(t, env, expectedEnv) + require.Equal(t, "refs/heads/main", ref) + require.Equal(t, commitID.String(), oldValue) + require.Equal(t, newValue, gittest.DefaultObjectHash.ZeroOID.String()) + requirePayload(t, env) return nil }, postReceive: func(t *testing.T, ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, stdin io.Reader, stdout, stderr io.Writer) error { changes, err := io.ReadAll(stdin) require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s %s refs/heads/master\n", oldRev, git.ZeroOID.String()), string(changes)) - require.Equal(t, env, expectedEnv) + require.Equal(t, fmt.Sprintf("%s %s refs/heads/main\n", commitID.String(), gittest.DefaultObjectHash.ZeroOID.String()), string(changes)) + requirePayload(t, env) require.Empty(t, pushOptions) return nil }, referenceTransaction: func(t *testing.T, ctx context.Context, state hook.ReferenceTransactionState, env []string, stdin io.Reader) error { changes, err := io.ReadAll(stdin) require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s %s refs/heads/master\n", oldRev, git.ZeroOID.String()), string(changes)) + require.Equal(t, fmt.Sprintf("%s %s refs/heads/main\n", commitID.String(), gittest.DefaultObjectHash.ZeroOID.String()), string(changes)) require.Less(t, referenceTransactionCalls, 2) if referenceTransactionCalls == 0 { @@ -169,7 +174,7 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { } referenceTransactionCalls++ - require.Equal(t, env, expectedEnv) + requirePayload(t, env) return nil }, expectedRefDeletion: true, @@ -219,7 +224,7 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { expectedErr: "reference-transaction failure", }, { - desc: "post-receive error", + desc: "post-receive error is ignored", preReceive: func(t *testing.T, ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, stdin io.Reader, stdout, stderr io.Writer) error { return nil }, @@ -234,7 +239,6 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { require.NoError(t, err) return errors.New("ignored") }, - expectedErr: "post-receive failure", expectedRefDeletion: true, }, } @@ -247,7 +251,7 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { gitCmdFactory := gittest.NewCommandFactory(t, cfg) updater := updateref.NewUpdaterWithHooks(cfg, config.NewLocator(cfg), hookManager, gitCmdFactory, nil) - err := updater.UpdateReference(ctx, repo, user, nil, git.ReferenceName("refs/heads/master"), git.ZeroOID, git.ObjectID(oldRev)) + err := updater.UpdateReference(ctx, repo, gittest.TestUser, nil, git.ReferenceName("refs/heads/main"), gittest.DefaultObjectHash.ZeroOID, commitID) if tc.expectedErr == "" { require.NoError(t, err) } else { @@ -255,24 +259,31 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { } if tc.expectedRefDeletion { - contained, err := localrepo.NewTestRepo(t, cfg, repo).HasRevision(ctx, git.Revision("refs/heads/master")) + contained, err := localrepo.NewTestRepo(t, cfg, repo).HasRevision(ctx, git.Revision("refs/heads/main")) require.NoError(t, err) require.False(t, contained, "branch should have been deleted") - gittest.Exec(t, cfg, "-C", repoPath, "branch", "master", oldRev) + gittest.Exec(t, cfg, "-C", repoPath, "branch", "main", commitID.String()) } else { - ref, err := localrepo.NewTestRepo(t, cfg, repo).GetReference(ctx, "refs/heads/master") + ref, err := localrepo.NewTestRepo(t, cfg, repo).GetReference(ctx, "refs/heads/main") require.NoError(t, err) - require.Equal(t, ref.Target, oldRev) + require.Equal(t, ref.Target, commitID.String()) } }) } } func TestUpdaterWithHooks_quarantine(t *testing.T) { - cfg, repoProto, _ := testcfg.BuildWithRepo(t) + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) gitCmdFactory := gittest.NewCommandFactory(t, cfg) locator := config.NewLocator(cfg) - ctx := testhelper.Context(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) unquarantinedRepo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -356,9 +367,9 @@ func TestUpdaterWithHooks_quarantine(t *testing.T) { Email: []byte("mail@example.com"), }, quarantine, - git.ReferenceName("refs/heads/master"), - git.ZeroOID, - git.ObjectID("1e292f8fedd741b75372e19097c76d327140c312"), + git.ReferenceName("refs/heads/main"), + gittest.DefaultObjectHash.ZeroOID, + commitID, )) require.Equal(t, map[string]int{ @@ -369,7 +380,7 @@ func TestUpdaterWithHooks_quarantine(t *testing.T) { "commit": 1, }, hookExecutions) - contained, err := unquarantinedRepo.HasRevision(ctx, git.Revision("refs/heads/master")) + contained, err := unquarantinedRepo.HasRevision(ctx, git.Revision("refs/heads/main")) require.NoError(t, err) require.False(t, contained, "branch should have been deleted") } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref.go index 3708e76c7d..d99b497508 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref/updateref.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref.go @@ -5,19 +5,31 @@ import ( "bytes" "context" "fmt" + "regexp" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) +// ErrAlreadyLocked indicates a reference cannot be locked because another +// process has already locked it. +type ErrAlreadyLocked struct { + Ref string +} + +func (e *ErrAlreadyLocked) Error() string { + return fmt.Sprintf("reference is already locked: %q", e.Ref) +} + // Updater wraps a `git update-ref --stdin` process, presenting an interface // that allows references to be easily updated in bulk. It is not suitable for // concurrent use. type Updater struct { - repo git.RepositoryExecutor - cmd *command.Command - stdout *bufio.Reader - stderr *bytes.Buffer + repo git.RepositoryExecutor + cmd *command.Command + stdout *bufio.Reader + stderr *bytes.Buffer + objectHash git.ObjectHash // withStatusFlushing determines whether the Git version used supports proper flushing of // status messages. @@ -63,7 +75,7 @@ func New(ctx context.Context, repo git.RepositoryExecutor, opts ...UpdaterOpt) ( Flags: []git.Option{git.Flag{Name: "-z"}, git.Flag{Name: "--stdin"}}, }, txOption, - git.WithStdin(command.SetupStdin), + git.WithSetupStdin(), git.WithStderr(&stderr), ) if err != nil { @@ -75,11 +87,17 @@ func New(ctx context.Context, repo git.RepositoryExecutor, opts ...UpdaterOpt) ( return nil, fmt.Errorf("determining git version: %w", err) } + objectHash, err := repo.ObjectHash(ctx) + if err != nil { + return nil, fmt.Errorf("detecting object hash: %w", err) + } + updater := &Updater{ repo: repo, cmd: cmd, stderr: &stderr, stdout: bufio.NewReader(cmd), + objectHash: objectHash, withStatusFlushing: gitVersion.FlushesUpdaterefStatus(), } @@ -94,31 +112,42 @@ func New(ctx context.Context, repo git.RepositoryExecutor, opts ...UpdaterOpt) ( return updater, nil } -// Update commands the reference to be updated to point at the object ID specified in newvalue. If -// newvalue is the zero OID, then the branch will be deleted. If oldvalue is a non-empty string, -// then the reference will only be updated if its current value matches the old value. If the old -// value is the zero OID, then the branch must not exist. -func (u *Updater) Update(reference git.ReferenceName, newvalue, oldvalue string) error { - _, err := fmt.Fprintf(u.cmd, "update %s\x00%s\x00%s\x00", reference.String(), newvalue, oldvalue) +// Update commands the reference to be updated to point at the object ID specified in newOID. If +// newOID is the zero OID, then the branch will be deleted. If oldOID is a non-empty string, then +// the reference will only be updated if its current value matches the old value. If the old value +// is the zero OID, then the branch must not exist. +func (u *Updater) Update(reference git.ReferenceName, newOID, oldOID git.ObjectID) error { + _, err := fmt.Fprintf(u.cmd, "update %s\x00%s\x00%s\x00", reference.String(), newOID, oldOID) return err } // Create commands the reference to be created with the given object ID. The ref must not exist. -func (u *Updater) Create(reference git.ReferenceName, value string) error { - return u.Update(reference, value, git.ZeroOID.String()) +func (u *Updater) Create(reference git.ReferenceName, oid git.ObjectID) error { + return u.Update(reference, oid, u.objectHash.ZeroOID) } // Delete commands the reference to be removed from the repository. This command will ignore any old // state of the reference and just force-remove it. func (u *Updater) Delete(reference git.ReferenceName) error { - return u.Update(reference, git.ZeroOID.String(), "") + return u.Update(reference, u.objectHash.ZeroOID, "") } +var refLockedRegex = regexp.MustCompile("cannot lock ref '(.+?)'") + // Prepare prepares the reference transaction by locking all references and determining their // current values. The updates are not yet committed and will be rolled back in case there is no // call to `Commit()`. This call is optional. func (u *Updater) Prepare() error { - return u.setState("prepare") + if err := u.setState("prepare"); err != nil { + matches := refLockedRegex.FindSubmatch([]byte(err.Error())) + if len(matches) > 1 { + return &ErrAlreadyLocked{Ref: string(matches[1])} + } + + return err + } + + return nil } // Commit applies the commands specified in other calls to the Updater diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref_test.go new file mode 100644 index 0000000000..50c2d7eb1f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref/updateref_test.go @@ -0,0 +1,309 @@ +package updateref + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func setupUpdater(t *testing.T, ctx context.Context) (config.Cfg, *localrepo.Repo, string, *Updater) { + t.Helper() + + cfg := testcfg.Build(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto, git.WithSkipHooks()) + + updater, err := New(ctx, repo) + require.NoError(t, err) + + return cfg, repo, repoPath, updater +} + +func TestUpdater_create(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, _, repoPath, updater := setupUpdater(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + require.NoError(t, updater.Create("refs/heads/_create", commitID)) + require.NoError(t, updater.Commit()) + + // Verify that the reference was created as expected and that it points to the correct + // commit. + require.Equal(t, gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/_create"), commitID) +} + +func TestUpdater_update(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, repo, repoPath, _ := setupUpdater(t, ctx) + + oldCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + newCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(oldCommitID)) + otherCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("other")) + + // Check that we can force-update the reference when we don't give an old object ID. + updater, err := New(ctx, repo) + require.NoError(t, err) + require.NoError(t, updater.Update("refs/heads/main", newCommitID, "")) + require.NoError(t, updater.Commit()) + require.Equal(t, gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/main"), newCommitID) + + // Check that we can update with safety guards when giving an old commit ID. + updater, err = New(ctx, repo) + require.NoError(t, err) + require.NoError(t, updater.Update("refs/heads/main", oldCommitID, newCommitID)) + require.NoError(t, updater.Commit()) + require.Equal(t, gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/main"), oldCommitID) + + // And finally assert that we fail to update the reference in case we're trying to update + // when the old commit ID doesn't match. + updater, err = New(ctx, repo) + require.NoError(t, err) + require.NoError(t, updater.Update("refs/heads/main", newCommitID, otherCommitID)) + err = updater.Commit() + require.Error(t, err) + require.Contains(t, err.Error(), fmt.Sprintf("fatal: commit: cannot lock ref 'refs/heads/main': is at %s but expected %s", oldCommitID, otherCommitID)) + + require.Equal(t, gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/main"), oldCommitID) +} + +func TestUpdater_delete(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, repo, repoPath, updater := setupUpdater(t, ctx) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + require.NoError(t, updater.Delete("refs/heads/main")) + require.NoError(t, updater.Commit()) + + // Check that the reference was removed. + _, err := repo.ReadCommit(ctx, "refs/heads/main") + require.Equal(t, localrepo.ErrObjectNotFound, err) +} + +func TestUpdater_prepareLocksTransaction(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, _, repoPath, updater := setupUpdater(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + require.NoError(t, updater.Update("refs/heads/feature", commitID, "")) + require.NoError(t, updater.Prepare()) + require.NoError(t, updater.Update("refs/heads/feature", commitID, "")) + + err := updater.Commit() + require.Error(t, err, "cannot update after prepare") + require.Contains(t, err.Error(), "fatal: prepared transactions can only be closed") +} + +func TestUpdater_concurrentLocking(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg := testcfg.Build(t) + + if !gittest.GitSupportsStatusFlushing(t, ctx, cfg) { + t.Skip("git does not support flushing yet, which is known to be flaky") + } + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto, git.WithSkipHooks()) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + // Create the first updater that prepares the reference transaction so that the reference + // we're about to update is locked. + firstUpdater, err := New(ctx, repo) + require.NoError(t, err) + require.NoError(t, firstUpdater.Update("refs/heads/master", commitID, "")) + require.NoError(t, firstUpdater.Prepare()) + + // Now we create a second updater that tries to update the same reference. + secondUpdater, err := New(ctx, repo) + require.NoError(t, err) + require.NoError(t, secondUpdater.Update("refs/heads/master", commitID, "")) + + // Preparing this second updater should fail though because we notice that the reference is + // locked. + err = secondUpdater.Prepare() + var errAlreadyLocked *ErrAlreadyLocked + require.ErrorAs(t, err, &errAlreadyLocked) + require.Equal(t, err, &ErrAlreadyLocked{ + Ref: "refs/heads/master", + }) + + // Whereas committing the first transaction should succeed. + require.NoError(t, firstUpdater.Commit()) +} + +func TestUpdater_bulkOperation(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, repo, repoPath, updater := setupUpdater(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + var expectedRefs []git.Reference + for i := 0; i < 1000; i++ { + reference := git.Reference{ + Name: git.ReferenceName(fmt.Sprintf("refs/head/test_%d", i)), + Target: commitID.String(), + } + + require.NoError(t, updater.Create(reference.Name, commitID)) + expectedRefs = append(expectedRefs, reference) + } + + require.NoError(t, updater.Commit()) + + refs, err := repo.GetReferences(ctx, "refs/") + require.NoError(t, err) + require.ElementsMatch(t, expectedRefs, refs) +} + +func TestUpdater_contextCancellation(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + childCtx, childCancel := context.WithCancel(ctx) + + cfg, repoProto, repoPath, _ := setupUpdater(t, ctx) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + updater, err := New(childCtx, repo) + require.NoError(t, err) + + require.NoError(t, updater.Create("refs/heads/main", commitID)) + + // Force the update-ref process to terminate early by cancelling the context. + childCancel() + + // We should see that committing the update fails now. + require.Error(t, updater.Commit()) + + // And the reference should not have been created. + _, err = repo.ReadCommit(ctx, "refs/heads/main") + require.Equal(t, localrepo.ErrObjectNotFound, err) +} + +func TestUpdater_cancel(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, repo, repoPath, updater := setupUpdater(t, ctx) + + if !gittest.GitSupportsStatusFlushing(t, ctx, cfg) { + t.Skip("git does not support flushing yet, which is known to be flaky") + } + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + // Queue the branch for deletion and lock it. + require.NoError(t, updater.Delete(git.ReferenceName("refs/heads/main"))) + require.NoError(t, updater.Prepare()) + + // Try to delete the same reference via a concurrent updater. This should not be allowed + // because the reference is locked already. + concurrentUpdater, err := New(ctx, repo) + require.NoError(t, err) + require.NoError(t, concurrentUpdater.Delete(git.ReferenceName("refs/heads/main"))) + err = concurrentUpdater.Commit() + require.Error(t, err) + require.Contains(t, err.Error(), "fatal: commit: cannot lock ref 'refs/heads/main'") + + // We now cancel the initial updater. Afterwards, it should be possible again to update the + // ref because locks should have been released. + require.NoError(t, updater.Cancel()) + + concurrentUpdater, err = New(ctx, repo) + require.NoError(t, err) + require.NoError(t, concurrentUpdater.Delete(git.ReferenceName("refs/heads/main"))) + require.NoError(t, concurrentUpdater.Commit()) +} + +func TestUpdater_closingStdinAbortsChanges(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, repo, repoPath, updater := setupUpdater(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + + require.NoError(t, updater.Create("refs/heads/main", commitID)) + + // Note that we call `Wait()` on the command, not on the updater. This + // circumvents our usual semantics of sending "commit" and thus + // emulates that the command somehow terminates correctly without us + // terminating it intentionally. Previous to our use of the "start" + // verb, this would've caused the reference to be created... + require.NoError(t, updater.cmd.Wait()) + + // ... but as we now use explicit transactional behaviour, this is no + // longer the case. + _, err := repo.ReadCommit(ctx, "refs/heads/main") + require.Equal(t, localrepo.ErrObjectNotFound, err, "expected 'not found' error got %v", err) +} + +func TestUpdater_capturesStderr(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg, _, _, updater := setupUpdater(t, ctx) + + newValue := git.ObjectID(strings.Repeat("1", gittest.DefaultObjectHash.EncodedLen())) + oldValue := gittest.DefaultObjectHash.ZeroOID + + require.NoError(t, updater.Update("refs/heads/main", newValue, oldValue)) + + var expectedErr string + if gittest.GitSupportsStatusFlushing(t, ctx, cfg) { + expectedErr = fmt.Sprintf("state update to \"commit\" failed: EOF, stderr: \"fatal: commit: cannot update ref '%[1]s': "+ + "trying to write ref '%[1]s' with nonexistent object %[2]s\\n\"", "refs/heads/main", newValue) + } else { + expectedErr = fmt.Sprintf("git update-ref: exit status 128, stderr: "+ + "\"fatal: commit: cannot update ref '%[1]s': "+ + "trying to write ref '%[1]s' with nonexistent object %[2]s\\n\"", "refs/heads/main", newValue) + } + + err := updater.Commit() + require.NotNil(t, err) + require.Equal(t, err.Error(), expectedErr) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version.go index 981dce5e17..881f4adc0d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" ) // minimumVersion is the minimum required Git version. If updating this version, be sure to @@ -84,6 +84,12 @@ func (v Version) FlushesUpdaterefStatus() bool { }) } +// HasGranularFsyncConfig determines whether the given Git version supports the new granular fsync +// configuration via `core.fsync`. This new config has been introduced with Git v2.36.0. +func (v Version) HasGranularFsyncConfig() bool { + return !v.LessThan(Version{major: 2, minor: 36, rc: true}) +} + // LessThan determines whether the version is older than another version. func (v Version) LessThan(other Version) bool { switch { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version_test.go index 55bbc0ff3e..49bc56af76 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git/version_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git/version_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git import ( @@ -147,3 +149,27 @@ func TestVersion_FlushesUpdaterefStatus(t *testing.T) { }) } } + +func TestVersion_HasGranularFsyncConfig(t *testing.T) { + for _, tc := range []struct { + version string + expect bool + }{ + {"2.35.0", false}, + {"2.35.0-rc0", false}, + {"2.35.1", false}, + {"2.35.1.gl3", false}, + {"2.36.0-rc1", true}, + {"2.36.0", true}, + {"2.36.0.gl1", true}, + {"2.36.1", true}, + {"2.37.1", true}, + {"3.0.0", true}, + } { + t.Run(tc.version, func(t *testing.T) { + version, err := parseVersion(tc.version) + require.NoError(t, err) + require.Equal(t, tc.expect, version.HasGranularFsyncConfig()) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply.go index d14062debe..5c2b70da20 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply.go @@ -6,8 +6,8 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // ErrMergeConflict is returned when there is a merge conflict. @@ -104,8 +104,13 @@ func (b *Executor) Apply(ctx context.Context, repo repository.GitRepo, params Ap execEnv := b.gitCmdFactory.GetExecutionEnvironment(ctx) + args := []string{"-git-binary-path", execEnv.BinaryPath} + if b.signingKey != "" { + args = append(args, "-signing-key", b.signingKey) + } + var result Result - output, err := b.run(ctx, repo, reader, "apply", "-git-binary-path", execEnv.BinaryPath) + output, err := b.run(ctx, repo, reader, "apply", args...) if err != nil { return "", fmt.Errorf("run: %w", err) } @@ -118,7 +123,7 @@ func (b *Executor) Apply(ctx context.Context, repo repository.GitRepo, params Ap return "", result.Err } - commitID, err := git.NewObjectIDFromHex(result.CommitID) + commitID, err := git.ObjectHashSHA1.FromHex(result.CommitID) if err != nil { return "", fmt.Errorf("could not parse commit ID: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply_test.go index 6c9a05c281..af99a58e9e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/apply_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/apply_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git2go import ( @@ -7,23 +9,25 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestExecutor_Apply(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) testcfg.BuildGitalyGit2Go(t, cfg) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) executor := NewExecutor(cfg, gittest.NewCommandFactory(t, cfg), config.NewLocator(cfg)) - ctx := testhelper.Context(t) oidBase, err := repo.WriteBlob(ctx, "file", strings.NewReader("base")) require.NoError(t, err) @@ -37,7 +41,7 @@ func TestExecutor_Apply(t *testing.T) { author := NewSignature("Test Author", "test.author@example.com", time.Now()) committer := NewSignature("Test Committer", "test.committer@example.com", time.Now()) - parentCommitSHA, err := executor.Commit(ctx, repo, CommitParams{ + parentCommitSHA, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -46,7 +50,7 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - noCommonAncestor, err := executor.Commit(ctx, repo, CommitParams{ + noCommonAncestor, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -55,7 +59,7 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - updateToA, err := executor.Commit(ctx, repo, CommitParams{ + updateToA, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -65,7 +69,7 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - updateToB, err := executor.Commit(ctx, repo, CommitParams{ + updateToB, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -75,7 +79,7 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - updateFromAToB, err := executor.Commit(ctx, repo, CommitParams{ + updateFromAToB, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -85,7 +89,7 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - otherFile, err := executor.Commit(ctx, repo, CommitParams{ + otherFile, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -94,9 +98,9 @@ func TestExecutor_Apply(t *testing.T) { }) require.NoError(t, err) - diffBetween := func(t testing.TB, fromCommit, toCommit git.ObjectID) []byte { - t.Helper() - return gittest.Exec(t, cfg, "-C", repoPath, "format-patch", "--stdout", fromCommit.String()+".."+toCommit.String()) + diffBetween := func(tb testing.TB, fromCommit, toCommit git.ObjectID) []byte { + tb.Helper() + return gittest.Exec(tb, cfg, "-C", repoPath, "format-patch", "--stdout", fromCommit.String()+".."+toCommit.String()) } for _, tc := range []struct { @@ -210,7 +214,7 @@ func TestExecutor_Apply(t *testing.T) { Author: author, Committer: committer, Message: tc.patches[len(tc.patches)-1].Message, - }, getCommit(t, ctx, repo, commitID)) + }, getCommit(t, ctx, repo, commitID, false)) gittest.RequireTree(t, cfg, repoPath, commitID.String(), tc.tree) }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/cherry_pick.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/cherry_pick.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/cherry_pick.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/cherry_pick.go index c190ab357b..7e954f50ed 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/cherry_pick.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/cherry_pick.go @@ -4,13 +4,13 @@ import ( "context" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) -// CherryPickCommand contains parameters to perform a cherry pick. +// CherryPickCommand contains parameters to perform a cherry-pick. type CherryPickCommand struct { - // Repository is the path where to execute the cherry pick. + // Repository is the path where to execute the cherry-pick. Repository string // CommitterName is the committer name for the resulting commit. CommitterName string @@ -26,9 +26,13 @@ type CherryPickCommand struct { Commit string // Mainline is the parent to be considered the mainline Mainline uint + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } -// CherryPick performs a cherry pick via gitaly-git2go. +// CherryPick performs a cherry-pick via gitaly-git2go. func (b *Executor) CherryPick(ctx context.Context, repo repository.GitRepo, m CherryPickCommand) (git.ObjectID, error) { + m.SigningKey = b.signingKey + return b.runWithGob(ctx, repo, "cherry-pick", m) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit.go index b8aeda71c4..7197e5a37b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit.go @@ -1,13 +1,11 @@ package git2go import ( - "bytes" "context" - "encoding/gob" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // IndexError is an error that was produced by performing an invalid operation on the index. @@ -42,8 +40,8 @@ func (err DirectoryExistsError) Error() string { return fmt.Sprintf("directory exists: %q", string(err)) } -// CommitParams contains the information and the steps to build a commit. -type CommitParams struct { +// CommitCommand contains the information and the steps to build a commit. +type CommitCommand struct { // Repository is the path of the repository to operate on. Repository string // Author is the author of the commit. @@ -56,34 +54,14 @@ type CommitParams struct { Parent string // Actions are the steps to build the commit. Actions []Action + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } // Commit builds a commit from the actions, writes it to the object database and // returns its object id. -func (b *Executor) Commit(ctx context.Context, repo repository.GitRepo, params CommitParams) (git.ObjectID, error) { - input := &bytes.Buffer{} - if err := gob.NewEncoder(input).Encode(params); err != nil { - return "", err - } +func (b *Executor) Commit(ctx context.Context, repo repository.GitRepo, c CommitCommand) (git.ObjectID, error) { + c.SigningKey = b.signingKey - output, err := b.run(ctx, repo, input, "commit") - if err != nil { - return "", err - } - - var result Result - if err := gob.NewDecoder(output).Decode(&result); err != nil { - return "", err - } - - if result.Err != nil { - return "", result.Err - } - - commitID, err := git.NewObjectIDFromHex(result.CommitID) - if err != nil { - return "", fmt.Errorf("could not parse commit ID: %w", err) - } - - return commitID, nil + return b.runWithGob(ctx, repo, "commit", c) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit_actions.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit_actions.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit_actions.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit_actions.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit_test.go index 00e942220b..48deee8153 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/commit_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/commit_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git2go import ( @@ -5,18 +7,21 @@ import ( "context" "errors" "fmt" + "os" "strconv" "strings" "testing" "time" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestMain(m *testing.M) { @@ -46,7 +51,9 @@ func TestExecutor_Commit(t *testing.T) { cfg := testcfg.Build(t) testcfg.BuildGitalyGit2Go(t, cfg) - repoProto, repoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -59,8 +66,9 @@ func TestExecutor_Commit(t *testing.T) { executor := NewExecutor(cfg, gittest.NewCommandFactory(t, cfg), config.NewLocator(cfg)) for _, tc := range []struct { - desc string - steps []step + desc string + steps []step + signAndVerify bool }{ { desc: "create directory", @@ -451,14 +459,34 @@ func TestExecutor_Commit(t *testing.T) { }, }, }, + { + desc: "update created file, sign commit and verify signature", + steps: []step{ + { + actions: []Action{ + CreateFile{Path: "file", OID: originalFile.String()}, + UpdateFile{Path: "file", OID: updatedFile.String()}, + }, + treeEntries: []gittest.TreeEntry{ + {Mode: DefaultMode, Path: "file", Content: "updated"}, + }, + }, + }, + signAndVerify: true, + }, } { t.Run(tc.desc, func(t *testing.T) { author := NewSignature("Author Name", "author.email@example.com", time.Now()) committer := NewSignature("Committer Name", "committer.email@example.com", time.Now()) + + if tc.signAndVerify { + executor.signingKey = testhelper.SigningKeyPath + } + var parentCommit git.ObjectID for i, step := range tc.steps { message := fmt.Sprintf("commit %d", i+1) - commitID, err := executor.Commit(ctx, repo, CommitParams{ + commitID, err := executor.Commit(ctx, repo, CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -479,7 +507,7 @@ func TestExecutor_Commit(t *testing.T) { Author: author, Committer: committer, Message: message, - }, getCommit(t, ctx, repo, commitID)) + }, getCommit(t, ctx, repo, commitID, tc.signAndVerify)) gittest.RequireTree(t, cfg, repoPath, commitID.String(), step.treeEntries) parentCommit = commitID @@ -488,56 +516,91 @@ func TestExecutor_Commit(t *testing.T) { } } -func getCommit(t testing.TB, ctx context.Context, repo *localrepo.Repo, oid git.ObjectID) commit { - t.Helper() +func getCommit(tb testing.TB, ctx context.Context, repo *localrepo.Repo, oid git.ObjectID, verifySignature bool) commit { + tb.Helper() data, err := repo.ReadObject(ctx, oid) - require.NoError(t, err) + require.NoError(tb, err) + + var ( + gpgsig, dataWithoutGpgSig string + gpgsigStarted bool + ) var commit commit lines := strings.Split(string(data), "\n") for i, line := range lines { if line == "" { commit.Message = strings.Join(lines[i+1:], "\n") + dataWithoutGpgSig += "\n" + commit.Message break } + if gpgsigStarted && strings.HasPrefix(line, " ") { + gpgsig += strings.TrimSpace(line) + "\n" + continue + } + split := strings.SplitN(line, " ", 2) - require.Len(t, split, 2, "invalid commit: %q", data) + require.Len(tb, split, 2, "invalid commit: %q", data) field, value := split[0], split[1] + + if field != "gpgsig" { + dataWithoutGpgSig += line + "\n" + } + switch field { case "parent": - require.Empty(t, commit.Parent, "multi parent parsing not implemented") + require.Empty(tb, commit.Parent, "multi parent parsing not implemented") commit.Parent = git.ObjectID(value) case "author": - require.Empty(t, commit.Author, "commit contained multiple authors") - commit.Author = unmarshalSignature(t, value) + require.Empty(tb, commit.Author, "commit contained multiple authors") + commit.Author = unmarshalSignature(tb, value) case "committer": - require.Empty(t, commit.Committer, "commit contained multiple committers") - commit.Committer = unmarshalSignature(t, value) + require.Empty(tb, commit.Committer, "commit contained multiple committers") + commit.Committer = unmarshalSignature(tb, value) + case "gpgsig": + gpgsig = value + "\n" + gpgsigStarted = true default: } } + if gpgsig != "" || verifySignature { + file, err := os.Open("testdata/publicKey.gpg") + require.NoError(tb, err) + + keyring, err := openpgp.ReadKeyRing(file) + require.NoError(tb, err) + + _, err = openpgp.CheckArmoredDetachedSignature( + keyring, + strings.NewReader(dataWithoutGpgSig), + strings.NewReader(gpgsig), + &packet.Config{}, + ) + require.NoError(tb, err) + } + return commit } -func unmarshalSignature(t testing.TB, data string) Signature { - t.Helper() +func unmarshalSignature(tb testing.TB, data string) Signature { + tb.Helper() // Format: NAME DATE_UNIX DATE_TIMEZONE split1 := strings.Split(data, " <") - require.Len(t, split1, 2, "invalid signature: %q", data) + require.Len(tb, split1, 2, "invalid signature: %q", data) split2 := strings.Split(split1[1], "> ") - require.Len(t, split2, 2, "invalid signature: %q", data) + require.Len(tb, split2, 2, "invalid signature: %q", data) split3 := strings.Split(split2[1], " ") - require.Len(t, split3, 2, "invalid signature: %q", data) + require.Len(tb, split3, 2, "invalid signature: %q", data) timestamp, err := strconv.ParseInt(split3[0], 10, 64) - require.NoError(t, err) + require.NoError(tb, err) return Signature{ Name: split1[0], diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/conflicts.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/conflicts.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/conflicts.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/conflicts.go index 650057c59b..8dd6c9986f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/conflicts.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/conflicts.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/executor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/executor.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/executor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/executor.go index 73dc095e88..b97a9f3b0a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/executor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/executor.go @@ -7,17 +7,16 @@ import ( "errors" "fmt" "io" - "os/exec" - "path/filepath" + "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/alternates" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - glog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/alternates" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + glog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/labkit/correlation" ) @@ -25,13 +24,14 @@ var ( // ErrInvalidArgument is returned in case the merge arguments are invalid. ErrInvalidArgument = errors.New("invalid parameters") - // BinaryName is a binary name with version suffix . - BinaryName = "gitaly-git2go-" + version.GetModuleVersion() + // BinaryName is the name of the gitaly-git2go binary. + BinaryName = "gitaly-git2go" ) // Executor executes gitaly-git2go. type Executor struct { binaryPath string + signingKey string gitCmdFactory git.CommandFactory locator storage.Locator logFormat, logLevel string @@ -41,7 +41,8 @@ type Executor struct { // configuration. func NewExecutor(cfg config.Cfg, gitCmdFactory git.CommandFactory, locator storage.Locator) *Executor { return &Executor{ - binaryPath: filepath.Join(cfg.BinDir, BinaryName), + binaryPath: cfg.BinaryPath(BinaryName), + signingKey: cfg.Git.SigningKey, gitCmdFactory: gitCmdFactory, locator: locator, logFormat: cfg.Logging.Format, @@ -55,7 +56,19 @@ func (b *Executor) run(ctx context.Context, repo repository.GitRepo, stdin io.Re return nil, fmt.Errorf("gitaly-git2go: %w", err) } + var enabledFeatureFlags, disabledFeatureFlags []string + + for flag, value := range featureflag.FromContext(ctx) { + switch value { + case true: + enabledFeatureFlags = append(enabledFeatureFlags, flag.MetadataKey()) + case false: + disabledFeatureFlags = append(disabledFeatureFlags, flag.MetadataKey()) + } + } + env := alternates.Env(repoPath, repo.GetGitObjectDirectory(), repo.GetGitAlternateObjectDirectories()) + env = append(env, b.gitCmdFactory.GetExecutionEnvironment(ctx).EnvironmentVariables...) // Pass the log output directly to gitaly-git2go. No need to reinterpret // these logs as long as the destination is an append-only file. See @@ -66,17 +79,23 @@ func (b *Executor) run(ctx context.Context, repo repository.GitRepo, stdin io.Re "-log-format", b.logFormat, "-log-level", b.logLevel, "-correlation-id", correlation.ExtractFromContext(ctx), + "-enabled-feature-flags", strings.Join(enabledFeatureFlags, ","), + "-disabled-feature-flags", strings.Join(disabledFeatureFlags, ","), subcmd, }, args...) var stdout bytes.Buffer - cmd, err := command.New(ctx, exec.Command(b.binaryPath, args...), stdin, &stdout, log, env...) + cmd, err := command.New(ctx, append([]string{b.binaryPath}, args...), + command.WithStdin(stdin), + command.WithStdout(&stdout), + command.WithStderr(log), + command.WithEnvironment(env), + command.WithCommandName("gitaly-git2go", subcmd), + ) if err != nil { return nil, err } - cmd.SetMetricsSubCmd(subcmd) - if err := cmd.Wait(); err != nil { return nil, err } @@ -106,7 +125,7 @@ func (b *Executor) runWithGob(ctx context.Context, repo repository.GitRepo, cmd return "", fmt.Errorf("%s: %w", cmd, result.Err) } - commitID, err := git.NewObjectIDFromHex(result.CommitID) + commitID, err := git.ObjectHashSHA1.FromHex(result.CommitID) if err != nil { return "", fmt.Errorf("could not parse commit ID: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags.go new file mode 100644 index 0000000000..bfde6867b5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags.go @@ -0,0 +1,22 @@ +package git2go + +// FeatureFlag is a feature flag state as seen by the `gitaly-git2go featureflag` test subcommand. +type FeatureFlag struct { + // MetadataKey is the metadata key of the feature flag. + MetadataKey string + // Name is the name of the feature flag. + Name string + // Value is the value of the feature flag. + Value bool +} + +// FeatureFlags is a struct only used by tests to confirm that feature flags are +// being properly propagated from the git2go Executor to the gitaly-git2go +// binary +type FeatureFlags struct { + // Flags is the set of feature flags observed by the command. + Flags []FeatureFlag + // Err is set if an error occurred. Err must exist on all gob serialized + // results so that any error can be returned. + Err error +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags_test.go new file mode 100644 index 0000000000..b4e9117efc --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/featureflags_test.go @@ -0,0 +1,74 @@ +//go:build !gitaly_test_sha256 + +package git2go + +import ( + "context" + "encoding/gob" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func (b *Executor) FeatureFlags(ctx context.Context, repo repository.GitRepo) ([]FeatureFlag, error) { + output, err := b.run(ctx, repo, nil, "feature-flags") + if err != nil { + return nil, err + } + + var result FeatureFlags + if err := gob.NewDecoder(output).Decode(&result); err != nil { + return nil, err + } + + if result.Err != nil { + return nil, result.Err + } + + return result.Flags, err +} + +var ( + featureA = featureflag.NewFeatureFlag("feature_a", "", "", false) + featureB = featureflag.NewFeatureFlag("feature_b", "", "", true) +) + +func TestExecutor_explicitFeatureFlags(t *testing.T) { + testhelper.NewFeatureSets(featureA, featureB).Run(t, testExecutorFeatureFlags) +} + +func testExecutorFeatureFlags(t *testing.T, ctx context.Context) { + cfg := testcfg.Build(t) + testcfg.BuildGitalyGit2Go(t, cfg) + + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + executor := NewExecutor(cfg, gittest.NewCommandFactory(t, cfg), config.NewLocator(cfg)) + + flags, err := executor.FeatureFlags(ctx, repo) + require.NoError(t, err) + + require.Subset(t, flags, []FeatureFlag{ + { + Name: "feature_a", + MetadataKey: "gitaly-feature-feature-a", + Value: featureA.IsEnabled(ctx), + }, + { + Name: "feature_b", + MetadataKey: "gitaly-feature-feature-b", + Value: featureB.IsEnabled(ctx), + }, + }, flags) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/merge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/merge.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/merge.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/merge.go index b0f2e5503f..8669a18eb4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/merge.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/merge.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) const ( @@ -47,6 +47,8 @@ type MergeCommand struct { // If set to `true`, then the resulting commit will have `Ours` as its only parent. // Otherwise, a merge commit will be created with `Ours` and `Theirs` as its parents. Squash bool + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } // MergeResult contains results from a merge. @@ -60,6 +62,7 @@ func (b *Executor) Merge(ctx context.Context, repo repository.GitRepo, m MergeCo if err := m.verify(); err != nil { return MergeResult{}, fmt.Errorf("merge: %w: %s", ErrInvalidArgument, err.Error()) } + m.SigningKey = b.signingKey commitID, err := b.runWithGob(ctx, repo, "merge", m) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/rebase.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/rebase.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/rebase.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/rebase.go index 96991ce5c2..8b041dadb7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/rebase.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/rebase.go @@ -3,8 +3,8 @@ package git2go import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // RebaseCommand contains parameters to rebase a branch. @@ -30,9 +30,13 @@ type RebaseCommand struct { // and which are thus empty to be skipped. If unset, empty commits will cause the rebase to // fail. SkipEmptyCommits bool + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } // Rebase performs the rebase via gitaly-git2go func (b *Executor) Rebase(ctx context.Context, repo repository.GitRepo, r RebaseCommand) (git.ObjectID, error) { + r.SigningKey = b.signingKey + return b.runWithGob(ctx, repo, "rebase", r) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/resolve_conflicts.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/resolve_conflicts.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/resolve_conflicts.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/resolve_conflicts.go index ae25455310..cd1ad0d031 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/resolve_conflicts.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/resolve_conflicts.go @@ -6,8 +6,8 @@ import ( "encoding/gob" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // ResolveCommand contains arguments to perform a merge commit and resolve any @@ -28,6 +28,8 @@ type ResolveResult struct { // Resolve will attempt merging and resolving conflicts for the provided request func (b *Executor) Resolve(ctx context.Context, repo repository.GitRepo, r ResolveCommand) (ResolveResult, error) { + r.SigningKey = b.signingKey + if err := r.verify(); err != nil { return ResolveResult{}, fmt.Errorf("resolve: %w: %s", ErrInvalidArgument, err.Error()) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/revert.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/revert.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/revert.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/revert.go index 756ec64f53..4c42e706d6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/revert.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/revert.go @@ -4,8 +4,8 @@ import ( "context" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // RevertCommand contains parameters required to execute a revert via gitaly-git2go. @@ -26,9 +26,13 @@ type RevertCommand struct { Revert string // Mainline is the parent to be considered the mainline Mainline uint + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } // Revert reverts a commit via gitaly-git2go. func (b *Executor) Revert(ctx context.Context, repo repository.GitRepo, r RevertCommand) (git.ObjectID, error) { + r.SigningKey = b.signingKey + return b.runWithGob(ctx, repo, "revert", r) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/serialization.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/serialization.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/serialization.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/serialization.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/serialization_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/serialization_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/serialization_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/serialization_test.go index e18a10961c..b9a1c3670d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/serialization_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/serialization_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package git2go import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/signature.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/signature.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/signature.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/signature.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/submodule.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/submodule.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/submodule.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/submodule.go index 145ef503fe..ce4aad37f9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/git2go/submodule.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/submodule.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // Error strings present in the legacy Ruby implementation @@ -37,6 +37,9 @@ type SubmoduleCommand struct { Submodule string // Branch where to commit submodule update Branch string + + // SigningKey is a path to the key to sign commit using OpenPGP + SigningKey string } // SubmoduleResult contains results from a committing a submodule update @@ -47,6 +50,8 @@ type SubmoduleResult struct { // Submodule attempts to commit the request submodule change func (b *Executor) Submodule(ctx context.Context, repo repository.GitRepo, s SubmoduleCommand) (SubmoduleResult, error) { + s.SigningKey = b.signingKey + if err := s.verify(); err != nil { return SubmoduleResult{}, fmt.Errorf("submodule: %w", err) } @@ -58,7 +63,7 @@ func (b *Executor) Submodule(ctx context.Context, repo repository.GitRepo, s Sub } // Ideally we would use `b.runWithGob` here to avoid the gob encoding - // boilerplate but it is not possible here because `runWithGob` adds error + // boilerplate, but it is not possible here because `runWithGob` adds error // prefixes and the `LegacyErrPrefix*` errors must match exactly. stdout, err := b.run(ctx, repo, input, cmd) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/publicKey.gpg b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/publicKey.gpg new file mode 100644 index 0000000000..98d02a71e9 Binary files /dev/null and b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/publicKey.gpg differ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/signingKey.gpg b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/signingKey.gpg new file mode 100644 index 0000000000..841fbc76ab Binary files /dev/null and b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/git2go/testdata/signingKey.gpg differ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/match_walker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/match_walker.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/match_walker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/match_walker.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/tar_builder.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/tar_builder.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/tar_builder.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/tar_builder.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/tar_entries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/tar_entries.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive/tar_entries.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive/tar_entries.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/address_parser.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/address_parser.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/address_parser.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/address_parser.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/address_parser_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/address_parser_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/address_parser_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/address_parser_test.go index f5dc2f31b0..3069d7e963 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/address_parser_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/address_parser_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package client import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial.go index f83a9941f8..b0b5585434 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial.go @@ -8,7 +8,7 @@ import ( "net/url" "time" - gitalyx509 "gitlab.com/gitlab-org/gitaly/v14/internal/x509" + gitalyx509 "gitlab.com/gitlab-org/gitaly/v15/internal/x509" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" "google.golang.org/grpc" @@ -57,6 +57,8 @@ type Handshaker interface { // If handshaker is provided, it's passed the transport credentials which would be otherwise set. The transport credentials // returned by handshaker are then set instead. func Dial(ctx context.Context, rawAddress string, connOpts []grpc.DialOption, handshaker Handshaker) (*grpc.ClientConn, error) { + connOpts = cloneOpts(connOpts) // copy to avoid potentially mutating the backing array of the passed slice + var canonicalAddress string var err error var transportCredentials credentials.TransportCredentials @@ -115,7 +117,7 @@ func Dial(ctx context.Context, rawAddress string, connOpts []grpc.DialOption, ha } if transportCredentials == nil { - connOpts = append(connOpts, grpc.WithInsecure()) + connOpts = append(connOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } else { connOpts = append(connOpts, grpc.WithTransportCredentials(transportCredentials)) } @@ -127,11 +129,6 @@ func Dial(ctx context.Context, rawAddress string, connOpts []grpc.DialOption, ha Time: 20 * time.Second, PermitWithoutStream: true, }), - UnaryInterceptor(), - grpc.WithChainStreamInterceptor( - grpctracing.StreamClientTracingInterceptor(), - grpccorrelation.StreamClientCorrelationInterceptor(), - ), ) conn, err := grpc.DialContext(ctx, canonicalAddress, connOpts...) @@ -142,6 +139,14 @@ func Dial(ctx context.Context, rawAddress string, connOpts []grpc.DialOption, ha return conn, nil } +// StreamInterceptor returns the stream interceptors that should be configured for a client. +func StreamInterceptor() grpc.DialOption { + return grpc.WithChainStreamInterceptor( + grpctracing.StreamClientTracingInterceptor(), + grpccorrelation.StreamClientCorrelationInterceptor(), + ) +} + // UnaryInterceptor returns the unary interceptors that should be configured for a client. func UnaryInterceptor() grpc.DialOption { return grpc.WithChainUnaryInterceptor( @@ -149,3 +154,9 @@ func UnaryInterceptor() grpc.DialOption { grpccorrelation.UnaryClientCorrelationInterceptor(), ) } + +func cloneOpts(opts []grpc.DialOption) []grpc.DialOption { + clone := make([]grpc.DialOption, len(opts)) + copy(clone, opts) + return clone +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial_test.go index 2e30413f98..9c9f72f171 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client/dial_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client/dial_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package client import ( @@ -6,10 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -50,7 +52,8 @@ func TestDial(t *testing.T) { require.NoError(t, err) defer func() { require.NoError(t, nonMuxedConn.Close()) }() - require.Equal(t, errNonMuxed, nonMuxedConn.Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{})) + dialErr := nonMuxedConn.Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{}) + testhelper.RequireGrpcError(t, errNonMuxed, dialErr) }) t.Run("muxed conn", func(t *testing.T) { @@ -59,6 +62,7 @@ func TestDial(t *testing.T) { require.NoError(t, err) defer func() { require.NoError(t, nonMuxedConn.Close()) }() - require.Equal(t, errMuxed, nonMuxedConn.Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{})) + dialErr := nonMuxedConn.Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{}) + testhelper.RequireGrpcError(t, errMuxed, dialErr) }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth/auth.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth/auth.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth/auth.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth/auth.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups.go new file mode 100644 index 0000000000..8d90945521 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups.go @@ -0,0 +1,68 @@ +package cgroups + +// Config is a struct for cgroups config +type Config struct { + // Mountpoint is where the cgroup filesystem is mounted, usually under /sys/fs/cgroup/ + Mountpoint string `toml:"mountpoint"` + // HierarchyRoot is the parent cgroup under which Gitaly creates of cgroups. + // A system administrator is expected to create such cgroup/directory under /memory + // and/or /cpu depending on which resource is enabled. HierarchyRoot is expected to + // be owned by the user and group Gitaly runs as. + HierarchyRoot string `toml:"hierarchy_root"` + Repositories Repositories `toml:"repositories"` + // MemoryBytes is the memory limit for the parent cgroup. 0 implies no memory limit. + MemoryBytes int64 `toml:"memory_bytes"` + // CPUShares are the shares of CPU the parent cgroup is allowed to utilize. A value of 1024 + // is full utilization of the CPU. 0 implies no CPU limit. + CPUShares uint64 `toml:"cpu_shares"` + MetricsEnabled bool `toml:"metrics_enabled"` + + // Deprecated: No longer supported after 15.0 + Count uint `toml:"count"` + CPU CPU `toml:"cpu"` + Memory Memory `toml:"memory"` +} + +// FallbackToOldVersion translates the old format of cgroups into the new +// format. +func (c *Config) FallbackToOldVersion() { + if c.Repositories.Count == 0 { + c.Repositories.Count = c.Count + + if c.Repositories.MemoryBytes == 0 && c.Memory.Enabled { + c.Repositories.MemoryBytes = c.Memory.Limit + } + + if c.Repositories.CPUShares == 0 && c.CPU.Enabled { + c.Repositories.CPUShares = c.CPU.Shares + } + } +} + +// Repositories configures cgroups to be created that are isolated by repository. +type Repositories struct { + // Count is the number of cgroups that will be created for repository-level isolation + // of git commands. + Count uint `toml:"count"` + // MemoryBytes is the memory limit for each cgroup. 0 implies no memory limit. + MemoryBytes int64 `toml:"memory_bytes"` + // CPUShares are the shares of CPU that each cgroup is allowed to utilize. A value of 1024 + // is full utilization of the CPU. 0 implies no CPU limit. + CPUShares uint64 `toml:"cpu_shares"` +} + +// Memory is a struct storing cgroups memory config +// Deprecated: Not in use after 15.0. +type Memory struct { + Enabled bool `toml:"enabled"` + // Limit is the memory limit in bytes. Could be -1 to indicate unlimited memory. + Limit int64 `toml:"limit"` +} + +// CPU is a struct storing cgroups CPU config +// Deprecated: Not in use after 15.0. +type CPU struct { + Enabled bool `toml:"enabled"` + // Shares is the number of CPU shares (relative weight (ratio) vs. other cgroups with CPU shares). + Shares uint64 `toml:"shares"` +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups_test.go new file mode 100644 index 0000000000..34b39dcc42 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups/cgroups_test.go @@ -0,0 +1,152 @@ +//go:build !gitaly_test_sha256 + +package cgroups + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFallbackToOldVersion(t *testing.T) { + testCases := []struct { + desc string + configBefore Config + configAfter Config + }{ + { + desc: "empty config", + configBefore: Config{}, + configAfter: Config{}, + }, + { + desc: "new format", + configBefore: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Repositories: Repositories{ + Count: 100, + MemoryBytes: 1024, + CPUShares: 16, + }, + }, + configAfter: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Repositories: Repositories{ + Count: 100, + MemoryBytes: 1024, + CPUShares: 16, + }, + }, + }, + { + desc: "old format", + configBefore: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: CPU{ + Enabled: true, + Shares: 16, + }, + }, + configAfter: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: CPU{ + Enabled: true, + Shares: 16, + }, + Repositories: Repositories{ + Count: 100, + MemoryBytes: 1024, + CPUShares: 16, + }, + }, + }, + { + desc: "old format, memory only", + configBefore: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: CPU{ + Enabled: false, + Shares: 16, + }, + }, + configAfter: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: CPU{ + Enabled: false, + Shares: 16, + }, + + Repositories: Repositories{ + Count: 100, + MemoryBytes: 1024, + }, + }, + }, + { + desc: "old format, cpu only", + configBefore: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: false, + Limit: 1024, + }, + CPU: CPU{ + Enabled: true, + Shares: 16, + }, + }, + configAfter: Config{ + Mountpoint: "some/mountpoint", + HierarchyRoot: "gitaly", + Count: 100, + Memory: Memory{ + Enabled: false, + Limit: 1024, + }, + CPU: CPU{ + Enabled: true, + Shares: 16, + }, + Repositories: Repositories{ + Count: 100, + CPUShares: 16, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + tc.configBefore.FallbackToOldVersion() + assert.Equal(t, tc.configAfter, tc.configBefore) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config.go index 49b6cc5092..f1aebe07d6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config.go @@ -9,16 +9,17 @@ import ( "path/filepath" "reflect" "strings" + "syscall" "time" - "github.com/pelletier/go-toml" + "github.com/pelletier/go-toml/v2" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - internallog "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + internallog "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) const ( @@ -31,10 +32,10 @@ const ( // DailyJob enables a daily task to be scheduled for specific storages type DailyJob struct { - Hour uint `toml:"start_hour"` - Minute uint `toml:"start_minute"` - Duration Duration `toml:"duration"` - Storages []string `toml:"storages"` + Hour uint `toml:"start_hour"` + Minute uint `toml:"start_minute"` + Duration duration.Duration `toml:"duration"` + Storages []string `toml:"storages"` // Disabled will completely disable a daily job, even in cases where a // default schedule is implied @@ -61,8 +62,7 @@ type Cfg struct { Hooks Hooks `toml:"hooks"` Concurrency []Concurrency `toml:"concurrency"` RateLimiting []RateLimiting `toml:"rate_limiting"` - GracefulRestartTimeout Duration `toml:"graceful_restart_timeout"` - InternalSocketDir string `toml:"internal_socket_dir"` + GracefulRestartTimeout duration.Duration `toml:"graceful_restart_timeout"` DailyMaintenance DailyJob `toml:"daily_maintenance"` Cgroups cgroups.Config `toml:"cgroups"` PackObjectsCache StreamCacheConfig `toml:"pack_objects_cache"` @@ -70,8 +70,8 @@ type Cfg struct { // TLS configuration type TLS struct { - CertPath string `toml:"certificate_path,omitempty"` - KeyPath string `toml:"key_path,omitempty"` + CertPath string `toml:"certificate_path,omitempty" json:"cert_path"` + KeyPath string `toml:"key_path,omitempty" json:"key_path"` } // GitlabShell contains the settings required for executing `gitlab-shell` @@ -92,14 +92,13 @@ type Hooks struct { CustomHooksDir string `toml:"custom_hooks_dir" json:"custom_hooks_dir"` } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type HTTPSettings struct { ReadTimeout int `toml:"read_timeout" json:"read_timeout"` User string `toml:"user" json:"user"` Password string `toml:"password" json:"password"` CAFile string `toml:"ca_file" json:"ca_file"` CAPath string `toml:"ca_path" json:"ca_path"` - SelfSigned bool `toml:"self_signed_cert" json:"self_signed_cert"` } // Git contains the settings for the Git executable @@ -108,6 +107,8 @@ type Git struct { BinPath string `toml:"bin_path"` CatfileCacheSize int `toml:"catfile_cache_size"` Config []GitConfig `toml:"config"` + IgnoreGitconfig bool `toml:"ignore_gitconfig"` + SigningKey string `toml:"signing_key"` } // GitConfig contains a key-value pair which is to be passed to git as configuration. @@ -147,7 +148,7 @@ type Concurrency struct { MaxQueueSize int `toml:"max_queue_size"` // MaxQueueWait is the maximum time a request can remain in the concurrency queue // waiting to be picked up by Gitaly - MaxQueueWait Duration `toml:"max_queue_wait"` + MaxQueueWait duration.Duration `toml:"max_queue_wait"` } // RateLimiting allows endpoints to be limited to a maximum request rate per @@ -161,20 +162,20 @@ type RateLimiting struct { RPC string `toml:"rpc"` // Interval sets the interval with which the token bucket will // be refilled to what is configured in Burst. - Interval time.Duration `toml:"interval"` + Interval duration.Duration `toml:"interval"` // Burst sets the capacity of the token bucket (see above). Burst int `toml:"burst"` } // StreamCacheConfig contains settings for a streamcache instance. type StreamCacheConfig struct { - Enabled bool `toml:"enabled"` // Default: false - Dir string `toml:"dir"` // Default: /+gitaly/PackObjectsCache - MaxAge Duration `toml:"max_age"` // Default: 5m + Enabled bool `toml:"enabled"` // Default: false + Dir string `toml:"dir"` // Default: /+gitaly/PackObjectsCache + MaxAge duration.Duration `toml:"max_age"` // Default: 5m } // Load initializes the Config variable from file and the environment. -// Environment variables take precedence over the file. +// Environment variables take precedence over the file. func Load(file io.Reader) (Cfg, error) { cfg := Cfg{ Prometheus: prometheus.DefaultConfig(), @@ -206,7 +207,6 @@ func (cfg *Cfg) Validate() error { cfg.ConfigureRuby, cfg.validateBinDir, cfg.validateRuntimeDir, - cfg.validateInternalSocketDir, cfg.validateMaintenance, cfg.validateCgroups, cfg.configurePackObjectsCache, @@ -221,7 +221,7 @@ func (cfg *Cfg) Validate() error { func (cfg *Cfg) setDefaults() error { if cfg.GracefulRestartTimeout.Duration() == 0 { - cfg.GracefulRestartTimeout = Duration(time.Minute) + cfg.GracefulRestartTimeout = duration.Duration(time.Minute) } if cfg.Gitlab.SecretFile == "" { @@ -232,63 +232,20 @@ func (cfg *Cfg) setDefaults() error { cfg.Hooks.CustomHooksDir = filepath.Join(cfg.GitlabShell.Dir, "hooks") } - if cfg.RuntimeDir == "" { - // If there is no runtime directory configured we just use a temporary runtime - // directory. This may not always be an ideal choice given that it's typically - // created at `/tmp`, which may get periodically pruned if `noatime` is set. - runtimeDir, err := os.MkdirTemp("", "gitaly-") - if err != nil { - return fmt.Errorf("creating temporary runtime directory: %w", err) - } - - cfg.RuntimeDir = runtimeDir - } else { - // Otherwise, we use the configured runtime directory. Note that we don't use the - // runtime directory directly, but instead create a subdirectory within it which is - // based on the process's PID. While we could use `MkdirTemp()` instead and don't - // bother with preexisting directories, the benefit of using the PID here is that we - // can determine whether the directory may still be in use by checking whether the - // PID exists. Furthermore, it allows easier debugging in case one wants to inspect - // the runtime directory of a running Gitaly node. - - runtimeDir := filepath.Join(cfg.RuntimeDir, fmt.Sprintf("gitaly-%d", os.Getpid())) - - if _, err := os.Stat(runtimeDir); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("statting runtime directory: %w", err) - } else if err != nil { - // If the directory exists already then it must be from an old invocation of - // Gitaly. Because we use the PID as path component we know that the old - // instance cannot exist anymore though, so it's safe to remove this - // directory now. - if err := os.RemoveAll(runtimeDir); err != nil { - return fmt.Errorf("removing old runtime directory: %w", err) - } - } - - if err := os.Mkdir(runtimeDir, 0o700); err != nil { - return fmt.Errorf("creating runtime directory: %w", err) - } - - cfg.RuntimeDir = runtimeDir - } - - if cfg.InternalSocketDir == "" { - // The socket path must be short-ish because listen(2) fails on long - // socket paths. We hope/expect that os.MkdirTemp creates a directory - // that is not too deep. We need a directory, not a tempfile, because we - // will later want to set its permissions to 0700 - socketDir := filepath.Join(cfg.RuntimeDir, "sock.d") - if err := os.Mkdir(socketDir, 0o700); err != nil { - return fmt.Errorf("create internal socket directory: %w", err) - } - - cfg.InternalSocketDir = socketDir - } - if reflect.DeepEqual(cfg.DailyMaintenance, DailyJob{}) { cfg.DailyMaintenance = defaultMaintenanceWindow(cfg.Storages) } + if cfg.Cgroups.Mountpoint == "" { + cfg.Cgroups.Mountpoint = "/sys/fs/cgroup" + } + + if cfg.Cgroups.HierarchyRoot == "" { + cfg.Cgroups.HierarchyRoot = "gitaly" + } + + cfg.Cgroups.FallbackToOldVersion() + return nil } @@ -324,6 +281,31 @@ func validateIsDirectory(path, name string) error { return nil } +// packedBinaries are the binaries that are packed in the main Gitaly binary. This should always match +// the actual list in /packed_binaries.go so the binaries are correctly located. +// +// Resolving the names automatically from the packed binaries is not possible at the moment due to how +// the packed binaries themselves depend on this config package. If this config package inspected the +// packed binaries, there would be a cyclic dependency. Anything that the packed binaries import must +// not depend on /packed_binaries.go. +var packedBinaries = map[string]struct{}{ + "gitaly-hooks": {}, + "gitaly-ssh": {}, + "gitaly-git2go": {}, + "gitaly-lfs-smudge": {}, +} + +// BinaryPath returns the path to a given binary. BinaryPath does not do any validation, it simply joins the binaryName +// with the correct base directory depending on whether the binary is a packed binary or not. +func (cfg *Cfg) BinaryPath(binaryName string) string { + baseDirectory := cfg.BinDir + if _, ok := packedBinaries[binaryName]; ok { + baseDirectory = cfg.RuntimeDir + } + + return filepath.Join(baseDirectory, binaryName) +} + func (cfg *Cfg) validateStorages() error { if len(cfg.Storages) == 0 { return fmt.Errorf("no storage configurations found. Are you using the right format? https://gitlab.com/gitlab-org/gitaly/issues/397") @@ -390,9 +372,14 @@ func (cfg *Cfg) Storage(storageName string) (Storage, bool) { return Storage{}, false } -// GitalyInternalSocketPath is the path to the internal gitaly socket -func (cfg *Cfg) GitalyInternalSocketPath() string { - return filepath.Join(cfg.InternalSocketDir, fmt.Sprintf("internal_%d.sock", os.Getpid())) +// InternalSocketDir returns the location of the internal socket directory. +func (cfg *Cfg) InternalSocketDir() string { + return filepath.Join(cfg.RuntimeDir, "sock.d") +} + +// InternalSocketPath is the path to the internal Gitaly socket. +func (cfg *Cfg) InternalSocketPath() string { + return filepath.Join(cfg.InternalSocketDir(), "intern") } func (cfg *Cfg) validateBinDir() error { @@ -410,8 +397,8 @@ func (cfg *Cfg) validateBinDir() error { } func (cfg *Cfg) validateRuntimeDir() error { - if len(cfg.RuntimeDir) == 0 { - return fmt.Errorf("runtime_dir: is not set") + if cfg.RuntimeDir == "" { + return nil } if err := validateIsDirectory(cfg.RuntimeDir, "runtime_dir"); err != nil { @@ -465,42 +452,6 @@ func (cfg *Cfg) validateToken() error { return nil } -func (cfg *Cfg) validateInternalSocketDir() error { - if cfg.InternalSocketDir == "" { - return nil - } - - if err := validateIsDirectory(cfg.InternalSocketDir, "internal_socket_dir"); err != nil { - return err - } - - if err := trySocketCreation(cfg.InternalSocketDir); err != nil { - return fmt.Errorf("internal_socket_dir: try create socket: %w", err) - } - return nil -} - -func trySocketCreation(dir string) error { - // To validate the socket can actually be created, we open and close a socket. - // Any error will be assumed persistent for when the gitaly-ruby sockets are created - // and thus fatal at boot time - b, err := text.RandomHex(4) - if err != nil { - return err - } - - socketPath := filepath.Join(dir, fmt.Sprintf("test-%s.sock", b)) - defer func() { _ = os.Remove(socketPath) }() - - // Attempt to create an actual socket and not just a file to catch socket path length problems - l, err := net.Listen("unix", socketPath) - if err != nil { - return fmt.Errorf("socket could not be created in %s: %s", dir, err) - } - - return l.Close() -} - // defaultMaintenanceWindow specifies a 10 minute job that runs daily at +1200 // GMT time func defaultMaintenanceWindow(storages []Storage) DailyJob { @@ -512,7 +463,7 @@ func defaultMaintenanceWindow(storages []Storage) DailyJob { return DailyJob{ Hour: 12, Minute: 0, - Duration: Duration(10 * time.Minute), + Duration: duration.Duration(10 * time.Minute), Storages: storageNames, } } @@ -546,24 +497,12 @@ func (cfg *Cfg) validateMaintenance() error { func (cfg *Cfg) validateCgroups() error { cg := cfg.Cgroups - if cg.Count == 0 { - return nil + if cg.MemoryBytes > 0 && (cg.Repositories.MemoryBytes > cg.MemoryBytes) { + return errors.New("cgroups.repositories: memory limit cannot exceed parent") } - if cg.Mountpoint == "" { - return fmt.Errorf("cgroups.mountpoint: cannot be empty") - } - - if cg.HierarchyRoot == "" { - return fmt.Errorf("cgroups.hierarchy_root: cannot be empty") - } - - if cg.CPU.Enabled && cg.CPU.Shares == 0 { - return fmt.Errorf("cgroups.cpu.shares: has to be greater than zero") - } - - if cg.Memory.Enabled && (cg.Memory.Limit == 0 || cg.Memory.Limit < -1) { - return fmt.Errorf("cgroups.memory.limit: has to be greater than zero or equal to -1") + if cg.MemoryBytes > 0 && (cg.Repositories.CPUShares > cg.CPUShares) { + return errors.New("cgroups.repositories: cpu shares cannot exceed parent") } return nil @@ -586,7 +525,7 @@ func (cfg *Cfg) configurePackObjectsCache() error { } if poc.MaxAge == 0 { - poc.MaxAge = Duration(5 * time.Minute) + poc.MaxAge = duration.Duration(5 * time.Minute) } if poc.Dir == "" { @@ -603,3 +542,97 @@ func (cfg *Cfg) configurePackObjectsCache() error { return nil } + +// SetupRuntimeDirectory creates a new runtime directory. Runtime directory contains internal +// runtime data generated by Gitaly such as the internal sockets. If cfg.RuntimeDir is set, +// it's used as the parent directory for the runtime directory. Runtime directory owner process +// can be identified by the suffix process ID suffixed in the directory name. If a directory already +// exists for this process' ID, it's removed and recreated. If cfg.RuntimeDir is not set, a temporary +// directory is used instead. A directory is created for the internal socket as well since it is +// expected to be present in the runtime directory. SetupRuntimeDirectory returns the absolute path +// to the created runtime directory. +func SetupRuntimeDirectory(cfg Cfg, processID int) (string, error) { + var runtimeDir string + if cfg.RuntimeDir == "" { + // If there is no parent directory provided, we just use a temporary directory + // as the runtime directory. This may not always be an ideal choice given that + // it's typically created at `/tmp`, which may get periodically pruned if `noatime` + // is set. + var err error + runtimeDir, err = os.MkdirTemp("", "gitaly-") + if err != nil { + return "", fmt.Errorf("creating temporary runtime directory: %w", err) + } + } else { + // Otherwise, we use the configured runtime directory. Note that we don't use the + // runtime directory directly, but instead create a subdirectory within it which is + // based on the process's PID. While we could use `MkdirTemp()` instead and don't + // bother with preexisting directories, the benefit of using the PID here is that we + // can determine whether the directory may still be in use by checking whether the + // PID exists. Furthermore, it allows easier debugging in case one wants to inspect + // the runtime directory of a running Gitaly node. + + runtimeDir = GetGitalyProcessTempDir(cfg.RuntimeDir, processID) + + if _, err := os.Stat(runtimeDir); err != nil && !os.IsNotExist(err) { + return "", fmt.Errorf("statting runtime directory: %w", err) + } else if err != nil { + // If the directory exists already then it must be from an old invocation of + // Gitaly. Because we use the PID as path component we know that the old + // instance cannot exist anymore though, so it's safe to remove this + // directory now. + if err := os.RemoveAll(runtimeDir); err != nil { + return "", fmt.Errorf("removing old runtime directory: %w", err) + } + } + + if err := os.Mkdir(runtimeDir, 0o700); err != nil { + return "", fmt.Errorf("creating runtime directory: %w", err) + } + } + + // Set the runtime dir in the config as the internal socket helpers + // rely on it. + cfg.RuntimeDir = runtimeDir + + // The socket path must be short-ish because listen(2) fails on long + // socket paths. We hope/expect that os.MkdirTemp creates a directory + // that is not too deep. We need a directory, not a tempfile, because we + // will later want to set its permissions to 0700 + if err := os.Mkdir(cfg.InternalSocketDir(), 0o700); err != nil { + return "", fmt.Errorf("create internal socket directory: %w", err) + } + + if err := trySocketCreation(cfg.InternalSocketDir()); err != nil { + return "", fmt.Errorf("failed creating internal test socket: %w", err) + } + + return runtimeDir, nil +} + +func trySocketCreation(dir string) error { + // To validate the socket can actually be created, we open and close a socket. + // Any error will be assumed persistent for when the gitaly-ruby sockets are created + // and thus fatal at boot time. + // + // There are two kinds of internal sockets we create: the internal server socket + // called "intern", and then the Ruby worker sockets called "ruby.$N", with "$N" + // being the number of the Ruby worker. Given that we typically wouldn't spawn + // hundreds of Ruby workers, the maximum internal socket path name would thus be 7 + // characters long. + socketPath := filepath.Join(dir, "tsocket") + defer func() { _ = os.Remove(socketPath) }() + + // Attempt to create an actual socket and not just a file to catch socket path length problems + l, err := net.Listen("unix", socketPath) + if err != nil { + var errno syscall.Errno + if errors.As(err, &errno) && errno == syscall.EINVAL { + return fmt.Errorf("%w: your socket path is likely too long, please change Gitaly's runtime directory", errno) + } + + return fmt.Errorf("socket could not be created in %s: %w", dir, err) + } + + return l.Close() +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config_test.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config_test.go index 82c345c71e..ed56ae236c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/config_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/config_test.go @@ -1,7 +1,8 @@ +//go:build !gitaly_test_sha256 + package config import ( - "bytes" "errors" "fmt" "os" @@ -12,13 +13,25 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/cgroups" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) +func TestBinaryPath(t *testing.T) { + cfg := Cfg{ + BinDir: "bindir", + RuntimeDir: "runtime", + } + + require.Equal(t, "runtime/gitaly-hooks", cfg.BinaryPath("gitaly-hooks")) + require.Equal(t, "bindir/gitaly-debug", cfg.BinaryPath("gitaly-debug")) + require.Equal(t, "bindir", cfg.BinaryPath("")) +} + func TestLoadBrokenConfig(t *testing.T) { tmpFile := strings.NewReader(`path = "/tmp"\nname="foo"`) _, err := Load(tmpFile) @@ -30,8 +43,7 @@ func TestLoadEmptyConfig(t *testing.T) { require.NoError(t, err) expectedCfg := Cfg{ - Prometheus: prometheus.DefaultConfig(), - InternalSocketDir: cfg.InternalSocketDir, + Prometheus: prometheus.DefaultConfig(), } require.NoError(t, expectedCfg.setDefaults()) @@ -145,7 +157,7 @@ func TestLoadPrometheus(t *testing.T) { require.Equal(t, ":9236", cfg.PrometheusListenAddr) require.Equal(t, prometheus.Config{ - ScrapeTimeout: time.Second, + ScrapeTimeout: duration.Duration(time.Second), GRPCLatencyBuckets: []float64{0, 1, 2}, }, cfg.Prometheus) } @@ -563,16 +575,16 @@ func TestLoadGracefulRestartTimeout(t *testing.T) { tests := []struct { name string config string - expected time.Duration + expected duration.Duration }{ { name: "default value", - expected: 1 * time.Minute, + expected: duration.Duration(1 * time.Minute), }, { name: "8m03s", config: `graceful_restart_timeout = "8m03s"`, - expected: 8*time.Minute + 3*time.Second, + expected: duration.Duration(8*time.Minute + 3*time.Second), }, } for _, test := range tests { @@ -582,7 +594,7 @@ func TestLoadGracefulRestartTimeout(t *testing.T) { cfg, err := Load(tmpFile) assert.NoError(t, err) - assert.Equal(t, test.expected, cfg.GracefulRestartTimeout.Duration()) + assert.Equal(t, test.expected, cfg.GracefulRestartTimeout) }) } } @@ -603,81 +615,82 @@ dir = '%s'`, gitlabShellDir)) }, cfg.Hooks) } -func TestValidateInternalSocketDir(t *testing.T) { - // create a valid socket directory - tmpDir := testhelper.TempDir(t) - // create a symlinked socket directory - dirName := "internal_socket_dir" - validSocketDirSymlink := filepath.Join(tmpDir, dirName) - tmpSocketDir, err := os.MkdirTemp(tmpDir, "") - require.NoError(t, err) - tmpSocketDir, err = filepath.Abs(tmpSocketDir) - require.NoError(t, err) - require.NoError(t, os.Symlink(tmpSocketDir, validSocketDirSymlink)) - - // create a broken symlink - dirName = "internal_socket_dir_broken" - brokenSocketDirSymlink := filepath.Join(tmpDir, dirName) - require.NoError(t, os.Symlink("/does/not/exist", brokenSocketDirSymlink)) - - pathTooLongForSocket := filepath.Join(tmpDir, strings.Repeat("/nested_directory", 10)) - require.NoError(t, os.MkdirAll(pathTooLongForSocket, os.ModePerm)) +func TestSetupRuntimeDirectory_validateInternalSocket(t *testing.T) { + verifyPathDoesNotExist := func(t *testing.T, runtimeDir string, actualErr error) { + require.EqualError(t, actualErr, fmt.Sprintf("creating runtime directory: mkdir %s/gitaly-%d: no such file or directory", runtimeDir, os.Getpid())) + } testCases := []struct { - desc string - internalSocketDir string - expErrMsgRegexp string + desc string + setup func(t *testing.T) string + verify func(t *testing.T, runtimeDir string, actualErr error) }{ { - desc: "empty socket dir", - internalSocketDir: "", + desc: "non existing directory", + setup: func(t *testing.T) string { + return "/path/does/not/exist" + }, + verify: verifyPathDoesNotExist, }, { - desc: "non existing directory", - internalSocketDir: "/tmp/relative/path/to/nowhere", - expErrMsgRegexp: `internal_socket_dir: path doesn't exist: "/tmp/relative/path/to/nowhere"`, + desc: "symlinked runtime directory", + setup: func(t *testing.T) string { + runtimeDir := testhelper.TempDir(t) + require.NoError(t, os.Mkdir(filepath.Join(runtimeDir, "sock.d"), os.ModePerm)) + + // Create a symlink which points to the real runtime directory. + symlinkDir := testhelper.TempDir(t) + symlink := filepath.Join(symlinkDir, "symlink-to-runtime-dir") + require.NoError(t, os.Symlink(runtimeDir, symlink)) + + return symlink + }, }, { - desc: "valid socket directory", - internalSocketDir: tmpDir, + desc: "broken symlinked runtime directory", + setup: func(t *testing.T) string { + symlinkDir := testhelper.TempDir(t) + symlink := filepath.Join(symlinkDir, "symlink-to-runtime-dir") + require.NoError(t, os.Symlink("/path/does/not/exist", symlink)) + return symlink + }, + verify: verifyPathDoesNotExist, }, { - desc: "valid symlinked directory", - internalSocketDir: validSocketDirSymlink, - }, - { - desc: "broken symlinked directory", - internalSocketDir: brokenSocketDirSymlink, - expErrMsgRegexp: fmt.Sprintf(`internal_socket_dir: path doesn't exist: %q`, brokenSocketDirSymlink), - }, - { - desc: "socket can't be created", - internalSocketDir: pathTooLongForSocket, - expErrMsgRegexp: `internal_socket_dir: try create socket: socket could not be created in .*\/test-.{8}\.sock: bind: invalid argument`, + desc: "socket can't be created", + setup: func(t *testing.T) string { + tempDir := testhelper.TempDir(t) + + runtimeDirTooLongForSockets := filepath.Join(tempDir, strings.Repeat("/nested_directory", 10)) + socketDir := filepath.Join(runtimeDirTooLongForSockets, "sock.d") + require.NoError(t, os.MkdirAll(socketDir, os.ModePerm)) + + return runtimeDirTooLongForSockets + }, + verify: func(t *testing.T, runtimeDir string, actualErr error) { + require.EqualError(t, actualErr, "failed creating internal test socket: invalid argument: your socket path is likely too long, please change Gitaly's runtime directory") + }, }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - err := (&Cfg{InternalSocketDir: tc.internalSocketDir}).validateInternalSocketDir() - if tc.expErrMsgRegexp != "" { - assert.Regexp(t, tc.expErrMsgRegexp, err) + runtimeDir := tc.setup(t) + + cfg := Cfg{ + RuntimeDir: runtimeDir, + } + + _, actualErr := SetupRuntimeDirectory(cfg, os.Getpid()) + if tc.verify == nil { + require.NoError(t, actualErr) } else { - assert.NoError(t, err) + tc.verify(t, cfg.RuntimeDir, actualErr) } }) } } -func TestInternalSocketDir(t *testing.T) { - cfg, err := Load(bytes.NewReader(nil)) - require.NoError(t, err) - socketDir := cfg.InternalSocketDir - - require.NoError(t, trySocketCreation(socketDir)) - require.NoError(t, os.RemoveAll(socketDir)) -} - func TestLoadDailyMaintenance(t *testing.T) { for _, tt := range []struct { name string @@ -701,7 +714,7 @@ func TestLoadDailyMaintenance(t *testing.T) { expect: DailyJob{ Hour: 11, Minute: 23, - Duration: Duration(45 * time.Minute), + Duration: duration.Duration(45 * time.Minute), Storages: []string{"default"}, }, }, @@ -739,7 +752,7 @@ func TestLoadDailyMaintenance(t *testing.T) { expect: DailyJob{ Hour: 0, Minute: 59, - Duration: Duration(24*time.Hour + time.Second), + Duration: duration.Duration(24*time.Hour + time.Second), }, validateErr: errors.New("daily maintenance specified duration 24h0m1s must be less than 24 hours"), }, @@ -747,7 +760,7 @@ func TestLoadDailyMaintenance(t *testing.T) { rawCfg: `[daily_maintenance] duration = "meow"`, expect: DailyJob{}, - loadErr: errors.New("load toml: (2, 4): unmarshal text: time: invalid duration"), + loadErr: errors.New("load toml: toml: time: invalid duration \"meow\""), }, { rawCfg: `[daily_maintenance] @@ -766,7 +779,7 @@ func TestLoadDailyMaintenance(t *testing.T) { expect: DailyJob{ Hour: 12, Minute: 0, - Duration: Duration(10 * time.Minute), + Duration: duration.Duration(10 * time.Minute), Storages: []string{"default"}, }, }, @@ -796,139 +809,303 @@ func TestLoadDailyMaintenance(t *testing.T) { } func TestValidateCgroups(t *testing.T) { - for _, tt := range []struct { + type testCase struct { name string rawCfg string expect cgroups.Config validateErr error - }{ - { - name: "enabled success", - rawCfg: `[cgroups] - count = 10 - mountpoint = "/sys/fs/cgroup" - hierarchy_root = "gitaly" - [cgroups.memory] - enabled = true - limit = 1024 - [cgroups.cpu] - enabled = true - shares = 512`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "/sys/fs/cgroup", - HierarchyRoot: "gitaly", - Memory: cgroups.Memory{ - Enabled: true, - Limit: 1024, - }, - CPU: cgroups.CPU{ - Enabled: true, - Shares: 512, - }, - }, - }, - { - name: "disabled success", - rawCfg: `[cgroups] - count = 0`, - expect: cgroups.Config{ - Count: 0, - }, - }, - { - name: "empty mount point", - rawCfg: `[cgroups] - count = 10 - mountpoint = ""`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "", - }, - validateErr: errors.New("cgroups.mountpoint: cannot be empty"), - }, - { - name: "empty hierarchy_root", - rawCfg: `[cgroups] - count = 10 - mountpoint = "/sys/fs/cgroup" - hierarchy_root = ""`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "/sys/fs/cgroup", - HierarchyRoot: "", - }, - validateErr: errors.New("cgroups.hierarchy_root: cannot be empty"), - }, - { - name: "invalid cpu shares", - rawCfg: `[cgroups] - count = 10 - mountpoint = "/sys/fs/cgroup" - hierarchy_root = "gitaly" - [cgroups.cpu] - enabled = true - shares = 0`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "/sys/fs/cgroup", - HierarchyRoot: "gitaly", - CPU: cgroups.CPU{ - Enabled: true, - Shares: 0, - }, - }, - validateErr: errors.New("cgroups.cpu.shares: has to be greater than zero"), - }, - { - name: "invalid memory limit - zero", - rawCfg: `[cgroups] - count = 10 - mountpoint = "/sys/fs/cgroup" - hierarchy_root = "gitaly" - [cgroups.memory] - enabled = true - limit = 0`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "/sys/fs/cgroup", - HierarchyRoot: "gitaly", - Memory: cgroups.Memory{ - Enabled: true, - Limit: 0, - }, - }, - validateErr: errors.New("cgroups.memory.limit: has to be greater than zero or equal to -1"), - }, - { - name: "invalid memory limit - negative", - rawCfg: `[cgroups] - count = 10 - mountpoint = "/sys/fs/cgroup" - hierarchy_root = "gitaly" - [cgroups.memory] - enabled = true - limit = -5`, - expect: cgroups.Config{ - Count: 10, - Mountpoint: "/sys/fs/cgroup", - HierarchyRoot: "gitaly", - Memory: cgroups.Memory{ - Enabled: true, - Limit: -5, - }, - }, - validateErr: errors.New("cgroups.memory.limit: has to be greater than zero or equal to -1"), - }, - } { - t.Run(tt.name, func(t *testing.T) { - tmpFile := strings.NewReader(tt.rawCfg) - cfg, err := Load(tmpFile) - require.NoError(t, err) - require.Equal(t, tt.expect, cfg.Cgroups) - require.Equal(t, tt.validateErr, cfg.validateCgroups()) - }) } + + t.Run("old format", func(t *testing.T) { + testCases := []testCase{ + { + name: "enabled success", + rawCfg: `[cgroups] + count = 10 + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.memory] + enabled = true + limit = 1024 + [cgroups.cpu] + enabled = true + shares = 512`, + expect: cgroups.Config{ + Count: 10, + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Memory: cgroups.Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: cgroups.CPU{ + Enabled: true, + Shares: 512, + }, + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 1024, + CPUShares: 512, + }, + }, + }, + { + name: "empty mount point", + rawCfg: `[cgroups] + count = 10 + mountpoint = "" + hierarchy_root = "baz" + `, + expect: cgroups.Config{ + Count: 10, + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "baz", + Repositories: cgroups.Repositories{ + Count: 10, + }, + }, + }, + { + name: "empty hierarchy_root", + rawCfg: `[cgroups] + count = 10 + mountpoint = "/sys/fs/cgroup" + hierarchy_root = ""`, + expect: cgroups.Config{ + Count: 10, + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + }, + }, + }, + { + name: "cpu shares - zero", + rawCfg: `[cgroups] + count = 10 + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.memory] + enabled = true + limit = 1024 + [cgroups.cpu] + enabled = true + shares = 0`, + expect: cgroups.Config{ + Count: 10, + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Memory: cgroups.Memory{ + Enabled: true, + Limit: 1024, + }, + CPU: cgroups.CPU{ + Enabled: true, + Shares: 0, + }, + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 1024, + }, + }, + }, + { + name: "memory limit - zero", + rawCfg: `[cgroups] + count = 10 + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.memory] + enabled = true + limit = 0 + [cgroups.cpu] + enabled = true + shares = 512 + `, + expect: cgroups.Config{ + Count: 10, + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Memory: cgroups.Memory{ + Enabled: true, + Limit: 0, + }, + CPU: cgroups.CPU{ + Enabled: true, + Shares: 512, + }, + Repositories: cgroups.Repositories{ + Count: 10, + CPUShares: 512, + }, + }, + }, + { + name: "repositories - zero count", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.repositories] + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + }, + }, + } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + tmpFile := strings.NewReader(tt.rawCfg) + cfg, err := Load(tmpFile) + require.NoError(t, err) + require.Equal(t, tt.expect, cfg.Cgroups) + require.Equal(t, tt.validateErr, cfg.validateCgroups()) + }) + } + }) + + t.Run("new format", func(t *testing.T) { + testCases := []testCase{ + { + name: "enabled success", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.repositories] + count = 10 + memory_bytes = 1024 + cpu_shares = 512 + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 1024, + CPUShares: 512, + }, + }, + }, + { + name: "repositories count is zero", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.repositories] + count = 0 + memory_bytes = 1024 + cpu_shares = 512 + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + MemoryBytes: 1024, + CPUShares: 512, + }, + }, + }, + { + name: "memory is zero", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + [cgroups.repositories] + count = 10 + cpu_shares = 512`, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + Repositories: cgroups.Repositories{ + Count: 10, + CPUShares: 512, + }, + }, + }, + { + name: "repositories memory exceeds parent", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + memory_bytes = 1073741824 + cpu_shares = 1024 + [cgroups.repositories] + count = 10 + memory_bytes = 2147483648 + cpu_shares = 128 + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + MemoryBytes: 1073741824, + CPUShares: 1024, + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 2147483648, + CPUShares: 128, + }, + }, + validateErr: errors.New("cgroups.repositories: memory limit cannot exceed parent"), + }, + { + name: "repositories cpu exceeds parent", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + memory_bytes = 1073741824 + cpu_shares = 128 + [cgroups.repositories] + count = 10 + memory_bytes = 1024 + cpu_shares = 512 + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + MemoryBytes: 1073741824, + CPUShares: 128, + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 1024, + CPUShares: 512, + }, + }, + validateErr: errors.New("cgroups.repositories: cpu shares cannot exceed parent"), + }, + { + name: "metrics enabled", + rawCfg: `[cgroups] + mountpoint = "/sys/fs/cgroup" + hierarchy_root = "gitaly" + metrics_enabled = true + [cgroups.repositories] + count = 10 + memory_bytes = 1024 + cpu_shares = 512 + `, + expect: cgroups.Config{ + Mountpoint: "/sys/fs/cgroup", + HierarchyRoot: "gitaly", + MetricsEnabled: true, + Repositories: cgroups.Repositories{ + Count: 10, + MemoryBytes: 1024, + CPUShares: 512, + }, + }, + }, + } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + tmpFile := strings.NewReader(tt.rawCfg) + cfg, err := Load(tmpFile) + require.NoError(t, err) + require.Equal(t, tt.expect, cfg.Cgroups) + require.Equal(t, tt.validateErr, cfg.validateCgroups()) + }) + } + }) } func TestConfigurePackObjectsCache(t *testing.T) { @@ -949,7 +1126,7 @@ path="/foobar" in: storageConfig + `[pack_objects_cache] enabled = true `, - out: StreamCacheConfig{Enabled: true, MaxAge: Duration(5 * time.Minute), Dir: "/foobar/+gitaly/PackObjectsCache"}, + out: StreamCacheConfig{Enabled: true, MaxAge: duration.Duration(5 * time.Minute), Dir: "/foobar/+gitaly/PackObjectsCache"}, }, { desc: "enabled with custom values", @@ -958,7 +1135,7 @@ enabled = true dir = "/bazqux" max_age = "10m" `, - out: StreamCacheConfig{Enabled: true, MaxAge: Duration(10 * time.Minute), Dir: "/bazqux"}, + out: StreamCacheConfig{Enabled: true, MaxAge: duration.Duration(10 * time.Minute), Dir: "/bazqux"}, }, { desc: "enabled with 0 storages", @@ -1052,15 +1229,15 @@ func TestValidateBinDir(t *testing.T) { } } -func TestCfg_RuntimeDir(t *testing.T) { +func TestSetupRuntimeDirectory(t *testing.T) { t.Run("defaults", func(t *testing.T) { t.Run("empty runtime directory", func(t *testing.T) { cfg := Cfg{} - require.NoError(t, cfg.setDefaults()) + runtimeDir, err := SetupRuntimeDirectory(cfg, os.Getpid()) + require.NoError(t, err) - require.Equal(t, os.TempDir(), filepath.Dir(cfg.RuntimeDir)) - require.True(t, strings.HasPrefix(filepath.Base(cfg.RuntimeDir), "gitaly-")) - require.DirExists(t, cfg.RuntimeDir) + require.DirExists(t, runtimeDir) + require.True(t, strings.HasPrefix(runtimeDir, filepath.Join(os.TempDir(), "gitaly-"))) }) t.Run("non-existent runtime directory", func(t *testing.T) { @@ -1068,7 +1245,8 @@ func TestCfg_RuntimeDir(t *testing.T) { RuntimeDir: "/does/not/exist", } - require.EqualError(t, cfg.setDefaults(), fmt.Sprintf("creating runtime directory: mkdir /does/not/exist/gitaly-%d: no such file or directory", os.Getpid())) + _, err := SetupRuntimeDirectory(cfg, os.Getpid()) + require.EqualError(t, err, fmt.Sprintf("creating runtime directory: mkdir /does/not/exist/gitaly-%d: no such file or directory", os.Getpid())) }) t.Run("existent runtime directory", func(t *testing.T) { @@ -1076,9 +1254,12 @@ func TestCfg_RuntimeDir(t *testing.T) { cfg := Cfg{ RuntimeDir: dir, } - require.NoError(t, cfg.setDefaults()) - require.Equal(t, filepath.Join(dir, fmt.Sprintf("gitaly-%d", os.Getpid())), cfg.RuntimeDir) - require.DirExists(t, cfg.RuntimeDir) + + runtimeDir, err := SetupRuntimeDirectory(cfg, os.Getpid()) + require.NoError(t, err) + + require.Equal(t, filepath.Join(dir, fmt.Sprintf("gitaly-%d", os.Getpid())), runtimeDir) + require.DirExists(t, runtimeDir) }) }) @@ -1097,9 +1278,8 @@ func TestCfg_RuntimeDir(t *testing.T) { runtimeDir: dirPath, }, { - desc: "unset", - runtimeDir: "", - expectedErr: fmt.Errorf("runtime_dir: is not set"), + desc: "unset", + runtimeDir: "", }, { desc: "path doesn't exist", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/locator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/locator.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/locator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/locator.go index 15b7376ab8..8476bfa643 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/locator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/locator.go @@ -4,8 +4,8 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -106,7 +106,7 @@ func (l *configLocator) StateDir(storageName string) (string, error) { return l.getPath(storageName, statePrefix) } -// TempDir returns the path to the temp dir for a storag. +// TempDir returns the path to the temp dir for a storage. func (l *configLocator) TempDir(storageName string) (string, error) { return l.getPath(storageName, tmpRootPrefix) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log/log.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log/log.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log/log.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log/log.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus/config.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus/config.go index 4873eec1d3..12fbeec094 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus/config.go @@ -6,12 +6,13 @@ import ( grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) // Config contains additional configuration data for prometheus type Config struct { // ScrapeTimeout is the allowed duration of a Prometheus scrape before timing out. - ScrapeTimeout time.Duration `toml:"scrape_timeout,omitempty"` + ScrapeTimeout duration.Duration `toml:"scrape_timeout,omitempty"` // GRPCLatencyBuckets configures the histogram buckets used for gRPC // latency measurements. GRPCLatencyBuckets []float64 `toml:"grpc_latency_buckets,omitempty"` @@ -20,7 +21,7 @@ type Config struct { // DefaultConfig returns a new config with default values set. func DefaultConfig() Config { return Config{ - ScrapeTimeout: 10 * time.Second, + ScrapeTimeout: duration.Duration(10 * time.Second), GRPCLatencyBuckets: []float64{0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0}, } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/ruby.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/ruby.go new file mode 100644 index 0000000000..92fa70c606 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/ruby.go @@ -0,0 +1,59 @@ +package config + +import ( + "fmt" + "path/filepath" + "time" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" +) + +// Ruby contains setting for Ruby worker processes +type Ruby struct { + Dir string `toml:"dir"` + MaxRSS int `toml:"max_rss"` + GracefulRestartTimeout duration.Duration `toml:"graceful_restart_timeout"` + RestartDelay duration.Duration `toml:"restart_delay"` + NumWorkers int `toml:"num_workers"` + LinguistLanguagesPath string `toml:"linguist_languages_path"` + RuggedGitConfigSearchPath string `toml:"rugged_git_config_search_path"` +} + +// ConfigureRuby validates the gitaly-ruby configuration and sets default values. +func (cfg *Cfg) ConfigureRuby() error { + if cfg.Ruby.GracefulRestartTimeout.Duration() == 0 { + cfg.Ruby.GracefulRestartTimeout = duration.Duration(10 * time.Minute) + } + + if cfg.Ruby.MaxRSS == 0 { + cfg.Ruby.MaxRSS = 200 * 1024 * 1024 + } + + if cfg.Ruby.RestartDelay.Duration() == 0 { + cfg.Ruby.RestartDelay = duration.Duration(5 * time.Minute) + } + + if len(cfg.Ruby.Dir) == 0 { + return fmt.Errorf("gitaly-ruby.dir: is not set") + } + + minWorkers := 2 + if cfg.Ruby.NumWorkers < minWorkers { + cfg.Ruby.NumWorkers = minWorkers + } + + var err error + cfg.Ruby.Dir, err = filepath.Abs(cfg.Ruby.Dir) + if err != nil { + return err + } + + if len(cfg.Ruby.RuggedGitConfigSearchPath) != 0 { + cfg.Ruby.RuggedGitConfigSearchPath, err = filepath.Abs(cfg.Ruby.RuggedGitConfigSearchPath) + if err != nil { + return err + } + } + + return validateIsDirectory(cfg.Ruby.Dir, "gitaly-ruby.dir") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry/sentry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry/sentry.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry/sentry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry/sentry.go index fc35597487..6bc263dca9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry/sentry.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry/sentry.go @@ -5,7 +5,7 @@ import ( sentry "github.com/getsentry/sentry-go" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler" ) // Config contains configuration for sentry diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir.go new file mode 100644 index 0000000000..d27100edfa --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir.go @@ -0,0 +1,87 @@ +package config + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + "syscall" + + log "github.com/sirupsen/logrus" +) + +// PruneOldGitalyProcessDirectories removes leftover temporary directories that belonged to processes that +// no longer exist. Directories are expected to be in the form gitaly-. +// The removals are logged prior to being executed. Unexpected directory entries are logged +// but not removed. +func PruneOldGitalyProcessDirectories(log log.FieldLogger, directory string) error { + entries, err := os.ReadDir(directory) + if err != nil { + return fmt.Errorf("list gitaly process directory: %w", err) + } + + for _, entry := range entries { + log := log.WithField("path", filepath.Join(directory, entry.Name())) + if err := func() error { + if !entry.IsDir() { + // There should be no files, only the gitaly process directories. + return errors.New("gitaly process directory contains an unexpected file") + } + + components := strings.Split(entry.Name(), "-") + if len(components) != 2 || components[0] != "gitaly" { + // This directory does not match the gitaly process directory naming format + // of `gitaly-. + return errors.New("gitaly process directory contains an unexpected directory") + } + + processID, err := strconv.ParseInt(components[1], 10, 64) + if err != nil { + // This is not a temporary gitaly process directory as the section + // after the hyphen is not a process id. + return errors.New("gitaly process directory contains an unexpected directory") + } + + process, err := os.FindProcess(int(processID)) + if err != nil { + return fmt.Errorf("could not find process: %w", err) + } + + defer func() { + if err := process.Release(); err != nil { + log.WithError(err).Error("failed releasing process") + } + }() + + if err := process.Signal(syscall.Signal(0)); err != nil { + // Either the process does not exist, or the pid has been re-used by for a + // process owned by another user and is not a Gitaly process. + if !errors.Is(err, os.ErrProcessDone) && !errors.Is(err, syscall.EPERM) { + return fmt.Errorf("sending signal 0 to process: %w", err) + } + + if err := os.RemoveAll(filepath.Join(directory, entry.Name())); err != nil { + return fmt.Errorf("removing leftover gitaly process directory: %w", err) + } + + log.Info("removed leftover gitaly process directory") + } + + return nil + }(); err != nil { + log.WithError(err).Error("could not prune entry") + continue + } + } + + return nil +} + +// GetGitalyProcessTempDir constructs a temporary directory name for the current gitaly +// process. This way, we can clean up old temporary directories by inspecting the pid attached +// to the folder. +func GetGitalyProcessTempDir(parentDir string, processID int) string { + return filepath.Join(parentDir, fmt.Sprintf("gitaly-%d", processID)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir_test.go new file mode 100644 index 0000000000..9961278ce5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/temp_dir_test.go @@ -0,0 +1,113 @@ +//go:build !gitaly_test_sha256 + +package config + +import ( + "errors" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestPruneOldGitalyProcessDirectories(t *testing.T) { + t.Run("no runtime directories", func(t *testing.T) { + require.NoError(t, PruneOldGitalyProcessDirectories(testhelper.NewDiscardingLogEntry(t), testhelper.TempDir(t))) + }) + + t.Run("unset runtime directory", func(t *testing.T) { + require.EqualError(t, + PruneOldGitalyProcessDirectories(testhelper.NewDiscardingLogEntry(t), ""), "list gitaly process directory: open : no such file or directory") + }) + + t.Run("non-existent runtime directory", func(t *testing.T) { + require.EqualError(t, + PruneOldGitalyProcessDirectories(testhelper.NewDiscardingLogEntry(t), + "/path/does/not/exist"), "list gitaly process directory: open /path/does/not/exist: no such file or directory") + }) + + t.Run("invalid, stale and active runtime directories", func(t *testing.T) { + baseDir := testhelper.TempDir(t) + cfg := Cfg{RuntimeDir: baseDir} + + // Setup a runtime directory for our process, it can't be stale as long as + // we are running. + ownRuntimeDir, err := SetupRuntimeDirectory(cfg, os.Getpid()) + require.NoError(t, err) + + expectedLogs := map[string]string{} + expectedErrs := map[string]error{} + + // Setup runtime directories for processes that have finished. + var prunableDirs []string + for i := 0; i < 2; i++ { + cmd := exec.Command("cat") + require.NoError(t, cmd.Run()) + + staleRuntimeDir, err := SetupRuntimeDirectory(cfg, cmd.Process.Pid) + require.NoError(t, err) + + prunableDirs = append(prunableDirs, staleRuntimeDir) + expectedLogs[staleRuntimeDir] = "removed leftover gitaly process directory" + } + + // Setup runtime directory with pid of process not owned by git user + rootRuntimeDir, err := SetupRuntimeDirectory(cfg, 1) + require.NoError(t, err) + expectedLogs[rootRuntimeDir] = "removed leftover gitaly process directory" + prunableDirs = append(prunableDirs, rootRuntimeDir) + + // Create an unexpected file in the runtime directory + unexpectedFilePath := filepath.Join(baseDir, "unexpected-file") + require.NoError(t, os.WriteFile(unexpectedFilePath, []byte(""), os.ModePerm)) + expectedLogs[unexpectedFilePath] = "could not prune entry" + expectedErrs[unexpectedFilePath] = errors.New("gitaly process directory contains an unexpected file") + + nonPrunableDirs := []string{ownRuntimeDir} + + // Setup some unexpected directories in the runtime directory + for _, dirName := range []string{ + "nohyphen", + "too-many-hyphens", + "invalidprefix-3", + "gitaly-invalidpid", + } { + dirPath := filepath.Join(baseDir, dirName) + require.NoError(t, os.Mkdir(dirPath, os.ModePerm)) + expectedLogs[dirPath] = "could not prune entry" + expectedErrs[dirPath] = errors.New("gitaly process directory contains an unexpected directory") + nonPrunableDirs = append(nonPrunableDirs, dirPath) + } + + logger, hook := test.NewNullLogger() + require.NoError(t, PruneOldGitalyProcessDirectories(logger, cfg.RuntimeDir)) + + actualLogs := map[string]string{} + actualErrs := map[string]error{} + for _, entry := range hook.Entries { + actualLogs[entry.Data["path"].(string)] = entry.Message + if entry.Data["error"] != nil { + err, ok := entry.Data["error"].(error) + require.True(t, ok) + actualErrs[entry.Data["path"].(string)] = err + } + } + + require.Equal(t, expectedLogs, actualLogs) + require.Equal(t, expectedErrs, actualErrs) + + require.FileExists(t, unexpectedFilePath) + + for _, nonPrunableEntry := range nonPrunableDirs { + require.DirExists(t, nonPrunableEntry, nonPrunableEntry) + } + + for _, prunableEntry := range prunableDirs { + require.NoDirExists(t, prunableEntry, prunableEntry) + } + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/testhelper_test.go index 8cced0b741..8700c49471 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package config import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff.go index 3fb8191f70..f33c630e14 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff.go @@ -8,8 +8,8 @@ import ( "regexp" "strconv" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" ) // Diff represents a single parsed diff entry @@ -328,13 +328,13 @@ func (parser *Parser) handleTypeChangeDiff() { ":%o %o %s %s A\t%s\n", 0, parser.currentDiff.NewMode, - git.ZeroOID, + git.ObjectHashSHA1.ZeroOID, parser.currentDiff.ToID, parser.currentDiff.FromPath, ) parser.currentDiff.NewMode = 0 - parser.currentDiff.ToID = git.ZeroOID.String() + parser.currentDiff.ToID = git.ObjectHashSHA1.ZeroOID.String() parser.rawLines = append([][]byte{[]byte(newRawLine)}, parser.rawLines...) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff_test.go index fb8d8e754e..59a38d6f4e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/diff_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/diff_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package diff import ( @@ -7,7 +9,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" ) func TestDiffParserWithLargeDiffWithTrueCollapseDiffsFlag(t *testing.T) { @@ -47,7 +49,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "4cc7061661b8f52891bc1b39feb4d856b21a1067", FromPath: []byte("big.txt"), ToPath: []byte("big.txt"), @@ -58,7 +60,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "3be11c69355948412925fa5e073d76d58ff3afd2", FromPath: []byte("file-00.txt"), ToPath: []byte("file-00.txt"), @@ -266,7 +268,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "4cc7061661b8f52891bc1b39feb4d856b21a1067", FromPath: []byte("big.txt"), ToPath: []byte("big.txt"), @@ -278,7 +280,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "3be11c69355948412925fa5e073d76d58ff3afd2", FromPath: []byte("file-00.txt"), ToPath: []byte("file-00.txt"), @@ -329,7 +331,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "4cc7061661b8f52891bc1b39feb4d856b21a1067", FromPath: []byte("big.txt"), ToPath: []byte("big.txt"), @@ -342,7 +344,7 @@ index 0000000000000000000000000000000000000000..3be11c69355948412925fa5e073d76d5 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "3be11c69355948412925fa5e073d76d58ff3afd2", FromPath: []byte("file-00.txt"), ToPath: []byte("file-00.txt"), @@ -392,7 +394,7 @@ index 0000000000000000000000000000000000000000..b6507e5b5ce18077e3ec8aaa2291404e { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b6507e5b5ce18077e3ec8aaa2291404e5051d45d", FromPath: []byte("expand-collapse/file-0.txt"), ToPath: []byte("expand-collapse/file-0.txt"), @@ -404,7 +406,7 @@ index 0000000000000000000000000000000000000000..b6507e5b5ce18077e3ec8aaa2291404e { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b6507e5b5ce18077e3ec8aaa2291404e5051d45d", FromPath: []byte("expand-collapse/file-1.txt"), ToPath: []byte("expand-collapse/file-1.txt"), @@ -416,7 +418,7 @@ index 0000000000000000000000000000000000000000..b6507e5b5ce18077e3ec8aaa2291404e { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b6507e5b5ce18077e3ec8aaa2291404e5051d45d", FromPath: []byte("expand-collapse/file-2.txt"), ToPath: []byte("expand-collapse/file-2.txt"), @@ -450,7 +452,7 @@ index 0000000000000000000000000000000000000000..c3ae147b03a2d1fd89b25198b3fc5302 { OldMode: 0, NewMode: 0o100644, - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "c3ae147b03a2d1fd89b25198b3fc53028c5b0d53", FromPath: []byte("file-0"), ToPath: []byte("file-0"), @@ -485,8 +487,8 @@ func TestDiffLimitsBeingEnforcedByUpperBound(t *testing.T) { require.Equal(t, diffParser.limits.MaxPatchBytes, 0) } -func getDiffs(t testing.TB, rawDiff string, limits Limits) []*Diff { - t.Helper() +func getDiffs(tb testing.TB, rawDiff string, limits Limits) []*Diff { + tb.Helper() diffParser := NewDiffParser(strings.NewReader(rawDiff), limits) @@ -500,7 +502,7 @@ func getDiffs(t testing.TB, rawDiff string, limits Limits) []*Diff { diffs = append(diffs, &d) } - require.NoError(t, diffParser.Err()) + require.NoError(tb, diffParser.Err()) return diffs } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/numstat.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/numstat.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/numstat.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/numstat.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/numstat_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/numstat_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/numstat_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/numstat_test.go index 5f35a234af..cecd0ff6ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/numstat_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/numstat_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package diff import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/testdata/z-numstat.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/testdata/z-numstat.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff/testdata/z-numstat.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff/testdata/z-numstat.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/check.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/check.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/check.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/check.go index 57dd8bd749..181a862402 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/check.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/check.go @@ -3,10 +3,10 @@ package hook import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *GitLabHookManager) Check(ctx context.Context) (*gitlab.CheckInfo, error) { return m.gitlabClient.Check(ctx) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker.go new file mode 100644 index 0000000000..4a82e0f54a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker.go @@ -0,0 +1,116 @@ +package hook + +import ( + "context" + "sync" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/prometheus/client_golang/prometheus" +) + +// NewConcurrencyTracker creates a new ConcurrencyTracker. +func NewConcurrencyTracker() *ConcurrencyTracker { + c := &ConcurrencyTracker{ + concurrencyMap: make(map[string]int), + currentCallersVec: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "gitaly_pack_objects_process_active_callers", + Help: "Number of unique callers that have an active pack objects processes", + }, + []string{"segment"}, + ), + totalCallersVec: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gitaly_pack_objects_process_active_callers_total", + Help: "Total unique callers that have initiated a pack objects processes", + }, + []string{"segment"}, + ), + concurrentProcessesVec: prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "gitaly_pack_objects_concurrent_processes", + Help: "Number of concurrent processes", + Buckets: prometheus.LinearBuckets(0, 5, 20), + }, + []string{"segment"}, + ), + } + + return c +} + +// ConcurrencyTracker tracks concurrency of pack object calls +type ConcurrencyTracker struct { + lock sync.Mutex + concurrencyMap map[string]int + currentCallersVec *prometheus.GaugeVec + totalCallersVec *prometheus.CounterVec + concurrentProcessesVec *prometheus.HistogramVec +} + +func (c *ConcurrencyTracker) addConcurrencyDelta(compositeKey string, delta int) int { + c.lock.Lock() + defer c.lock.Unlock() + + c.concurrencyMap[compositeKey] += delta + + if c.concurrencyMap[compositeKey] == 0 { + delete(c.concurrencyMap, compositeKey) + } + + return c.concurrencyMap[compositeKey] +} + +// LogConcurrency logs the number of concurrent calls for a keyType, key +// combination +func (c *ConcurrencyTracker) LogConcurrency(ctx context.Context, keyType, key string) func() { + compositeKey := keyType + ":" + key + + concurrency := c.addConcurrencyDelta(compositeKey, 1) + if concurrency == 1 { + // If there are no entries in the map for this keyType, key + // combination, it means this is the first pack objects process + // for this keyType, key. Hence, we increment the total number + // of active callers for this keyType as this is a newly active + // caller of a pack object process. In finish, when the pack + // object process finishes, we check if it is the only active + // call and if so, we decrement this metric since that means the + // keyType, key caller is no longer responsible for any pack + c.currentCallersVec.WithLabelValues(keyType).Inc() + c.totalCallersVec.WithLabelValues(keyType).Inc() + } + + c.concurrentProcessesVec.WithLabelValues( + keyType, + ).Observe(float64(concurrency)) + + ctxlogrus.Extract(ctx). + WithField("concurrency_type", keyType). + WithField("concurrency_key", key). + WithField("concurrency", concurrency). + Info("concurrency") + + return func() { + c.finish(keyType, compositeKey) + } +} + +func (c *ConcurrencyTracker) finish(keyType, compositeKey string) { + if c.addConcurrencyDelta(compositeKey, -1) == 0 { + c.currentCallersVec.WithLabelValues(keyType).Dec() + } +} + +// Collect allows ConcurrencyTracker to adhere to the prometheus.Collector +// interface for collecting metrics. +func (c *ConcurrencyTracker) Collect(ch chan<- prometheus.Metric) { + c.currentCallersVec.Collect(ch) + c.totalCallersVec.Collect(ch) + c.concurrentProcessesVec.Collect(ch) +} + +// Describe allows ConcurrencyTracker to adhere to the prometheus.Collector +// interface for collecing metrics +func (c *ConcurrencyTracker) Describe(ch chan<- *prometheus.Desc) { + prometheus.DescribeByCollect(c, ch) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker_test.go new file mode 100644 index 0000000000..77f74ac58b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/concurrency_tracker_test.go @@ -0,0 +1,280 @@ +package hook + +import ( + "bytes" + "context" + "sync" + "testing" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestConcurrencyTracker(t *testing.T) { + testCases := []struct { + desc string + calls func(ctx context.Context, c *ConcurrencyTracker) + expectedLogData []logrus.Fields + }{ + { + desc: "single call", + calls: func(ctx context.Context, c *ConcurrencyTracker) { + finish := c.LogConcurrency(ctx, "repository", "a/b/c") + defer finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + defer finish() + }, + expectedLogData: []logrus.Fields{ + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 1, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 1, + }, + }, + }, + { + desc: "multiple calls", + calls: func(ctx context.Context, c *ConcurrencyTracker) { + finish := c.LogConcurrency(ctx, "repository", "a/b/c") + defer finish() + finish = c.LogConcurrency(ctx, "repository", "a/b/c") + defer finish() + finish = c.LogConcurrency(ctx, "repository", "a/b/c") + defer finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + defer finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + defer finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + defer finish() + }, + expectedLogData: []logrus.Fields{ + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 1, + }, + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 2, + }, + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 3, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 1, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 2, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 3, + }, + }, + }, + { + desc: "multiple finished calls", + calls: func(ctx context.Context, c *ConcurrencyTracker) { + finish := c.LogConcurrency(ctx, "repository", "a/b/c") + finish() + finish = c.LogConcurrency(ctx, "repository", "a/b/c") + finish() + finish = c.LogConcurrency(ctx, "repository", "a/b/c") + finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + finish() + finish = c.LogConcurrency(ctx, "user_id", "user-123") + finish() + }, + expectedLogData: []logrus.Fields{ + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 1, + }, + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 1, + }, + { + "concurrency_type": "repository", + "concurrency_key": "a/b/c", + "concurrency": 1, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 1, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 1, + }, + { + "concurrency_type": "user_id", + "concurrency_key": "user-123", + "concurrency": 1, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + + l, hook := test.NewNullLogger() + + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(l)) + + c := NewConcurrencyTracker() + + tc.calls(ctx, c) + + require.Len(t, hook.Entries, len(tc.expectedLogData)) + for i := 0; i < len(hook.Entries); i++ { + assert.Equal(t, tc.expectedLogData[i], hook.Entries[i].Data) + assert.Equal(t, "concurrency", hook.Entries[i].Message) + } + + assert.Len(t, c.concurrencyMap, 0) + }) + } +} + +func TestConcurrencyTrackerConcurrentCalls(t *testing.T) { + ctx := testhelper.Context(t) + + l, hook := test.NewNullLogger() + + ctx = ctxlogrus.ToContext(ctx, logrus.NewEntry(l)) + + c := NewConcurrencyTracker() + + var wg sync.WaitGroup + wg.Add(3) + + for i := 0; i < 3; i++ { + go func() { + defer wg.Done() + finish := c.LogConcurrency(ctx, "repository", "a/b/c") + defer finish() + }() + } + + wg.Wait() + + require.Len(t, hook.Entries, 3) + + for i := 0; i < len(hook.Entries); i++ { + assert.Equal(t, "a/b/c", hook.Entries[i].Data["concurrency_key"]) + assert.Equal(t, "repository", hook.Entries[i].Data["concurrency_type"]) + assert.Equal(t, "concurrency", hook.Entries[i].Message) + } + + assert.Len(t, c.concurrencyMap, 0) +} + +func TestConcurrencyTracker_metrics(t *testing.T) { + ctx := testhelper.Context(t) + + c := NewConcurrencyTracker() + + finish := c.LogConcurrency(ctx, "repository", "a") + finish() + c.LogConcurrency(ctx, "repository", "a") + c.LogConcurrency(ctx, "repository", "b") + c.LogConcurrency(ctx, "repository", "c") + + finish = c.LogConcurrency(ctx, "user_id", "user-1") + finish() + c.LogConcurrency(ctx, "user_id", "user-1") + c.LogConcurrency(ctx, "user_id", "user-2") + c.LogConcurrency(ctx, "user_id", "user-3") + c.LogConcurrency(ctx, "user_id", "user-4") + + expectedMetrics := `# HELP gitaly_pack_objects_concurrent_processes Number of concurrent processes +# TYPE gitaly_pack_objects_concurrent_processes histogram +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="0"} 0 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="5"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="10"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="15"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="20"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="25"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="30"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="35"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="40"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="45"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="50"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="55"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="60"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="65"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="70"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="75"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="80"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="85"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="90"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="95"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="+Inf"} 4 +gitaly_pack_objects_concurrent_processes_sum{segment="repository"} 4 +gitaly_pack_objects_concurrent_processes_count{segment="repository"} 4 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="0"} 0 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="5"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="10"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="15"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="20"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="25"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="30"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="35"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="40"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="45"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="50"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="55"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="60"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="65"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="70"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="75"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="80"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="85"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="90"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="95"} 5 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="+Inf"} 5 +gitaly_pack_objects_concurrent_processes_sum{segment="user_id"} 5 +gitaly_pack_objects_concurrent_processes_count{segment="user_id"} 5 +# HELP gitaly_pack_objects_process_active_callers Number of unique callers that have an active pack objects processes +# TYPE gitaly_pack_objects_process_active_callers gauge +gitaly_pack_objects_process_active_callers{segment="repository"} 3 +gitaly_pack_objects_process_active_callers{segment="user_id"} 4 +# HELP gitaly_pack_objects_process_active_callers_total Total unique callers that have initiated a pack objects processes +# TYPE gitaly_pack_objects_process_active_callers_total counter +gitaly_pack_objects_process_active_callers_total{segment="repository"} 4 +gitaly_pack_objects_process_active_callers_total{segment="user_id"} 5 +` + require.NoError(t, testutil.CollectAndCompare( + c, + bytes.NewBufferString(expectedMetrics), + )) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom.go index 5020f8530d..9db59adaeb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom.go @@ -6,13 +6,12 @@ import ( "fmt" "io" "os" - "os/exec" "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sys/unix" ) @@ -66,15 +65,18 @@ func (m *GitLabHookManager) newCustomHooksExecutor(repo *gitalypb.Repository, ho } for _, hookFile := range hookFiles { - cmd := exec.Command(hookFile, args...) - cmd.Dir = repoPath - c, err := command.New(ctx, cmd, bytes.NewReader(stdinBytes), stdout, stderr, env...) + c, err := command.New(ctx, append([]string{hookFile}, args...), + command.WithDir(repoPath), + command.WithStdin(bytes.NewReader(stdinBytes)), + command.WithStdout(stdout), + command.WithStderr(stderr), + command.WithEnvironment(env), + command.WithCommandName("gitaly-hooks", hookName), + ) if err != nil { return err } - c.SetMetricsSubCmd(hookName) - if err = c.Wait(); err != nil { // Custom hook errors need to be handled specially when we update // refs via updateref.UpdaterWithHooks: their stdout and stderr must @@ -193,9 +195,9 @@ func (m *GitLabHookManager) customHooksEnv(ctx context.Context, payload git.Hook "GIT_DIR="+repoPath, "GL_REPOSITORY="+payload.Repo.GetGlRepository(), "GL_PROJECT_PATH="+payload.Repo.GetGlProjectPath(), - "GL_ID="+payload.ReceiveHooksPayload.UserID, - "GL_USERNAME="+payload.ReceiveHooksPayload.Username, - "GL_PROTOCOL="+payload.ReceiveHooksPayload.Protocol, + "GL_ID="+payload.UserDetails.UserID, + "GL_USERNAME="+payload.UserDetails.Username, + "GL_PROTOCOL="+payload.UserDetails.Protocol, ), nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom_test.go index 34a6cfda03..494088fd6b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/custom_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/custom_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -11,12 +13,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // printAllScript is a bash script that prints out stdin, the arguments, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/disabled_manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/disabled_manager.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/disabled_manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/disabled_manager.go index f43fb0a5e4..ce74f1a9b3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/disabled_manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/disabled_manager.go @@ -4,7 +4,7 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // DisabledManager never executes hooks and simply returns a nil error. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager.go index c1b9d7c41e..b8d53654a3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager.go @@ -4,12 +4,12 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // ReferenceTransactionState is the state of the Git reference transaction. It reflects the first diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager_mock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager_mock.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager_mock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager_mock.go index 6db7973907..052c3a0920 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/manager_mock.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/manager_mock.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // MockManager mocks the Manager interface for Git hooks (e.g. pre-receive, post-receive) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive.go index 549ca3d1d9..2063b1adf9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive.go @@ -10,10 +10,10 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -116,7 +116,7 @@ func printAlert(m gitlab.PostReceiveMessage, w io.Writer) error { return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *GitLabHookManager) PostReceiveHook(ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, stdin io.Reader, stdout, stderr io.Writer) error { payload, err := git.HooksPayloadFromEnv(env) if err != nil { @@ -150,10 +150,10 @@ func (m *GitLabHookManager) postReceiveHook(ctx context.Context, payload git.Hoo return helper.ErrInternalf("hook got no reference updates") } - if payload.ReceiveHooksPayload == nil { + if payload.UserDetails == nil { return helper.ErrInternalf("payload has no receive hooks info") } - if payload.ReceiveHooksPayload.UserID == "" { + if payload.UserDetails.UserID == "" { return helper.ErrInternalf("user ID not set") } if repo.GetGlRepository() == "" { @@ -162,7 +162,7 @@ func (m *GitLabHookManager) postReceiveHook(ctx context.Context, payload git.Hoo ok, messages, err := m.gitlabClient.PostReceive( ctx, repo.GetGlRepository(), - payload.ReceiveHooksPayload.UserID, + payload.UserDetails.UserID, string(stdin), pushOptions..., ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive_test.go index 434f7b13c0..5fb125ad04 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/postreceive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/postreceive_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -10,19 +12,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestPrintAlert(t *testing.T) { @@ -75,7 +77,7 @@ func TestPostReceive_customHook(t *testing.T) { t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, )) - receiveHooksPayload := &git.ReceiveHooksPayload{ + receiveHooksPayload := &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", @@ -83,7 +85,7 @@ func TestPostReceive_customHook(t *testing.T) { ctx := testhelper.Context(t) - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PostReceiveHook, featureflag.RawFromContext(ctx)).Env() + payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PostReceiveHook, featureflag.FromContext(ctx)).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( @@ -94,7 +96,7 @@ func TestPostReceive_customHook(t *testing.T) { }, receiveHooksPayload, git.PostReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -106,7 +108,7 @@ func TestPostReceive_customHook(t *testing.T) { }, receiveHooksPayload, git.PostReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -240,7 +242,7 @@ func (m *postreceiveAPIMock) PostReceive(ctx context.Context, glRepository, glID func TestPostReceive_gitlab(t *testing.T) { cfg, repo, repoPath := testcfg.BuildWithRepo(t) - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.ReceiveHooksPayload{ + payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", @@ -381,18 +383,18 @@ func TestPostReceive_quarantine(t *testing.T) { } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { env, err := git.NewHooksPayload(cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) stdin := strings.NewReader(fmt.Sprintf("%s %s refs/heads/master", - git.ZeroOID, git.ZeroOID)) + git.ObjectHashSHA1.ZeroOID, git.ObjectHashSHA1.ZeroOID)) var stdout, stderr bytes.Buffer require.NoError(t, hookManager.PostReceiveHook(ctx, repo, nil, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive.go index 36e630818e..544800ff0d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive.go @@ -10,10 +10,10 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // NotAllowedError is needed to report internal API errors that @@ -113,13 +113,13 @@ func (m *GitLabHookManager) preReceiveHook(ctx context.Context, payload git.Hook if repo.GetGlRepository() == "" { return helper.ErrInternalf("repository not set") } - if payload.ReceiveHooksPayload == nil { + if payload.UserDetails == nil { return helper.ErrInternalf("payload has no receive hooks info") } - if payload.ReceiveHooksPayload.UserID == "" { + if payload.UserDetails.UserID == "" { return helper.ErrInternalf("user ID not set") } - if payload.ReceiveHooksPayload.Protocol == "" { + if payload.UserDetails.Protocol == "" { return helper.ErrInternalf("protocol not set") } @@ -128,8 +128,8 @@ func (m *GitLabHookManager) preReceiveHook(ctx context.Context, payload git.Hook GitObjectDirectory: repo.GitObjectDirectory, GitAlternateObjectDirectories: repo.GitAlternateObjectDirectories, GLRepository: repo.GetGlRepository(), - GLID: payload.ReceiveHooksPayload.UserID, - GLProtocol: payload.ReceiveHooksPayload.Protocol, + GLID: payload.UserDetails.UserID, + GLProtocol: payload.UserDetails.Protocol, Changes: string(changes), } @@ -137,14 +137,14 @@ func (m *GitLabHookManager) preReceiveHook(ctx context.Context, payload git.Hook if err != nil { // This logic is broken because we just return every potential error to the // caller, even though we cannot tell whether the error message stems from - // the API or if it is a generic error. Ideally, we'd be able to able to - // tell whether the error was a PermissionDenied error and only then return + // the API or if it is a generic error. Ideally, we'd be able to tell + // whether the error was a PermissionDenied error and only then return // the error message as GitLab message. But this will require upstream // changes in gitlab-shell first. return NotAllowedError{ Message: err.Error(), - UserID: payload.ReceiveHooksPayload.UserID, - Protocol: payload.ReceiveHooksPayload.Protocol, + UserID: payload.UserDetails.UserID, + Protocol: payload.UserDetails.Protocol, Changes: changes, } } @@ -154,8 +154,8 @@ func (m *GitLabHookManager) preReceiveHook(ctx context.Context, payload git.Hook if !allowed { return NotAllowedError{ Message: message, - UserID: payload.ReceiveHooksPayload.UserID, - Protocol: payload.ReceiveHooksPayload.Protocol, + UserID: payload.UserDetails.UserID, + Protocol: payload.UserDetails.Protocol, Changes: changes, } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive_test.go index a67a053c80..f7bd013257 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/prereceive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/prereceive_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -9,20 +11,20 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestPrereceive_customHooks(t *testing.T) { @@ -34,7 +36,7 @@ func TestPrereceive_customHooks(t *testing.T) { t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, )) - receiveHooksPayload := &git.ReceiveHooksPayload{ + receiveHooksPayload := &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", @@ -42,7 +44,7 @@ func TestPrereceive_customHooks(t *testing.T) { ctx := testhelper.Context(t) - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PreReceiveHook, featureflag.RawFromContext(ctx)).Env() + payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PreReceiveHook, featureflag.FromContext(ctx)).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( @@ -53,7 +55,7 @@ func TestPrereceive_customHooks(t *testing.T) { }, receiveHooksPayload, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -65,7 +67,7 @@ func TestPrereceive_customHooks(t *testing.T) { }, receiveHooksPayload, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -200,18 +202,18 @@ func TestPrereceive_quarantine(t *testing.T) { } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { env, err := git.NewHooksPayload(cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) stdin := strings.NewReader(fmt.Sprintf("%s %s refs/heads/master", - git.ZeroOID, git.ZeroOID)) + git.ObjectHashSHA1.ZeroOID, git.ObjectHashSHA1.ZeroOID)) var stdout, stderr bytes.Buffer require.NoError(t, hookManager.PreReceiveHook(ctx, repo, nil, @@ -252,7 +254,7 @@ func (m *prereceiveAPIMock) PostReceive(context.Context, string, string, string, func TestPrereceive_gitlab(t *testing.T) { cfg, repo, repoPath := testcfg.BuildWithRepo(t) - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.ReceiveHooksPayload{ + payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/referencetransaction.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/referencetransaction.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/referencetransaction.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/referencetransaction.go index bba8eaabe6..b7e76dceec 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/referencetransaction.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/referencetransaction.go @@ -8,15 +8,15 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) // forceDeletionPrefix is the prefix of a queued reference transaction which deletes a // reference without checking its current value. -var forceDeletionPrefix = fmt.Sprintf("%[1]s %[1]s ", git.ZeroOID.String()) +var forceDeletionPrefix = fmt.Sprintf("%[1]s %[1]s ", git.ObjectHashSHA1.ZeroOID.String()) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *GitLabHookManager) ReferenceTransactionHook(ctx context.Context, state ReferenceTransactionState, env []string, stdin io.Reader) error { payload, err := git.HooksPayloadFromEnv(env) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel.go index 54b945c115..62c32a0590 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel.go @@ -11,8 +11,8 @@ import ( "path/filepath" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - gitaly_metadata "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + gitaly_metadata "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel_test.go index 0ac677df68..243e0de099 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/sidechannel_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/sidechannel_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" grpc_metadata "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/testdata/.gitkeep b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/testdata/.gitkeep similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/testdata/.gitkeep rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/testdata/.gitkeep diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/testhelper_test.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/testhelper_test.go index 6232587f9f..683fb27908 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -10,20 +12,20 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestMain(m *testing.M) { testhelper.Run(m) } -func getExpectedEnv(ctx context.Context, t testing.TB, locator storage.Locator, gitCmdFactory git.CommandFactory, repo *gitalypb.Repository) []string { +func getExpectedEnv(ctx context.Context, tb testing.TB, locator storage.Locator, gitCmdFactory git.CommandFactory, repo *gitalypb.Repository) []string { repoPath, err := locator.GetPath(repo) - require.NoError(t, err) + require.NoError(tb, err) expectedEnv := map[string]string{ "GIT_DIR": repoPath, @@ -42,7 +44,7 @@ func getExpectedEnv(ctx context.Context, t testing.TB, locator storage.Locator, // we need to deduplicate environment variables here. for _, allowedEnvVar := range append(command.AllowedEnvironment(os.Environ()), execEnv.EnvironmentVariables...) { kv := strings.SplitN(allowedEnvVar, "=", 2) - require.Len(t, kv, 2) + require.Len(tb, kv, 2) expectedEnv[kv[0]] = kv[1] } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions.go index 33097b551c..439aa9b6c2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions.go @@ -3,9 +3,9 @@ package hook import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) func isPrimary(payload git.HooksPayload) bool { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions_test.go index 7f307a2e39..1000b84206 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/transactions_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/transactions_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -9,16 +11,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) func TestHookManager_stopCalled(t *testing.T) { @@ -39,13 +41,13 @@ func TestHookManager_stopCalled(t *testing.T) { cfg, repo, &expectedTx, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", }, git.ReferenceTransactionHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -58,7 +60,7 @@ func TestHookManager_stopCalled(t *testing.T) { return hookManager.PreReceiveHook(ctx, repo, nil, []string{hooksPayload}, strings.NewReader("changes"), io.Discard, io.Discard) } updateFunc := func(t *testing.T) error { - return hookManager.UpdateHook(ctx, repo, "ref", git.ZeroOID.String(), git.ZeroOID.String(), []string{hooksPayload}, io.Discard, io.Discard) + return hookManager.UpdateHook(ctx, repo, "ref", git.ObjectHashSHA1.ZeroOID.String(), git.ObjectHashSHA1.ZeroOID.String(), []string{hooksPayload}, io.Discard, io.Discard) } postReceiveFunc := func(t *testing.T) error { return hookManager.PostReceiveHook(ctx, repo, nil, []string{hooksPayload}, strings.NewReader("changes"), io.Discard, io.Discard) @@ -146,7 +148,7 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { require.NoError(t, err) ctx, cancel := context.WithCancel(testhelper.Context(t)) - changes := fmt.Sprintf("%s %s refs/heads/master", strings.Repeat("1", 40), git.ZeroOID) + changes := fmt.Sprintf("%s %s refs/heads/master", strings.Repeat("1", 40), git.ObjectHashSHA1.ZeroOID) cancel() @@ -156,7 +158,7 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { func TestIsForceDeletionsOnly(t *testing.T) { anyOID := strings.Repeat("1", 40) - zeroOID := git.ZeroOID.String() + zeroOID := git.ObjectHashSHA1.ZeroOID.String() forceDeletion := fmt.Sprintf("%s %s refs/heads/force-delete", zeroOID, zeroOID) forceUpdate := fmt.Sprintf("%s %s refs/heads/force-update", zeroOID, anyOID) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update.go index d8db702b3a..8574622f07 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update.go @@ -6,12 +6,12 @@ import ( "io" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *GitLabHookManager) UpdateHook(ctx context.Context, repo *gitalypb.Repository, ref, oldValue, newValue string, env []string, stdout, stderr io.Writer) error { payload, err := git.HooksPayloadFromEnv(env) if err != nil { @@ -39,13 +39,13 @@ func (m *GitLabHookManager) updateHook(ctx context.Context, payload git.HooksPay if ref == "" { return helper.ErrInternalf("hook got no reference") } - if err := git.ValidateObjectID(oldValue); err != nil { + if err := git.ObjectHashSHA1.ValidateHex(oldValue); err != nil { return helper.ErrInternalf("hook got invalid old value: %w", err) } - if err := git.ValidateObjectID(newValue); err != nil { + if err := git.ObjectHashSHA1.ValidateHex(newValue); err != nil { return helper.ErrInternalf("hook got invalid new value: %w", err) } - if payload.ReceiveHooksPayload == nil { + if payload.UserDetails == nil { return helper.ErrInternalf("payload has no receive hooks info") } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update_test.go index f51cb766d8..c5b47c76fe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook/update_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook/update_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -7,19 +9,19 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestUpdate_customHooks(t *testing.T) { @@ -31,7 +33,7 @@ func TestUpdate_customHooks(t *testing.T) { t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, )) - receiveHooksPayload := &git.ReceiveHooksPayload{ + receiveHooksPayload := &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", @@ -39,7 +41,7 @@ func TestUpdate_customHooks(t *testing.T) { ctx := testhelper.Context(t) - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.UpdateHook, featureflag.RawFromContext(ctx)).Env() + payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.UpdateHook, featureflag.FromContext(ctx)).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( @@ -50,7 +52,7 @@ func TestUpdate_customHooks(t *testing.T) { }, receiveHooksPayload, git.UpdateHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -62,7 +64,7 @@ func TestUpdate_customHooks(t *testing.T) { }, receiveHooksPayload, git.UpdateHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -231,19 +233,19 @@ func TestUpdate_quarantine(t *testing.T) { } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { env, err := git.NewHooksPayload(cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "1234", Username: "user", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) var stdout, stderr bytes.Buffer require.NoError(t, hookManager.UpdateHook(ctx, repo, "refs/heads/master", - git.ZeroOID.String(), git.ZeroOID.String(), []string{env}, &stdout, &stderr)) + git.ObjectHashSHA1.ZeroOID.String(), git.ObjectHashSHA1.ZeroOID.String(), []string{env}, &stdout, &stderr)) if isQuarantined { require.Equal(t, "allyourbasearebelongtous", stdout.String()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats.go new file mode 100644 index 0000000000..e65a90c9ae --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats.go @@ -0,0 +1,159 @@ +package linguist + +import ( + "compress/zlib" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" +) + +const ( + // languageStatsFilename is the name of the file in the repo that stores + // a cached version of the language statistics. The name is + // intentionally different from what the linguist gem uses. + languageStatsFilename = "gitaly-language.stats" + languageStatsVersion = "v2:gitaly" +) + +// languageStats takes care of accumulating and caching language statistics for +// a repository. +type languageStats struct { + // Version holds the file format version + Version string `json:"version"` + // CommitID holds the commit ID for the cached Totals + CommitID string `json:"commit_id"` + + // m will protect concurrent writes to Totals & ByFile maps + m sync.Mutex + + // Totals contains the total statistics for the CommitID + Totals ByteCountPerLanguage `json:"totals"` + // ByFile contains the statistics for a single file, where the filename + // is its key. + ByFile map[string]ByteCountPerLanguage `json:"by_file"` +} + +// newLanguageStats creates a languageStats object and tries to load the +// optionally available stats from file. +func newLanguageStats(repo *localrepo.Repo) (*languageStats, error) { + stats := languageStats{ + Totals: ByteCountPerLanguage{}, + ByFile: make(map[string]ByteCountPerLanguage), + } + + objPath, err := repo.Path() + if err != nil { + return &stats, fmt.Errorf("new language stats get repo path: %w", err) + } + + file, err := os.Open(filepath.Join(objPath, languageStatsFilename)) + if err != nil { + if os.IsNotExist(err) { + return &stats, nil + } + return &stats, fmt.Errorf("new language stats open: %w", err) + } + defer file.Close() + + r, err := zlib.NewReader(file) + if err != nil { + return &stats, fmt.Errorf("new language stats zlib reader: %w", err) + } + + var loaded languageStats + if err = json.NewDecoder(r).Decode(&loaded); err != nil { + return &stats, fmt.Errorf("new language stats json decode: %w", err) + } + + if loaded.Version != languageStatsVersion { + return &stats, fmt.Errorf("new language stats version mismatch %s vs %s", languageStatsVersion, loaded.Version) + } + + return &loaded, nil +} + +// add the statistics for the given filename +func (c *languageStats) add(filename, language string, size uint64) { + c.m.Lock() + defer c.m.Unlock() + + for k, v := range c.ByFile[filename] { + c.Totals[k] -= v + if c.Totals[k] <= 0 { + delete(c.Totals, k) + } + } + + c.ByFile[filename] = ByteCountPerLanguage{language: size} + if size > 0 { + c.Totals[language] += size + } +} + +// drop statistics for the given files +func (c *languageStats) drop(filenames ...string) { + c.m.Lock() + defer c.m.Unlock() + + for _, f := range filenames { + for k, v := range c.ByFile[f] { + c.Totals[k] -= v + if c.Totals[k] <= 0 { + delete(c.Totals, k) + } + } + delete(c.ByFile, f) + } +} + +// save the language stats to file in the repository +func (c *languageStats) save(repo *localrepo.Repo, commitID string) error { + c.CommitID = commitID + c.Version = languageStatsVersion + + repoPath, err := repo.Path() + if err != nil { + return fmt.Errorf("languageStats save get repo path: %w", err) + } + + tempPath, err := repo.StorageTempDir() + if err != nil { + return fmt.Errorf("languageStats locate temp dir: %w", err) + } + + file, err := os.CreateTemp(tempPath, languageStatsFilename) + if err != nil { + return fmt.Errorf("languageStats create temp file: %w", err) + } + defer func() { + file.Close() + _ = os.Remove(file.Name()) + }() + + w := zlib.NewWriter(file) + defer w.Close() + + if err = json.NewEncoder(w).Encode(c); err != nil { + return fmt.Errorf("languageStats encode json: %w", err) + } + + if err = w.Close(); err != nil { + return fmt.Errorf("languageStats zlib write: %w", err) + } + if err = file.Sync(); err != nil { + return fmt.Errorf("languageStats flush: %w", err) + } + if err = file.Close(); err != nil { + return fmt.Errorf("languageStats close: %w", err) + } + + if err = os.Rename(file.Name(), filepath.Join(repoPath, languageStatsFilename)); err != nil { + return fmt.Errorf("languageStats rename: %w", err) + } + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats_test.go new file mode 100644 index 0000000000..9199f6eb88 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/language_stats_test.go @@ -0,0 +1,254 @@ +//go:build !gitaly_test_sha256 + +package linguist + +import ( + "compress/zlib" + "encoding/json" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" +) + +func TestNewLanguageStats(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + for _, tc := range []struct { + desc string + run func(*testing.T, *localrepo.Repo, string) + }{ + { + desc: "non-existing cache", + run: func(t *testing.T, repo *localrepo.Repo, repoPath string) { + stats, err := newLanguageStats(repo) + require.NoError(t, err) + require.Empty(t, stats.Totals) + require.Empty(t, stats.ByFile) + }, + }, + { + desc: "pre-existing cache", + run: func(t *testing.T, repo *localrepo.Repo, repoPath string) { + stats, err := newLanguageStats(repo) + require.NoError(t, err) + + stats.Totals["C"] = 555 + require.NoError(t, stats.save(repo, "badcafe")) + + require.Equal(t, ByteCountPerLanguage{"C": 555}, stats.Totals) + }, + }, + { + desc: "corrupt cache", + run: func(t *testing.T, repo *localrepo.Repo, repoPath string) { + require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), 0o644)) + + stats, err := newLanguageStats(repo) + require.Errorf(t, err, "new language stats zlib reader: invalid header") + require.Empty(t, stats.Totals) + require.Empty(t, stats.ByFile) + }, + }, + { + desc: "incorrect version cache", + run: func(t *testing.T, repo *localrepo.Repo, repoPath string) { + stats, err := newLanguageStats(repo) + require.NoError(t, err) + + stats.Totals["C"] = 555 + stats.Version = "faulty" + + // Copy save() behavior, but with a faulty version + file, err := os.OpenFile(filepath.Join(repoPath, languageStatsFilename), os.O_WRONLY|os.O_CREATE, 0o755) + require.NoError(t, err) + w := zlib.NewWriter(file) + require.NoError(t, json.NewEncoder(w).Encode(stats)) + require.NoError(t, w.Close()) + require.NoError(t, file.Sync()) + require.NoError(t, file.Close()) + + newStats, err := newLanguageStats(repo) + require.Error(t, err, fmt.Errorf("new language stats version mismatch %s vs %s", languageStatsVersion, "faulty")) + require.Empty(t, newStats.Totals) + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + tc.run(t, repo, repoPath) + }) + } +} + +func TestLanguageStats_add(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + for _, tc := range []struct { + desc string + run func(*testing.T, *languageStats) + }{ + { + desc: "adds to the total", + run: func(t *testing.T, s *languageStats) { + s.add("main.go", "Go", 100) + + require.Equal(t, uint64(100), s.Totals["Go"]) + require.Len(t, s.ByFile, 1) + require.Equal(t, ByteCountPerLanguage{"Go": 100}, s.ByFile["main.go"]) + }, + }, + { + desc: "accumulates", + run: func(t *testing.T, s *languageStats) { + s.add("main.go", "Go", 100) + s.add("main_test.go", "Go", 80) + + require.Equal(t, uint64(180), s.Totals["Go"]) + require.Len(t, s.ByFile, 2) + require.Equal(t, ByteCountPerLanguage{"Go": 100}, s.ByFile["main.go"]) + require.Equal(t, ByteCountPerLanguage{"Go": 80}, s.ByFile["main_test.go"]) + }, + }, + { + desc: "languages don't interfere", + run: func(t *testing.T, s *languageStats) { + s.add("main.go", "Go", 60) + s.add("Makefile", "Make", 30) + + require.Equal(t, uint64(60), s.Totals["Go"]) + require.Equal(t, uint64(30), s.Totals["Make"]) + require.Len(t, s.ByFile, 2) + require.Equal(t, ByteCountPerLanguage{"Go": 60}, s.ByFile["main.go"]) + require.Equal(t, ByteCountPerLanguage{"Make": 30}, s.ByFile["Makefile"]) + }, + }, + { + desc: "updates the stat for a file", + run: func(t *testing.T, s *languageStats) { + s.add("main.go", "Go", 60) + s.add("main.go", "Go", 30) + + require.Equal(t, uint64(30), s.Totals["Go"]) + require.Len(t, s.ByFile, 1) + require.Equal(t, ByteCountPerLanguage{"Go": 30}, s.ByFile["main.go"]) + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + s, err := newLanguageStats(repo) + require.NoError(t, err) + + tc.run(t, s) + }) + } +} + +func TestLanguageStats_drop(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + for _, tc := range []struct { + desc string + run func(*testing.T, *languageStats) + }{ + { + desc: "existing file", + run: func(t *testing.T, s *languageStats) { + s.drop("main.go") + + require.Equal(t, uint64(20), s.Totals["Go"]) + require.Len(t, s.ByFile, 1) + require.Equal(t, ByteCountPerLanguage{"Go": 20}, s.ByFile["main_test.go"]) + }, + }, + { + desc: "non-existing file", + run: func(t *testing.T, s *languageStats) { + s.drop("foo.go") + + require.Equal(t, uint64(100), s.Totals["Go"]) + require.Len(t, s.ByFile, 2) + require.Equal(t, ByteCountPerLanguage{"Go": 80}, s.ByFile["main.go"]) + require.Equal(t, ByteCountPerLanguage{"Go": 20}, s.ByFile["main_test.go"]) + }, + }, + { + desc: "all files", + run: func(t *testing.T, s *languageStats) { + s.drop("main.go", "main_test.go") + + require.Empty(t, s.Totals) + require.Empty(t, s.ByFile) + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + s, err := newLanguageStats(repo) + require.NoError(t, err) + + s.Totals["Go"] = 100 + s.ByFile["main.go"] = ByteCountPerLanguage{"Go": 80} + s.ByFile["main_test.go"] = ByteCountPerLanguage{"Go": 20} + + tc.run(t, s) + }) + } +} + +func TestLanguageStats_save(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + s, err := newLanguageStats(repo) + require.NoError(t, err) + + s.Totals["Go"] = 100 + s.ByFile["main.go"] = ByteCountPerLanguage{"Go": 80} + s.ByFile["main_test.go"] = ByteCountPerLanguage{"Go": 20} + + err = s.save(repo, "buzz") + require.NoError(t, err) + require.FileExists(t, filepath.Join(repoPath, languageStatsFilename)) + + loaded, err := newLanguageStats(repo) + require.NoError(t, err) + + require.Equal(t, "buzz", loaded.CommitID) + require.Equal(t, languageStatsVersion, loaded.Version) + require.Equal(t, s.Totals, loaded.Totals) + require.Equal(t, s.ByFile, loaded.ByFile) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist.go new file mode 100644 index 0000000000..696f70a4f1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist.go @@ -0,0 +1,257 @@ +package linguist + +import ( + "context" + "crypto/sha256" + "encoding/json" + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + + "github.com/go-enry/go-enry/v2" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" +) + +// Language is used to parse Linguist's language.json file. +type Language struct { + Color string `json:"color"` +} + +// ByteCountPerLanguage represents a counter value (bytes) per language. +type ByteCountPerLanguage map[string]uint64 + +// Instance is a holder of the defined in the system language settings. +type Instance struct { + cfg config.Cfg + colorMap map[string]Language + gitCmdFactory git.CommandFactory +} + +// New loads the name->color map from the Linguist gem and returns initialised instance +// to use back to the caller or an error. +func New(cfg config.Cfg, gitCmdFactory git.CommandFactory) (*Instance, error) { + jsonReader, err := openLanguagesJSON(cfg) + if err != nil { + return nil, err + } + defer jsonReader.Close() + + var colorMap map[string]Language + if err := json.NewDecoder(jsonReader).Decode(&colorMap); err != nil { + return nil, err + } + + return &Instance{ + cfg: cfg, + gitCmdFactory: gitCmdFactory, + colorMap: colorMap, + }, nil +} + +// Stats returns the repository's language stats as reported by 'git-linguist'. +func (inst *Instance) Stats(ctx context.Context, repo *localrepo.Repo, commitID string, catfileCache catfile.Cache) (ByteCountPerLanguage, error) { + if featureflag.GoLanguageStats.IsEnabled(ctx) { + return inst.enryStats(ctx, repo, commitID, catfileCache) + } + + repoPath, err := repo.Path() + if err != nil { + return nil, fmt.Errorf("get repo path: %w", err) + } + + cmd, err := inst.startGitLinguist(ctx, repoPath, commitID) + if err != nil { + return nil, fmt.Errorf("starting linguist: %w", err) + } + + data, err := io.ReadAll(cmd) + if err != nil { + return nil, fmt.Errorf("reading linguist output: %w", err) + } + + if err := cmd.Wait(); err != nil { + return nil, fmt.Errorf("waiting for linguist: %w", err) + } + + stats := make(ByteCountPerLanguage) + if err := json.Unmarshal(data, &stats); err != nil { + return nil, fmt.Errorf("unmarshaling stats: %w", err) + } + + return stats, nil +} + +// Color returns the color Linguist has assigned to language. +func (inst *Instance) Color(language string) string { + if color := inst.colorMap[language].Color; color != "" { + return color + } + + colorSha := sha256.Sum256([]byte(language)) + return fmt.Sprintf("#%x", colorSha[0:3]) +} + +func (inst *Instance) startGitLinguist(ctx context.Context, repoPath string, commitID string) (*command.Command, error) { + bundle, err := exec.LookPath("bundle") + if err != nil { + return nil, fmt.Errorf("finding bundle executable: %w", err) + } + + cmd := []string{bundle, "exec", "bin/gitaly-linguist", "--repository=" + repoPath, "--commit=" + commitID} + + internalCmd, err := command.New(ctx, cmd, + command.WithDir(inst.cfg.Ruby.Dir), + command.WithEnvironment(env.AllowedRubyEnvironment(os.Environ())), + command.WithCommandName("git-linguist", "stats"), + ) + if err != nil { + return nil, fmt.Errorf("creating command: %w", err) + } + + return internalCmd, nil +} + +func openLanguagesJSON(cfg config.Cfg) (io.ReadCloser, error) { + if jsonPath := cfg.Ruby.LinguistLanguagesPath; jsonPath != "" { + // This is a fallback for environments where dynamic discovery of the + // linguist path via Bundler is not working for some reason, for example + // https://gitlab.com/gitlab-org/gitaly/issues/1119. + return os.Open(jsonPath) + } + + linguistPathSymlink, err := os.CreateTemp("", "gitaly-linguist-path") + if err != nil { + return nil, err + } + defer func() { _ = os.Remove(linguistPathSymlink.Name()) }() + + if err := linguistPathSymlink.Close(); err != nil { + return nil, err + } + + // We use a symlink because we cannot trust Bundler to not print garbage + // on its stdout. + rubyScript := `FileUtils.ln_sf(Bundler.rubygems.find_name('github-linguist').first.full_gem_path, ARGV.first)` + cmd := exec.Command("bundle", "exec", "ruby", "-rfileutils", "-e", rubyScript, linguistPathSymlink.Name()) + cmd.Dir = cfg.Ruby.Dir + + // We have learned that in practice the command we are about to run is a + // canary for Ruby/Bundler configuration problems. Including stderr and + // stdout in the gitaly log is useful for debugging such problems. + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + + if err := cmd.Run(); err != nil { + if exitError, ok := err.(*exec.ExitError); ok { + err = fmt.Errorf("%v; stderr: %q", exitError, exitError.Stderr) + } + return nil, err + } + + return os.Open(filepath.Join(linguistPathSymlink.Name(), "lib", "linguist", "languages.json")) +} + +func (inst *Instance) enryStats(ctx context.Context, repo *localrepo.Repo, commitID string, catfileCache catfile.Cache) (ByteCountPerLanguage, error) { + stats, err := newLanguageStats(repo) + if err != nil { + ctxlogrus.Extract(ctx).WithError(err).Info("linguist load from cache") + } + if stats.CommitID == commitID { + return stats.Totals, nil + } + + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) + if err != nil { + return nil, fmt.Errorf("create object reader: %w", err) + } + defer cancel() + + var revlistIt gitpipe.RevisionIterator + + if stats.CommitID == "" { + // No existing stats cached, so get all the files for the commit + // using git-ls-tree(1). + revlistIt = gitpipe.LsTree(ctx, repo, + commitID, + gitpipe.LsTreeWithRecursive(), + gitpipe.LsTreeWithBlobFilter(), + ) + } else { + // Stats are cached for one commit, so get the git-diff-tree(1) + // between that commit and the one we're calculating stats for. + + skipDeleted := func(result *gitpipe.RevisionResult) bool { + // Skip files that are deleted. + if git.ObjectHashSHA1.IsZeroOID(result.OID) { + // It's a little bit of a hack to use this skip + // function, but for every file that's deleted, + // remove the stats. + stats.drop(string(result.ObjectName)) + return true + } + return false + } + + revlistIt = gitpipe.DiffTree(ctx, repo, + stats.CommitID, commitID, + gitpipe.DiffTreeWithRecursive(), + gitpipe.DiffTreeWithIgnoreSubmodules(), + gitpipe.DiffTreeWithSkip(skipDeleted), + ) + } + + objectIt, err := gitpipe.CatfileObject(ctx, objectReader, revlistIt) + if err != nil { + return nil, fmt.Errorf("linguist gitpipe: %w", err) + } + + for objectIt.Next() { + object := objectIt.Result() + filename := string(object.ObjectName) + + // Read arbitrary number of bytes considered enough to determine language + content, err := io.ReadAll(io.LimitReader(object, 2048)) + if err != nil { + return nil, fmt.Errorf("linguist read blob: %w", err) + } + + if _, err := io.Copy(io.Discard, object); err != nil { + return nil, fmt.Errorf("linguist discard excess blob: %w", err) + } + + lang := enry.GetLanguage(filename, content) + + // Ignore anything that's neither markup nor a programming language, + // similar to what the linguist gem does: + // https://github.com/github/linguist/blob/v7.20.0/lib/linguist/blob_helper.rb#L378-L387 + if enry.GetLanguageType(lang) != enry.Programming && + enry.GetLanguageType(lang) != enry.Markup { + // The file might have been included in the stats before + stats.drop(filename) + + continue + } + + stats.add(filename, lang, uint64(object.Object.ObjectSize())) + } + + if err := objectIt.Err(); err != nil { + return nil, fmt.Errorf("linguist object iterator: %w", err) + } + + if err := stats.save(repo, commitID); err != nil { + return nil, fmt.Errorf("linguist language stats save: %w", err) + } + + return stats.Totals, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist_test.go new file mode 100644 index 0000000000..c74152d004 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/linguist_test.go @@ -0,0 +1,375 @@ +//go:build !gitaly_test_sha256 + +package linguist + +import ( + "context" + "encoding/json" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/go-enry/go-enry/v2" + enrydata "github.com/go-enry/go-enry/v2/data" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +// TestNew_knownLanguages tests the compatibility between the Ruby and the Go +// implementation. This test will be removed together with the Ruby implementation. +func TestNew_knownLanguages(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t, testcfg.WithRealLinguist()) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + + linguist, err := New(cfg, gitCmdFactory) + require.NoError(t, err) + + t.Run("by name", func(t *testing.T) { + linguistLanguages := make([]string, 0, len(linguist.colorMap)) + for language := range linguist.colorMap { + linguistLanguages = append(linguistLanguages, language) + } + + enryLanguages := make([]string, 0, len(enrydata.IDByLanguage)) + for language := range enrydata.IDByLanguage { + enryLanguages = append(enryLanguages, language) + } + + require.ElementsMatch(t, linguistLanguages, enryLanguages) + }) + + t.Run("with their color", func(t *testing.T) { + exclude := map[string]struct{}{} + + linguistLanguages := make(map[string]string, len(linguist.colorMap)) + for language, color := range linguist.colorMap { + if color.Color == "" { + exclude[language] = struct{}{} + continue + } + linguistLanguages[language] = color.Color + } + + enryLanguages := make(map[string]string, len(enrydata.IDByLanguage)) + for language := range enrydata.IDByLanguage { + if _, excluded := exclude[language]; excluded { + continue + } + + color := enry.GetColor(language) + enryLanguages[language] = color + } + + require.Equal(t, linguistLanguages, enryLanguages) + }) +} + +func TestInstance_Stats(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testInstanceStats) +} + +func testInstanceStats(t *testing.T, ctx context.Context) { + cfg := testcfg.Build(t) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + + linguist, err := New(cfg, gitCmdFactory) + require.NoError(t, err) + + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + + languageStatsFilename := filenameForCache(ctx) + + for _, tc := range []struct { + desc string + setup func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) + expectedStats ByteCountPerLanguage + expectedErr string + }{ + { + desc: "successful", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "webpack.coffee", Mode: "100644", Content: strings.Repeat("a", 107)}, + gittest.TreeEntry{Path: "show_user.html", Mode: "100644", Content: strings.Repeat("a", 349)}, + gittest.TreeEntry{Path: "api.javascript", Mode: "100644", Content: strings.Repeat("a", 1014)}, + gittest.TreeEntry{Path: "application.rb", Mode: "100644", Content: strings.Repeat("a", 2943)}, + )) + + return repoProto, repoPath, commitID + }, + expectedStats: ByteCountPerLanguage{ + "CoffeeScript": 107, + "HTML": 349, + "JavaScript": 1014, + "Ruby": 2943, + }, + }, + { + desc: "empty code files", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + emptyBlob := gittest.WriteBlob(t, cfg, repoPath, []byte{}) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "Hello world!"}, + gittest.TreeEntry{Path: "index.html", Mode: "100644", OID: emptyBlob}, + gittest.TreeEntry{Path: "app.js", Mode: "100644", OID: emptyBlob}, + )) + + return repoProto, repoPath, commitID + }, + expectedStats: ByteCountPerLanguage{}, + }, + { + desc: "preexisting cache", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "webpack.coffee", Mode: "100644", Content: strings.Repeat("a", 107)}, + gittest.TreeEntry{Path: "show_user.html", Mode: "100644", Content: strings.Repeat("a", 349)}, + gittest.TreeEntry{Path: "api.javascript", Mode: "100644", Content: strings.Repeat("a", 1014)}, + gittest.TreeEntry{Path: "application.rb", Mode: "100644", Content: strings.Repeat("a", 2943)}, + )) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + // We simply run the linguist once before so that it can already + // write the cache. + _, err := linguist.Stats(ctx, repo, commitID.String(), catfileCache) + require.NoError(t, err) + require.FileExists(t, filepath.Join(repoPath, languageStatsFilename)) + + // Make sure it isn't able to generate stats from scratch + require.NoError(t, os.RemoveAll(filepath.Join(repoPath, "objects", "pack"))) + + return repoProto, repoPath, commitID + }, + expectedStats: ByteCountPerLanguage{ + "CoffeeScript": 107, + "HTML": 349, + "JavaScript": 1014, + "Ruby": 2943, + }, + }, + { + desc: "corrupted cache", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "webpack.coffee", Mode: "100644", Content: strings.Repeat("a", 107)}, + gittest.TreeEntry{Path: "show_user.html", Mode: "100644", Content: strings.Repeat("a", 349)}, + gittest.TreeEntry{Path: "api.javascript", Mode: "100644", Content: strings.Repeat("a", 1014)}, + gittest.TreeEntry{Path: "application.rb", Mode: "100644", Content: strings.Repeat("a", 2943)}, + )) + + require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), 0o644)) + + return repoProto, repoPath, commitID + }, + expectedStats: ByteCountPerLanguage{ + "CoffeeScript": 107, + "HTML": 349, + "JavaScript": 1014, + "Ruby": 2943, + }, + }, + { + desc: "old cache", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + oldCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "main.rb", Content: "require 'fileutils'", Mode: "100644"}, + )) + newCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(oldCommitID), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "main.go", Content: "package main", Mode: "100644"}, + )) + + // Precreate the cache with the old commit. This ensures that + // linguist knows to update the cache. + stats, err := linguist.Stats(ctx, repo, oldCommitID.String(), catfileCache) + require.NoError(t, err) + require.FileExists(t, filepath.Join(repoPath, languageStatsFilename)) + require.Equal(t, ByteCountPerLanguage{ + "Ruby": 19, + }, stats) + + return repoProto, repoPath, newCommitID + }, + expectedStats: ByteCountPerLanguage{ + "Go": 12, + }, + }, + { + desc: "missing repository", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoPath := filepath.Join(testhelper.TempDir(t), "nonexistent") + repoProto := &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "nonexistent"} + + return repoProto, repoPath, git.ObjectID("b1bb1d1b0b1d1b00") + }, + expectedErr: "GetRepoPath: not a git repository", + }, + { + desc: "missing commit", + setup: func(t *testing.T) (*gitalypb.Repository, string, git.ObjectID) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + return repoProto, repoPath, git.ObjectID("b1bb1d1b0b1d1b00") + }, + expectedErr: "linguist", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath, objectID := tc.setup(t) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + stats, err := linguist.Stats(ctx, repo, objectID.String(), catfileCache) + if tc.expectedErr == "" { + require.NoError(t, err) + require.Equal(t, tc.expectedStats, stats) + require.FileExists(t, filepath.Join(repoPath, languageStatsFilename)) + } else { + require.Contains(t, err.Error(), tc.expectedErr) + } + }) + } +} + +func TestInstance_Stats_unmarshalJSONError(t *testing.T) { + cfg := testcfg.Build(t) + ctx := featureflag.ContextWithFeatureFlag(testhelper.Context(t), featureflag.GoLanguageStats, false) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} + + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + + repo := localrepo.New(config.NewLocator(cfg), gitCmdFactory, catfileCache, invalidRepo) + + ling, err := New(cfg, gitCmdFactory) + require.NoError(t, err) + + // When an error occurs, this used to trigger JSON marshaling of a plain string + // the new behaviour shouldn't do that, and return a command error + _, err = ling.Stats(ctx, repo, "deadbeef", catfileCache) + require.Error(t, err) + + _, ok := err.(*json.SyntaxError) + require.False(t, ok, "expected the error not be a json Syntax Error") +} + +func TestNew(t *testing.T) { + cfg := testcfg.Build(t, testcfg.WithRealLinguist()) + + ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) + require.NoError(t, err) + + require.Equal(t, "#701516", ling.Color("Ruby"), "color value for 'Ruby'") +} + +func TestNew_loadLanguagesCustomPath(t *testing.T) { + jsonPath, err := filepath.Abs("testdata/fake-languages.json") + require.NoError(t, err) + + cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{Ruby: config.Ruby{LinguistLanguagesPath: jsonPath}})) + + ling, err := New(cfg, gittest.NewCommandFactory(t, cfg)) + require.NoError(t, err) + + require.Equal(t, "foo color", ling.Color("FooBar")) +} + +// filenameForCache returns the filename where the cache is stored, depending on +// the feature flag. +func filenameForCache(ctx context.Context) string { + if featureflag.GoLanguageStats.IsDisabled(ctx) { + return "language-stats.cache" + } + return languageStatsFilename +} + +func BenchmarkInstance_Stats(b *testing.B) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Bench(b, benchmarkInstanceStats) +} + +func benchmarkInstanceStats(b *testing.B, ctx context.Context) { + cfg := testcfg.Build(b) + gitCmdFactory := gittest.NewCommandFactory(b, cfg) + languageStatsFilename := filenameForCache(ctx) + + linguist, err := New(cfg, gitCmdFactory) + require.NoError(b, err) + + catfileCache := catfile.NewCache(cfg) + b.Cleanup(catfileCache.Stop) + + repoProto, repoPath := gittest.CreateRepository(ctx, b, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: "benchmark.git", + }) + repo := localrepo.NewTestRepo(b, cfg, repoProto) + + var scratchStat ByteCountPerLanguage + var incStats ByteCountPerLanguage + + b.Run("from scratch", func(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + require.NoError(b, os.RemoveAll(filepath.Join(repoPath, languageStatsFilename))) + b.StartTimer() + + scratchStat, err = linguist.Stats(ctx, repo, "f5dfdd0057cd6bffc6259a5c8533dde5bf6a9d37", catfileCache) + require.NoError(b, err) + } + }) + + b.Run("incremental", func(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + require.NoError(b, os.RemoveAll(filepath.Join(repoPath, languageStatsFilename))) + // a commit about 3 months older than the next + _, err = linguist.Stats(ctx, repo, "3c813b292d25a9b2ffda70e7f609f623bfc0cb37", catfileCache) + b.StartTimer() + + incStats, err = linguist.Stats(ctx, repo, "f5dfdd0057cd6bffc6259a5c8533dde5bf6a9d37", catfileCache) + require.NoError(b, err) + } + }) + + require.Equal(b, scratchStat, incStats) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/testdata/fake-languages.json b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/testdata/fake-languages.json similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist/testdata/fake-languages.json rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist/testdata/fake-languages.json diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily.go index 492bcfae36..c99eeb5475 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily.go @@ -5,8 +5,8 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" ) // StoragesJob runs a job on storages. The string slice param indicates which @@ -55,7 +55,7 @@ func (dw DailyWorker) StartDaily(ctx context.Context, l logrus.FieldLogger, sche case <-ctx.Done(): return ctx.Err() case start = <-dw.timer(nt.Sub(dw.clock())): - l.WithField("max_duration", schedule.Duration.Duration()). + l.WithField("max_duration", schedule.Duration). Info("maintenance: daily starting") } @@ -68,7 +68,7 @@ func (dw DailyWorker) StartDaily(ctx context.Context, l logrus.FieldLogger, sche }) l.WithError(jobErr). - WithField("max_duration", schedule.Duration.Duration()). + WithField("max_duration", schedule.Duration). WithField("actual_duration", time.Since(start)). Info("maintenance: daily completed") } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily_test.go index 97cd411b10..689052e67c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/daily_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/daily_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package maintenance import ( @@ -7,8 +9,9 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestStartDaily(t *testing.T) { @@ -35,7 +38,7 @@ func TestStartDaily(t *testing.T) { errQ := make(chan error) s := config.DailyJob{ Hour: 1, - Duration: config.Duration(time.Hour), + Duration: duration.Duration(time.Hour), Storages: []string{"meow"}, } ctx, cancel := context.WithCancel(testhelper.Context(t)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/main_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/main_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/main_test.go index 2cf16c9b66..c3fa08ae7a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/main_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/main_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package maintenance import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize.go index 647a597ade..a692613d8d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize.go @@ -11,11 +11,11 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // WorkerFunc is a function that does a unit of work meant to run in the background @@ -116,8 +116,7 @@ func optimizeRepoAtPath(ctx context.Context, l logrus.FieldLogger, s config.Stor "start_time": start.UTC(), }) - ctx, cancel := context.WithTimeout(ctxlogrus.ToContext(ctx, logEntry), 5*time.Minute) - defer cancel() + ctx = ctxlogrus.ToContext(ctx, logEntry) err = o.OptimizeRepository(ctx, repo) logEntry = logEntry.WithField("time_ms", time.Since(start).Milliseconds()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize_test.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize_test.go index 4b7f1efd74..754c94f461 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/optimize_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/optimize_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package maintenance import ( @@ -5,22 +7,20 @@ import ( "math/rand" "path/filepath" "testing" - "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - repo "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + repo "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type mockOptimizer struct { @@ -110,39 +110,3 @@ func TestOptimizeReposRandomly(t *testing.T) { }) } } - -type mockOptimizerCancel struct { - t *testing.T - startedAt time.Time -} - -func (m mockOptimizerCancel) OptimizeRepository(ctx context.Context, _ repo.GitRepo) error { - timeline, ok := ctx.Deadline() - if assert.True(m.t, ok) { - assert.True(m.t, timeline.After(m.startedAt), m.startedAt) - future := m.startedAt.Add(10 * time.Minute) - assert.True(m.t, timeline.Before(future), future) - } - return nil -} - -func TestOptimizeReposRandomly_cancellationOverride(t *testing.T) { - cfgBuilder := testcfg.NewGitalyCfgBuilder() - cfg := cfgBuilder.Build(t) - - gittest.InitRepo(t, cfg, cfg.Storages[0]) - ctx := testhelper.Context(t) - - // The timeout should be overwritten by the default 5 min timeout. - //nolint:forbidigo // We're explicitly testing deadline override. - ctx, cancel := context.WithTimeout(ctx, 72*time.Hour) - defer cancel() - - ticker := helper.NewManualTicker() - ticker.Tick() - - mo := &mockOptimizerCancel{t: t, startedAt: time.Now()} - walker := OptimizeReposRandomly(cfg.Storages, mo, ticker, rand.New(rand.NewSource(1))) - - require.NoError(t, walker(ctx, testhelper.NewDiscardingLogEntry(t), []string{cfg.Storages[0].Name})) -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/randomwalker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/randomwalker.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/randomwalker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/randomwalker.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/randomwalker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/randomwalker_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/randomwalker_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/randomwalker_test.go index 5db523dc38..7e3dc8c0ad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/maintenance/randomwalker_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/maintenance/randomwalker_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package maintenance import ( @@ -7,7 +9,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestRandomWalk(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/balancer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/balancer.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/balancer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/balancer.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/balancer_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/balancer_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/balancer_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/balancer_test.go index baf7b9286a..239e9502e9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/balancer_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/balancer_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package balancer import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/pool.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer/pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer/pool.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/concurrency_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/concurrency_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/concurrency_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/concurrency_test.go index 0531a40737..af6bd5c58c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/concurrency_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/concurrency_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package rubyserver import ( @@ -7,9 +9,9 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "google.golang.org/grpc/codes" healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" @@ -78,8 +80,8 @@ func BenchmarkConcurrency(b *testing.B) { }) } -func makeRequest(t testing.TB, s *Server) error { - ctx := testhelper.Context(t) +func makeRequest(tb testing.TB, s *Server) error { + ctx := testhelper.Context(tb) conn, err := s.getConnection(ctx) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health.go index cf12a8e634..2802487c54 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health.go @@ -7,13 +7,14 @@ import ( "time" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) func ping(address string) error { conn, err := grpc.Dial( address, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), // Use a custom dialer to ensure that we don't experience // issues in environments that have proxy configurations // https://gitlab.com/gitlab-org/gitaly/merge_requests/1072#note_140408512 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health_test.go index da76dfeb48..4d887c877c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/health_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/health_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package rubyserver import ( @@ -5,8 +7,8 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestPingSuccess(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy.go index 9b20febec7..cab76e9ef6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy.go @@ -6,9 +6,9 @@ import ( "os" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy_test.go index 6e55d6c28b..0c11f56c66 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/proxy_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/proxy_test.go @@ -1,12 +1,14 @@ +//go:build !gitaly_test_sha256 + package rubyserver import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver.go index c64f183ab8..76c901a84d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/rubyserver.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver.go @@ -12,19 +12,20 @@ import ( grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - "gitlab.com/gitlab-org/gitaly/v14/internal/supervisor" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/supervisor" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) // ConnectTimeout is the timeout for establishing a connection to the gitaly-ruby process. @@ -37,16 +38,18 @@ func init() { } } -func setupEnv(cfg config.Cfg, gitCmdFactory git.CommandFactory) []string { +func setupEnv(cfg config.Cfg, gitCmdFactory git.CommandFactory) ([]string, error) { // Ideally, we'd pass in the RPC context to the Git command factory such that we can // properly use feature flags to switch between different execution environments. But the // Ruby server is precreated and thus cannot use feature flags here. So for now, we have to // live with the fact that we cannot use feature flags for it. - gitExecEnv := gitCmdFactory.GetExecutionEnvironment(context.TODO()) - // The same remark exists with our hooks path. - hooksPath := gitCmdFactory.HooksPath(context.TODO()) + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() - env := append( + gitExecEnv := gitCmdFactory.GetExecutionEnvironment(ctx) + hooksPath := gitCmdFactory.HooksPath(ctx) + + environment := append( command.AllowedEnvironment(os.Environ()), "GITALY_LOG_DIR="+cfg.Logging.Dir, "GITALY_RUBY_GIT_BIN_PATH="+gitExecEnv.BinaryPath, @@ -55,32 +58,28 @@ func setupEnv(cfg config.Cfg, gitCmdFactory git.CommandFactory) []string { "GITALY_RUBY_GITALY_BIN_DIR="+cfg.BinDir, "GITALY_VERSION="+version.GetVersion(), "GITALY_GIT_HOOKS_DIR="+hooksPath, - "GITALY_SOCKET="+cfg.GitalyInternalSocketPath(), + "GITALY_SOCKET="+cfg.InternalSocketPath(), "GITALY_TOKEN="+cfg.Auth.Token, "GITALY_RUGGED_GIT_CONFIG_SEARCH_PATH="+cfg.Ruby.RuggedGitConfigSearchPath, ) - env = append(env, command.GitEnv...) - env = append(env, gitExecEnv.EnvironmentVariables...) - env = appendEnvIfSet(env, "BUNDLE_PATH") - env = appendEnvIfSet(env, "BUNDLE_USER_CONFIG") - env = appendEnvIfSet(env, "GEM_HOME") + environment = append(environment, gitExecEnv.EnvironmentVariables...) + environment = append(environment, env.AllowedRubyEnvironment(os.Environ())...) + + gitConfig, err := gitCmdFactory.SidecarGitConfiguration(ctx) + if err != nil { + return nil, fmt.Errorf("getting Git configuration: %w", err) + } + environment = append(environment, git.ConfigPairsToGitEnvironment(gitConfig)...) if dsn := cfg.Logging.RubySentryDSN; dsn != "" { - env = append(env, "SENTRY_DSN="+dsn) + environment = append(environment, "SENTRY_DSN="+dsn) } if sentryEnvironment := cfg.Logging.Sentry.Environment; sentryEnvironment != "" { - env = append(env, "SENTRY_ENVIRONMENT="+sentryEnvironment) + environment = append(environment, "SENTRY_ENVIRONMENT="+sentryEnvironment) } - return env -} - -func appendEnvIfSet(envvars []string, key string) []string { - if value, ok := os.LookupEnv(key); ok { - envvars = append(envvars, fmt.Sprintf("%s=%s", key, value)) - } - return envvars + return environment, nil } // Server represents a gitaly-ruby helper process. @@ -92,6 +91,7 @@ type Server struct { workers []*worker clientConnMu sync.Mutex clientConn *grpc.ClientConn + gitconfigDir string } // New returns a new instance of the server. @@ -109,8 +109,12 @@ func (s *Server) Stop() { } for _, w := range s.workers { - w.stopMonitor() w.Process.Stop() + w.stopMonitor() + } + + if s.gitconfigDir != "" { + _ = os.RemoveAll(s.gitconfigDir) } } } @@ -128,7 +132,47 @@ func (s *Server) start() error { } cfg := s.cfg - env := setupEnv(cfg, s.gitCmdFactory) + + // Both Omnibus and CNG set up the gitconfig in a non-default location. This means that they + // need to tell us where to find it, which is done via the Rugged config search path. In + // fact though, this configuration really only contains a single entry that is of importance + // to us in the context of Rugged, which is `core.fsyncObjectFiles`: if not set, then we may + // fail to persist objects correctly and thus corrupt the repository. We don't care about + // anything else nowadays anymore because most of the functionality was stripped out of the + // sidecar. + // + // Because we only care about a single option, and because that option is in fact mandatory + // or we may end up with corrupted data, we want to get rid of this configuration. Rugged + // doesn't give us any way to force-enable fsyncing though except if we write it to a file. + // Consequentially, we'll have to inject our own gitconfig into Rugged that enables this + // config. And that's exactly what the following block does: if we detect that the distro + // isn't telling us where to find the Rugged configuration, we write our own config. This is + // required so that we can phase out support of the gitconfig in these distributions. + // + // This is transitory until either the sidecar goes away or the upstream pull request is + // released (https://github.com/libgit2/rugged/pull/918). + if cfg.Ruby.RuggedGitConfigSearchPath == "" { + gitconfigDir := filepath.Join(cfg.RuntimeDir, "ruby-gitconfig") + if err := os.Mkdir(gitconfigDir, 0o777); err != nil { + return fmt.Errorf("creating gitconfig dir: %w", err) + } + + // This file must be called `gitconfig` given that we pretend it's the system-level + // Git configuration. Otherwise, Rugged wouldn't find it. + if err := os.WriteFile(filepath.Join(gitconfigDir, "gitconfig"), []byte( + "[core]\n\tfsyncObjectFiles = true\n", + ), 0o666); err != nil { + return fmt.Errorf("writing gitconfig: %w", err) + } + + cfg.Ruby.RuggedGitConfigSearchPath = gitconfigDir + s.gitconfigDir = gitconfigDir + } + + env, err := setupEnv(cfg, s.gitCmdFactory) + if err != nil { + return fmt.Errorf("setting up sidecar environment: %w", err) + } gitalyRuby := filepath.Join(cfg.Ruby.Dir, "bin", "gitaly-ruby") @@ -142,7 +186,7 @@ func (s *Server) start() error { for i := 0; i < numWorkers; i++ { name := fmt.Sprintf("gitaly-ruby.%d", i) - socketPath := filepath.Join(cfg.InternalSocketDir, fmt.Sprintf("ruby.%d", i)) + socketPath := filepath.Join(cfg.InternalSocketDir(), fmt.Sprintf("ruby.%d", i)) // Use 'ruby-cd' to make sure gitaly-ruby has the same working directory // as the current process. This is a hack to sort-of support relative @@ -263,7 +307,7 @@ func (s *Server) createConnection(ctx context.Context) (*grpc.ClientConn, error) func dialOptions() []grpc.DialOption { return []grpc.DialOption{ grpc.WithBlock(), // With this we get retries. Without, connections fail fast. - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), // Use a custom dialer to ensure that we don't experience // issues in environments that have proxy configurations // https://gitlab.com/gitlab-org/gitaly/merge_requests/1072#note_140408512 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver_test.go new file mode 100644 index 0000000000..cf35f75382 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/rubyserver_test.go @@ -0,0 +1,229 @@ +//go:build !gitaly_test_sha256 + +package rubyserver + +import ( + "context" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" + "google.golang.org/grpc/codes" +) + +func TestStopSafe(t *testing.T) { + badServers := []*Server{ + nil, + New(config.Cfg{}, nil), + } + + for _, bs := range badServers { + bs.Stop() + } +} + +func TestSetHeaders(t *testing.T) { + cfg, repo, _ := testcfg.BuildWithRepo(t) + ctx := testhelper.Context(t) + + locator := config.NewLocator(cfg) + + testCases := []struct { + desc string + repo *gitalypb.Repository + errType codes.Code + setter func(context.Context, storage.Locator, *gitalypb.Repository) (context.Context, error) + }{ + { + desc: "SetHeaders invalid storage", + repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, + errType: codes.InvalidArgument, + setter: SetHeaders, + }, + { + desc: "SetHeaders invalid rel path", + repo: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "bar.git"}, + errType: codes.NotFound, + setter: SetHeaders, + }, + { + desc: "SetHeaders OK", + repo: repo, + errType: codes.OK, + setter: SetHeaders, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + clientCtx, err := tc.setter(ctx, locator, tc.repo) + + if tc.errType != codes.OK { + testhelper.RequireGrpcCode(t, err, tc.errType) + assert.Nil(t, clientCtx) + } else { + assert.NoError(t, err) + assert.NotNil(t, clientCtx) + } + }) + } +} + +type mockGitCommandFactory struct { + git.CommandFactory +} + +func (mockGitCommandFactory) GetExecutionEnvironment(context.Context) git.ExecutionEnvironment { + return git.ExecutionEnvironment{ + BinaryPath: "/something", + EnvironmentVariables: []string{ + "FOO=bar", + }, + } +} + +func (mockGitCommandFactory) HooksPath(context.Context) string { + return "custom_hooks_path" +} + +func (mockGitCommandFactory) SidecarGitConfiguration(context.Context) ([]git.ConfigPair, error) { + return []git.ConfigPair{ + {Key: "core.gc", Value: "false"}, + }, nil +} + +func TestSetupEnv(t *testing.T) { + cfg := config.Cfg{ + BinDir: "/bin/dit", + RuntimeDir: "/gitaly", + Logging: config.Logging{ + Config: log.Config{ + Dir: "/log/dir", + }, + RubySentryDSN: "testDSN", + Sentry: config.Sentry{ + Environment: "testEnvironment", + }, + }, + Auth: auth.Config{Token: "paswd"}, + Ruby: config.Ruby{RuggedGitConfigSearchPath: "/bin/rugged"}, + } + + env, err := setupEnv(cfg, mockGitCommandFactory{}) + require.NoError(t, err) + + require.Subset(t, env, []string{ + "FOO=bar", + "GITALY_LOG_DIR=/log/dir", + "GITALY_RUBY_GIT_BIN_PATH=/something", + fmt.Sprintf("GITALY_RUBY_WRITE_BUFFER_SIZE=%d", streamio.WriteBufferSize), + fmt.Sprintf("GITALY_RUBY_MAX_COMMIT_OR_TAG_MESSAGE_SIZE=%d", helper.MaxCommitOrTagMessageSize), + "GITALY_RUBY_GITALY_BIN_DIR=/bin/dit", + "GITALY_VERSION=" + version.GetVersion(), + fmt.Sprintf("GITALY_SOCKET=%s", cfg.InternalSocketPath()), + "GITALY_TOKEN=paswd", + "GITALY_RUGGED_GIT_CONFIG_SEARCH_PATH=/bin/rugged", + "SENTRY_DSN=testDSN", + "SENTRY_ENVIRONMENT=testEnvironment", + "GITALY_GIT_HOOKS_DIR=custom_hooks_path", + "GIT_CONFIG_KEY_0=core.gc", + "GIT_CONFIG_VALUE_0=false", + "GIT_CONFIG_COUNT=1", + }) +} + +func TestServer_gitconfig(t *testing.T) { + for _, tc := range []struct { + desc string + setup func(t *testing.T) (config.Cfg, string) + expectedGitconfig string + }{ + { + desc: "writes a default gitconfig", + setup: func(t *testing.T) (config.Cfg, string) { + cfg := testcfg.Build(t) + expectedPath := filepath.Join(cfg.RuntimeDir, "ruby-gitconfig", "gitconfig") + return cfg, expectedPath + }, + // If no search path is provided, we should create a placeholder file that + // contains all settings important to Rugged. + expectedGitconfig: "[core]\n\tfsyncObjectFiles = true\n", + }, + { + desc: "uses injected gitconfig", + setup: func(t *testing.T) (config.Cfg, string) { + gitconfigDir := testhelper.TempDir(t) + expectedPath := filepath.Join(gitconfigDir, "gitconfig") + require.NoError(t, os.WriteFile(expectedPath, []byte("garbage"), 0o666)) + + cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ + Ruby: config.Ruby{ + RuggedGitConfigSearchPath: gitconfigDir, + }, + })) + + return cfg, expectedPath + }, + // The gitconfig shouldn't have been rewritten, so it should still contain + // garbage after the server starts. + expectedGitconfig: "garbage", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + cfg, expectedPath := tc.setup(t) + + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + locator := config.NewLocator(cfg) + + rubyServer := New(cfg, gitCmdFactory) + require.NoError(t, rubyServer.Start()) + defer rubyServer.Stop() + + // Verify that the expected gitconfig exists and has expected contents. + gitconfigContents := testhelper.MustReadFile(t, expectedPath) + require.Equal(t, tc.expectedGitconfig, string(gitconfigContents)) + + // Write a gitconfig that is invalidly formatted. Like this we can assert + // whether the Ruby server tries to read it or not because it should in fact + // fail. + require.NoError(t, os.WriteFile(expectedPath, []byte( + `[`, + ), 0o666)) + + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + // We now do any random RPC request that hits the Ruby server... + client, err := rubyServer.WikiServiceClient(ctx) + require.NoError(t, err) + + ctx, err = SetHeaders(ctx, locator, repo) + require.NoError(t, err) + + stream, err := client.WikiListPages(ctx, &gitalypb.WikiListPagesRequest{Repository: repo}) + require.NoError(t, err) + + // ... and expect it to fail with an error parsing the configuration. This + // demonstrates the config was injected successfully. + _, err = stream.Recv() + testhelper.RequireGrpcError(t, fmt.Errorf("Rugged::ConfigError: failed to parse config file: missing ']' in section header (in %s:1)", expectedPath), err) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/stopwatch.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/stopwatch.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/stopwatch.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/stopwatch.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/testhelper_test.go index f304d96c2d..0e7918cc3a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package rubyserver import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker.go index f3dd20aa09..c5388d430f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker.go @@ -8,8 +8,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer" - "gitlab.com/gitlab-org/gitaly/v14/internal/supervisor" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer" + "gitlab.com/gitlab-org/gitaly/v15/internal/supervisor" ) var terminationCounter = promauto.NewCounterVec( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker_test.go index 8b4a5b6c1b..6c7c730ec6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/worker_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/worker_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package rubyserver import ( @@ -6,7 +8,7 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/supervisor" + "gitlab.com/gitlab-org/gitaly/v15/internal/supervisor" ) func TestWorker(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth/auth.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth/auth.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth/auth.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth/auth.go index f510646c31..29c043dcbe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth/auth.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth/auth.go @@ -7,8 +7,8 @@ import ( grpcmwauth "github.com/grpc-ecosystem/go-grpc-middleware/auth" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - gitalycfgauth "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + gitalycfgauth "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth_test.go index 78107cbe70..7cd8d9efa6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package server import ( @@ -12,28 +14,30 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) @@ -45,7 +49,7 @@ func TestMain(m *testing.M) { func TestSanity(t *testing.T) { serverSocketPath := runServer(t, testcfg.Build(t)) - conn, err := dial(serverSocketPath, []grpc.DialOption{grpc.WithInsecure()}) + conn, err := dial(serverSocketPath, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}) require.NoError(t, err) t.Cleanup(func() { conn.Close() }) @@ -102,7 +106,7 @@ func TestAuthFailures(t *testing.T) { })) serverSocketPath := runServer(t, cfg) - connOpts := append(tc.opts, grpc.WithInsecure()) + connOpts := append(tc.opts, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := dial(serverSocketPath, connOpts) require.NoError(t, err, tc.desc) t.Cleanup(func() { conn.Close() }) @@ -145,7 +149,7 @@ func TestAuthSuccess(t *testing.T) { })) serverSocketPath := runServer(t, cfg) - connOpts := append(tc.opts, grpc.WithInsecure()) + connOpts := append(tc.opts, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := dial(serverSocketPath, connOpts) require.NoError(t, err, tc.desc) t.Cleanup(func() { conn.Close() }) @@ -165,8 +169,8 @@ func dial(serverSocketPath string, opts []grpc.DialOption) (*grpc.ClientConn, er return grpc.Dial(serverSocketPath, opts...) } -func healthCheck(t testing.TB, conn *grpc.ClientConn) error { - ctx := testhelper.Context(t) +func healthCheck(tb testing.TB, conn *grpc.ClientConn) error { + ctx := testhelper.Context(tb) _, err := healthpb.NewHealthClient(conn).Check(ctx, &healthpb.HealthCheckRequest{}) return err @@ -176,7 +180,7 @@ func newOperationClient(t *testing.T, token, serverSocketPath string) (gitalypb. t.Helper() connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(token)), } conn, err := grpc.Dial(serverSocketPath, connOpts...) @@ -260,7 +264,7 @@ func runSecureServer(t *testing.T, cfg config.Cfg) string { func TestUnaryNoAuth(t *testing.T) { cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{Auth: auth.Config{Token: "testtoken"}})) path := runServer(t, cfg) - conn, err := grpc.Dial(path, grpc.WithInsecure()) + conn, err := grpc.Dial(path, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer testhelper.MustClose(t, conn) ctx := testhelper.Context(t) @@ -281,7 +285,7 @@ func TestStreamingNoAuth(t *testing.T) { cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{Auth: auth.Config{Token: "testtoken"}})) path := runServer(t, cfg) - conn, err := dial(path, []grpc.DialOption{grpc.WithInsecure()}) + conn, err := dial(path, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}) require.NoError(t, err) t.Cleanup(func() { conn.Close() }) ctx := testhelper.Context(t) @@ -342,6 +346,10 @@ sleep %vs for i := 0; i < 2; i++ { i := i go func() { + // We don't care about the feature flag, but it's required to satisfy our + // sanity checks in testing. So let's just explicitly enable it here. + ctx := featureflag.OutgoingCtxWithFeatureFlag(ctx, featureflag.UserCreateTagStructuredErrors, true) + _, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ Repository: repo, TagName: []byte(fmt.Sprintf("tag-name-%d", i)), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server.go index ab00acd6ef..e62b4b99cc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server.go @@ -10,24 +10,24 @@ import ( grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - diskcache "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cancelhandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + diskcache "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cancelhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" "google.golang.org/grpc" @@ -156,8 +156,12 @@ func New( grpc.Creds(lm), grpc.StreamInterceptor(grpcmw.ChainStreamServer(streamServerInterceptors...)), grpc.UnaryInterceptor(grpcmw.ChainUnaryServer(unaryServerInterceptors...)), + // We deliberately set the server MinTime to significantly less than the client interval of 20 + // seconds to allow for network jitter. We can afford to be forgiving as the maximum number of + // concurrent clients for a Gitaly server is typically in the hundreds and this volume of + // keepalives won't add significant load. grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ - MinTime: 20 * time.Second, + MinTime: 10 * time.Second, PermitWithoutStream: true, }), grpc.KeepaliveParams(keepalive.ServerParameters{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory.go index 6b33557be5..2a88ba4ba8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory.go @@ -4,10 +4,10 @@ import ( "sync" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory_test.go index a288272481..9a181089d8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/server_factory_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/server_factory_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package server import ( @@ -13,17 +15,18 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" @@ -31,20 +34,21 @@ import ( func TestGitalyServerFactory(t *testing.T) { ctx := testhelper.Context(t) + grp, ctx := errgroup.WithContext(ctx) + t.Cleanup(func() { assert.NoError(t, grp.Wait()) }) checkHealth := func(t *testing.T, sf *GitalyServerFactory, schema, addr string) healthpb.HealthClient { t.Helper() var cc *grpc.ClientConn if schema == starter.TLS { - listener, err := net.Listen(starter.TCP, addr) - require.NoError(t, err) - t.Cleanup(func() { listener.Close() }) - srv, err := sf.CreateExternal(true) require.NoError(t, err) healthpb.RegisterHealthServer(srv, health.NewServer()) - go srv.Serve(listener) + + listener, err := net.Listen(starter.TCP, addr) + require.NoError(t, err) + grp.Go(func() error { return srv.Serve(listener) }) certPool, err := x509.SystemCertPool() require.NoError(t, err) @@ -60,14 +64,13 @@ func TestGitalyServerFactory(t *testing.T) { cc, err = grpc.DialContext(ctx, listener.Addr().String(), grpc.WithTransportCredentials(creds)) require.NoError(t, err) } else { - listener, err := net.Listen(schema, addr) - require.NoError(t, err) - t.Cleanup(func() { listener.Close() }) - srv, err := sf.CreateExternal(false) require.NoError(t, err) healthpb.RegisterHealthServer(srv, health.NewServer()) - go srv.Serve(listener) + + listener, err := net.Listen(schema, addr) + require.NoError(t, err) + grp.Go(func() error { return srv.Serve(listener) }) endpoint, err := starter.ComposeEndpoint(schema, listener.Addr().String()) require.NoError(t, err) @@ -75,11 +78,9 @@ func TestGitalyServerFactory(t *testing.T) { cc, err = client.Dial(endpoint, nil) require.NoError(t, err) } - - t.Cleanup(func() { cc.Close() }) + t.Cleanup(func() { assert.NoError(t, cc.Close()) }) healthClient := healthpb.NewHealthClient(cc) - resp, err := healthClient.Check(ctx, &healthpb.HealthCheckRequest{}) require.NoError(t, err) require.Equal(t, healthpb.HealthCheckResponse_SERVING, resp.Status) @@ -93,8 +94,9 @@ func TestGitalyServerFactory(t *testing.T) { testhelper.NewDiscardingLogEntry(t), backchannel.NewRegistry(), cache.New(cfg, config.NewLocator(cfg)), - []*limithandler.LimiterMiddleware{limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters)}, + nil, ) + t.Cleanup(sf.Stop) checkHealth(t, sf, starter.TCP, "localhost:0") }) @@ -112,7 +114,7 @@ func TestGitalyServerFactory(t *testing.T) { testhelper.NewDiscardingLogEntry(t), backchannel.NewRegistry(), cache.New(cfg, config.NewLocator(cfg)), - []*limithandler.LimiterMiddleware{limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters)}, + nil, ) t.Cleanup(sf.Stop) @@ -126,7 +128,7 @@ func TestGitalyServerFactory(t *testing.T) { testhelper.NewDiscardingLogEntry(t), backchannel.NewRegistry(), cache.New(cfg, config.NewLocator(cfg)), - []*limithandler.LimiterMiddleware{limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters)}, + nil, ) t.Cleanup(sf.Stop) @@ -147,7 +149,7 @@ func TestGitalyServerFactory(t *testing.T) { }) t.Run("logging check", func(t *testing.T) { - testhelper.ModifyEnvironment(t, "GITALY_LOG_REQUEST_METHOD_ALLOW_PATTERN", ".") + t.Setenv("GITALY_LOG_REQUEST_METHOD_ALLOW_PATTERN", ".") cfg := testcfg.Build(t) logger, hook := test.NewNullLogger() @@ -156,8 +158,9 @@ func TestGitalyServerFactory(t *testing.T) { logger.WithContext(ctx), backchannel.NewRegistry(), cache.New(cfg, config.NewLocator(cfg)), - []*limithandler.LimiterMiddleware{limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters)}, + nil, ) + t.Cleanup(sf.Stop) checkHealth(t, sf, starter.TCP, "localhost:0") @@ -190,7 +193,7 @@ func TestGitalyServerFactory_closeOrder(t *testing.T) { testhelper.NewDiscardingLogEntry(t), backchannel.NewRegistry(), cache.New(cfg, config.NewLocator(cfg)), - []*limithandler.LimiterMiddleware{limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters)}, + nil, ) defer sf.Stop() @@ -204,7 +207,7 @@ func TestGitalyServerFactory_closeOrder(t *testing.T) { return } - require.Equal(t, errQuickRPC, err) + testhelper.RequireGrpcError(t, errQuickRPC, err) } invokeBlocking := func(conn *grpc.ClientConn) chan struct{} { @@ -212,7 +215,7 @@ func TestGitalyServerFactory_closeOrder(t *testing.T) { go func() { defer close(rpcFinished) - assert.Equal(t, + testhelper.RequireGrpcError(t, errBlockingRPC, conn.Invoke(ctx, "/Service/Blocking", &healthpb.HealthCheckRequest{}, &healthpb.HealthCheckRequest{}), ) @@ -298,7 +301,7 @@ func TestGitalyServerFactory_closeOrder(t *testing.T) { go server.Serve(ln) - conn, err := grpc.DialContext(ctx, ln.Addr().String(), grpc.WithInsecure()) + conn, err := grpc.DialContext(ctx, ln.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { testhelper.MustClose(t, conn) }) *builder.conn = conn diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/testdata/gitalycert.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/testdata/gitalycert.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/testdata/gitalycert.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/testdata/gitalycert.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/testdata/gitalykey.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/testdata/gitalykey.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/testdata/gitalykey.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/testdata/gitalykey.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs.go index 50a8a62745..64c5f8e620 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs.go @@ -7,19 +7,20 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/protobuf/proto" ) func verifyListBlobsRequest(req *gitalypb.ListBlobsRequest) error { if req.GetRepository() == nil { - return errors.New("empty repository") + return gitalyerrors.ErrEmptyRepository } if len(req.GetRevisions()) == 0 { return errors.New("missing revisions") @@ -98,10 +99,11 @@ func (s *server) processBlobs( // object iterator. We thus support an optional `catfileInfoIter` parameter: if set, // we just use that one and ignore the object iterator. if catfileInfoIter == nil { - objectInfoReader, err := s.catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object info reader: %w", err)) } + defer cancel() catfileInfoIter, err = gitpipe.CatfileInfo(ctx, objectInfoReader, objectIter) if err != nil { @@ -132,14 +134,15 @@ func (s *server) processBlobs( return helper.ErrInternal(err) } } else { - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) } + defer cancel() catfileObjectIter, err := gitpipe.CatfileObject(ctx, objectReader, objectIter) if err != nil { - return helper.ErrInternalf("creating catfile object iterator: %w", err) + return helper.ErrInternalf("creating object iterator: %w", err) } var i uint32 @@ -235,7 +238,7 @@ func (s *server) ListAllBlobs(req *gitalypb.ListAllBlobsRequest, stream gitalypb ctx := stream.Context() if req.GetRepository() == nil { - return helper.ErrInvalidArgumentf("empty repository") + return helper.ErrInvalidArgument(gitalyerrors.ErrEmptyRepository) } repo := s.localrepo(req.GetRepository()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs_test.go index 119254518e..7fd40fb1f6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/blobs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/blobs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blob import ( @@ -7,12 +9,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob.go index 99ce668738..77ad6dfaee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob.go @@ -1,36 +1,38 @@ package blob import ( - "fmt" + "errors" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) GetBlob(in *gitalypb.GetBlobRequest, stream gitalypb.BlobService_GetBlobServer) error { ctx := stream.Context() + if err := validateRequest(in); err != nil { + return helper.ErrInvalidArgument(err) + } + repo := s.localrepo(in.GetRepository()) - if err := validateRequest(in); err != nil { - return helper.ErrInvalidArgumentf("GetBlob: %v", err) - } - - objectReader, err := s.catfileCache.ObjectReader(stream.Context(), repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(stream.Context(), repo) if err != nil { - return helper.ErrInternalf("GetBlob: %v", err) + return helper.ErrInternalf("create object reader: %w", err) } + defer cancel() blob, err := objectReader.Object(ctx, git.Revision(in.Oid)) if err != nil { if catfile.IsNotFound(err) { return helper.ErrUnavailable(stream.Send(&gitalypb.GetBlobResponse{})) } - return helper.ErrInternalf("GetBlob: %v", err) + return helper.ErrInternalf("read object: %w", err) } if blob.Type != "blob" { @@ -62,15 +64,19 @@ func (s *server) GetBlob(in *gitalypb.GetBlobRequest, stream gitalypb.BlobServic _, err = io.CopyN(sw, blob, readLimit) if err != nil { - return helper.ErrUnavailablef("GetBlob: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } return nil } func validateRequest(in *gitalypb.GetBlobRequest) error { + if in.GetRepository() == nil { + return gitalyerrors.ErrEmptyRepository + } + if len(in.GetOid()) == 0 { - return fmt.Errorf("empty Oid") + return errors.New("empty Oid") } return nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob_test.go index d4dca06107..635553f9cd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blob_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blob_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blob import ( @@ -8,9 +10,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func TestSuccessfulGetBlob(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs.go index 5b899ebe7a..114fbbfc0e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs.go @@ -2,14 +2,16 @@ package blob import ( "bytes" + "errors" + "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) var treeEntryToObjectType = map[gitalypb.TreeEntry_EntryType]gitalypb.ObjectType{ @@ -38,14 +40,14 @@ func sendGetBlobsResponse( treeEntry, err := tef.FindByRevisionAndPath(ctx, revision, string(path)) if err != nil { - return err + return helper.ErrInternalf("find by revision and path: %w", err) } response := &gitalypb.GetBlobsResponse{Revision: revision, Path: path} if treeEntry == nil || len(treeEntry.Oid) == 0 { if err := stream.Send(response); err != nil { - return status.Errorf(codes.Unavailable, "GetBlobs: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } continue @@ -59,7 +61,7 @@ func sendGetBlobsResponse( response.Type = gitalypb.ObjectType_COMMIT if err := stream.Send(response); err != nil { - return status.Errorf(codes.Unavailable, "GetBlobs: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } continue @@ -67,7 +69,7 @@ func sendGetBlobsResponse( objectInfo, err := objectInfoReader.Info(ctx, git.Revision(treeEntry.Oid)) if err != nil { - return status.Errorf(codes.Internal, "GetBlobs: %v", err) + return helper.ErrInternalf("read object info: %w", err) } response.Size = objectInfo.Size @@ -81,7 +83,7 @@ func sendGetBlobsResponse( if response.Type != gitalypb.ObjectType_BLOB { if err := stream.Send(response); err != nil { - return status.Errorf(codes.Unavailable, "GetBlobs: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } continue } @@ -109,27 +111,27 @@ func sendBlobTreeEntry( readLimit = limit } - // For correctness it does not matter, but for performance, the order is + // For correctness, it does not matter, but for performance, the order is // important: first check if readlimit == 0, if not, only then create // blobObj. if readLimit == 0 { if err := stream.Send(response); err != nil { - return status.Errorf(codes.Unavailable, "GetBlobs: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } return nil } blobObj, err := objectReader.Object(ctx, git.Revision(response.Oid)) if err != nil { - return status.Errorf(codes.Internal, "GetBlobs: %v", err) + return helper.ErrInternalf("read object: %w", err) } defer func() { if _, err := io.Copy(io.Discard, blobObj); err != nil && returnedErr == nil { - returnedErr = status.Errorf(codes.Internal, "GetBlobs: discarding data: %v", err) + returnedErr = helper.ErrInternalf("discarding data: %w", err) } }() if blobObj.Type != "blob" { - return status.Errorf(codes.Internal, "blob got unexpected type %q", blobObj.Type) + return helper.ErrInternalf("blob got unexpected type %q", blobObj.Type) } sw := streamio.NewWriter(func(p []byte) error { @@ -146,7 +148,7 @@ func sendBlobTreeEntry( _, err = io.CopyN(sw, blobObj, readLimit) if err != nil { - return status.Errorf(codes.Unavailable, "GetBlobs: send: %v", err) + return helper.ErrUnavailablef("send: %w", err) } return nil @@ -154,36 +156,38 @@ func sendBlobTreeEntry( func (s *server) GetBlobs(req *gitalypb.GetBlobsRequest, stream gitalypb.BlobService_GetBlobsServer) error { if err := validateGetBlobsRequest(req); err != nil { - return err + return helper.ErrInvalidArgument(err) } repo := s.localrepo(req.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(stream.Context(), repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(stream.Context(), repo) if err != nil { - return err + return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) } + defer cancel() - objectInfoReader, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) if err != nil { - return err + return helper.ErrInternal(fmt.Errorf("creating object info reader: %w", err)) } + defer cancel() return sendGetBlobsResponse(req, stream, objectReader, objectInfoReader) } func validateGetBlobsRequest(req *gitalypb.GetBlobsRequest) error { if req.Repository == nil { - return status.Errorf(codes.InvalidArgument, "GetBlobs: empty Repository") + return gitalyerrors.ErrEmptyRepository } if len(req.RevisionPaths) == 0 { - return status.Errorf(codes.InvalidArgument, "GetBlobs: empty RevisionPaths") + return errors.New("empty RevisionPaths") } for _, rp := range req.RevisionPaths { if err := git.ValidateRevision([]byte(rp.Revision)); err != nil { - return status.Errorf(codes.InvalidArgument, "GetBlobs: %v", err) + return err } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs_test.go index e80888ed3d..d363a01c46 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/get_blobs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/get_blobs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blob import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers.go index ca05b47506..88b7870ec3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers.go @@ -6,15 +6,13 @@ import ( "io" "strings" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -31,14 +29,14 @@ func (s *server) ListLFSPointers(in *gitalypb.ListLFSPointersRequest, stream git ctx := stream.Context() if in.GetRepository() == nil { - return status.Error(codes.InvalidArgument, "empty repository") + return helper.ErrInvalidArgument(gitalyerrors.ErrEmptyRepository) } if len(in.Revisions) == 0 { - return status.Error(codes.InvalidArgument, "missing revisions") + return helper.ErrInvalidArgumentf("missing revisions") } for _, revision := range in.Revisions { if strings.HasPrefix(revision, "-") && revision != "--all" && revision != "--not" { - return status.Errorf(codes.InvalidArgument, "invalid revision: %q", revision) + return helper.ErrInvalidArgumentf("invalid revision: %q", revision) } } @@ -52,10 +50,11 @@ func (s *server) ListLFSPointers(in *gitalypb.ListLFSPointersRequest, stream git repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) } + defer cancel() revlistIter := gitpipe.Revlist(ctx, repo, in.GetRevisions(), gitpipe.WithObjects(), @@ -81,7 +80,7 @@ func (s *server) ListAllLFSPointers(in *gitalypb.ListAllLFSPointersRequest, stre ctx := stream.Context() if in.GetRepository() == nil { - return status.Error(codes.InvalidArgument, "empty repository") + return helper.ErrInvalidArgument(gitalyerrors.ErrEmptyRepository) } repo := s.localrepo(in.GetRepository()) @@ -94,10 +93,11 @@ func (s *server) ListAllLFSPointers(in *gitalypb.ListAllLFSPointersRequest, stre }, }) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { - return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) + return helper.ErrInternalf("creating object reader: %w", err) } + defer cancel() catfileInfoIter := gitpipe.CatfileInfoAllObjects(ctx, repo, gitpipe.WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool { @@ -124,7 +124,7 @@ func (s *server) GetLFSPointers(req *gitalypb.GetLFSPointersRequest, stream gita ctx := stream.Context() if err := validateGetLFSPointersRequest(req); err != nil { - return status.Errorf(codes.InvalidArgument, "GetLFSPointers: %v", err) + return helper.ErrInvalidArgument(err) } repo := s.localrepo(req.GetRepository()) @@ -137,22 +137,24 @@ func (s *server) GetLFSPointers(req *gitalypb.GetLFSPointersRequest, stream gita }, }) - objectInfoReader, err := s.catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object info reader: %w", err)) } + defer cancel() - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) } + defer cancel() blobs := make([]gitpipe.RevisionResult, len(req.GetBlobIds())) for i, blobID := range req.GetBlobIds() { blobs[i] = gitpipe.RevisionResult{OID: git.ObjectID(blobID)} } - catfileInfoIter, err := gitpipe.CatfileInfo(ctx, objectInfoReader, gitpipe.NewRevisionIterator(blobs), + catfileInfoIter, err := gitpipe.CatfileInfo(ctx, objectInfoReader, gitpipe.NewRevisionIterator(ctx, blobs), gitpipe.WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool { return objectInfo.Type != "blob" || objectInfo.Size > lfsPointerMaxSize }), @@ -160,6 +162,7 @@ func (s *server) GetLFSPointers(req *gitalypb.GetLFSPointersRequest, stream gita if err != nil { return helper.ErrInternalf("creating object info iterator: %w", err) } + defer cancel() catfileObjectIter, err := gitpipe.CatfileObject(ctx, objectReader, catfileInfoIter) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers_test.go index 417e779f87..ec127bd120 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/lfs_pointers_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/lfs_pointers_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blob import ( @@ -10,13 +12,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -66,6 +70,10 @@ func TestListLFSPointers(t *testing.T) { ctx := testhelper.Context(t) _, repo, _, client := setup(ctx, t) + ctx = testhelper.MergeOutgoingMetadata(ctx, + metadata.Pairs(catfile.SessionIDField, "1"), + ) + for _, tc := range []struct { desc string revs []string diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/server.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/server.go index 6e8acdd1d6..439c6ce10d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/server.go @@ -1,12 +1,12 @@ package blob import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/testdata/maintenance-md-blob.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/testdata/maintenance-md-blob.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/testdata/maintenance-md-blob.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/testdata/maintenance-md-blob.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/testhelper_test.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/testhelper_test.go index 29c57b3d28..4554cfc55e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package blob import ( @@ -5,15 +7,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func TestMain(m *testing.M) { @@ -43,7 +46,7 @@ func setup(ctx context.Context, tb testing.TB) (config.Cfg, *gitalypb.Repository }) cfg.SocketPath = addr - conn, err := grpc.Dial(addr, grpc.WithInsecure()) + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(tb, err) tb.Cleanup(func() { conn.Close() }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go index d10c483d1f..84b39aca90 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream.go @@ -4,12 +4,12 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/internalrefs" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/notifier" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/internalrefs" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/notifier" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/protobuf/proto" ) @@ -40,10 +40,11 @@ func (s *server) ApplyBfgObjectMapStream(server gitalypb.CleanupService_ApplyBfg reader := &bfgStreamReader{firstRequest: firstRequest, server: server} chunker := chunk.New(&bfgStreamWriter{server: server}) - notifier, err := notifier.New(ctx, s.catfileCache, repo, chunker) + notifier, cancel, err := notifier.New(ctx, s.catfileCache, repo, chunker) if err != nil { return helper.ErrInternal(err) } + defer cancel() // It doesn't matter if new internal references are added after this RPC // starts running - they shouldn't point to the objects removed by the BFG diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go index 23410ff94e..9bdacdfadc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/apply_bfg_object_map_stream_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package cleanup import ( @@ -9,12 +11,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -55,10 +57,10 @@ func TestApplyBfgObjectMapStreamSuccess(t *testing.T) { const filterRepoCommitMapHeader = "old new\n" objectMapData := fmt.Sprintf( filterRepoCommitMapHeader+strings.Repeat("%s %s\n", 5), - headCommit.Id, git.ZeroOID.String(), - git.ZeroOID.String(), blobID, - git.ZeroOID.String(), tagID, - blobID, git.ZeroOID.String(), + headCommit.Id, git.ObjectHashSHA1.ZeroOID.String(), + git.ObjectHashSHA1.ZeroOID.String(), blobID, + git.ObjectHashSHA1.ZeroOID.String(), tagID, + blobID, git.ObjectHashSHA1.ZeroOID.String(), tagID, tagID, ) @@ -88,10 +90,10 @@ func TestApplyBfgObjectMapStreamSuccess(t *testing.T) { // Ensure that the returned entry is correct require.Len(t, entries, 4, "wrong number of entries returned") - requireEntry(t, entries[0], headCommit.Id, git.ZeroOID.String(), gitalypb.ObjectType_COMMIT) - requireEntry(t, entries[1], git.ZeroOID.String(), blobID, gitalypb.ObjectType_BLOB) - requireEntry(t, entries[2], git.ZeroOID.String(), tagID, gitalypb.ObjectType_TAG) - requireEntry(t, entries[3], blobID, git.ZeroOID.String(), gitalypb.ObjectType_UNKNOWN) + requireEntry(t, entries[0], headCommit.Id, git.ObjectHashSHA1.ZeroOID.String(), gitalypb.ObjectType_COMMIT) + requireEntry(t, entries[1], git.ObjectHashSHA1.ZeroOID.String(), blobID, gitalypb.ObjectType_BLOB) + requireEntry(t, entries[2], git.ObjectHashSHA1.ZeroOID.String(), tagID, gitalypb.ObjectType_TAG) + requireEntry(t, entries[3], blobID, git.ObjectHashSHA1.ZeroOID.String(), gitalypb.ObjectType_UNKNOWN) } func requireEntry(t *testing.T, entry *gitalypb.ApplyBfgObjectMapStreamResponse_Entry, oldOid, newOid string, objectType gitalypb.ObjectType) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/internalrefs/cleaner.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/internalrefs/cleaner.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/internalrefs/cleaner.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/internalrefs/cleaner.go index ca2e04a8c0..0ef2986c84 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/internalrefs/cleaner.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/internalrefs/cleaner.go @@ -9,8 +9,8 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" ) // A ForEachFunc can be called for every entry in the filter-repo or BFG object @@ -124,10 +124,15 @@ func (c *Cleaner) processEntry(ctx context.Context, oldSHA, newSHA string) error // action). It is consulted once per line in the object map. Git is optimized // for ref -> SHA lookups, but we want the opposite! func buildLookupTable(ctx context.Context, repo git.RepositoryExecutor) (map[string][]git.ReferenceName, error) { + internalRefPrefixes := make([]string, 0, len(git.InternalRefPrefixes)) + for refPrefix := range git.InternalRefPrefixes { + internalRefPrefixes = append(internalRefPrefixes, refPrefix) + } + cmd, err := repo.Exec(ctx, git.SubCmd{ Name: "for-each-ref", Flags: []git.Option{git.ValueFlag{Name: "--format", Value: "%(objectname) %(refname)"}}, - Args: git.InternalRefPrefixes[:], + Args: internalRefPrefixes, }) if err != nil { return nil, err diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/notifier/notifier.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/notifier/notifier.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/notifier/notifier.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/notifier/notifier.go index 6b6acff882..94d588aa8d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/notifier/notifier.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/notifier/notifier.go @@ -3,10 +3,10 @@ package notifier import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // Notifier sends messages stating that an OID has been rewritten, looking @@ -17,13 +17,13 @@ type Notifier struct { } // New instantiates a new Notifier -func New(ctx context.Context, catfileCache catfile.Cache, repo git.RepositoryExecutor, chunker *chunk.Chunker) (*Notifier, error) { - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) +func New(ctx context.Context, catfileCache catfile.Cache, repo git.RepositoryExecutor, chunker *chunk.Chunker) (*Notifier, func(), error) { + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) if err != nil { - return nil, err + return nil, nil, err } - return &Notifier{objectInfoReader: objectInfoReader, chunker: chunker}, nil + return &Notifier{objectInfoReader: objectInfoReader, chunker: chunker}, cancel, nil } // Notify builds a new message and sends it to the chunker diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/server.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/server.go index 11c72a9633..7f3b0b0989 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/server.go @@ -1,12 +1,12 @@ package cleanup import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/testhelper_test.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/testhelper_test.go index 4d1ddfc14b..6909d67daf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup/testhelper_test.go @@ -1,19 +1,22 @@ +//go:build !gitaly_test_sha256 + package cleanup import ( "context" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func TestMain(m *testing.M) { @@ -42,7 +45,7 @@ func runCleanupServiceServer(t *testing.T, cfg config.Cfg) string { deps.GetGitCmdFactory(), deps.GetCatfileCache(), )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( deps.GetCfg(), deps.GetRubyServer(), @@ -59,7 +62,7 @@ func runCleanupServiceServer(t *testing.T, cfg config.Cfg) string { func newCleanupServiceClient(t *testing.T, serverSocketPath string) (gitalypb.CleanupServiceClient, *grpc.ClientConn) { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist.go new file mode 100644 index 0000000000..04b92be899 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist.go @@ -0,0 +1,122 @@ +package commit + +import ( + "context" + "io" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/protobuf/proto" +) + +func (s *server) CheckObjectsExist( + stream gitalypb.CommitService_CheckObjectsExistServer, +) error { + ctx := stream.Context() + + request, err := stream.Recv() + if err != nil { + if err == io.EOF { + // Ideally, we'd return an invalid-argument error in case there aren't any + // requests. We can't do this though as this would diverge from Praefect's + // behaviour, which always returns `io.EOF`. + return err + } + return helper.ErrInternalf("receiving initial request: %w", err) + } + + if request.GetRepository() == nil { + return helper.ErrInvalidArgumentf("empty Repository") + } + + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader( + ctx, + s.localrepo(request.GetRepository()), + ) + if err != nil { + return helper.ErrInternalf("creating object info reader: %w", err) + } + defer cancel() + + chunker := chunk.New(&checkObjectsExistSender{stream: stream}) + for { + // Note: we have already fetched the first request containing revisions further up, + // so we only fetch the next request at the end of this loop. + for _, revision := range request.GetRevisions() { + if err := git.ValidateRevision(revision); err != nil { + return helper.ErrInvalidArgumentf("invalid revision %q: %w", revision, err) + } + } + + if err := checkObjectsExist(ctx, request, objectInfoReader, chunker); err != nil { + return helper.ErrInternalf("checking object existence: %w", err) + } + + request, err = stream.Recv() + if err != nil { + if err == io.EOF { + break + } + + return helper.ErrInternalf("receiving request: %w", err) + } + } + + if err := chunker.Flush(); err != nil { + return helper.ErrInternalf("flushing results: %w", err) + } + + return nil +} + +type checkObjectsExistSender struct { + stream gitalypb.CommitService_CheckObjectsExistServer + revisions []*gitalypb.CheckObjectsExistResponse_RevisionExistence +} + +func (c *checkObjectsExistSender) Send() error { + return c.stream.Send(&gitalypb.CheckObjectsExistResponse{ + Revisions: c.revisions, + }) +} + +func (c *checkObjectsExistSender) Reset() { + c.revisions = c.revisions[:0] +} + +func (c *checkObjectsExistSender) Append(m proto.Message) { + c.revisions = append(c.revisions, m.(*gitalypb.CheckObjectsExistResponse_RevisionExistence)) +} + +func checkObjectsExist( + ctx context.Context, + request *gitalypb.CheckObjectsExistRequest, + objectInfoReader catfile.ObjectInfoReader, + chunker *chunk.Chunker, +) error { + revisions := request.GetRevisions() + + for _, revision := range revisions { + revisionExistence := gitalypb.CheckObjectsExistResponse_RevisionExistence{ + Name: revision, + Exists: true, + } + _, err := objectInfoReader.Info(ctx, git.Revision(revision)) + if err != nil { + if catfile.IsNotFound(err) { + revisionExistence.Exists = false + } else { + return helper.ErrInternalf("reading object info: %w", err) + } + } + + if err := chunker.Send(&revisionExistence); err != nil { + return helper.ErrInternalf("adding to chunker: %w", err) + } + } + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist_test.go new file mode 100644 index 0000000000..9628bba020 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/check_objects_exist_test.go @@ -0,0 +1,226 @@ +//go:build !gitaly_test_sha256 + +package commit + +import ( + "fmt" + "io" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestCheckObjectsExist(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, client := setupCommitService(ctx, t) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID1 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch("master"), gittest.WithMessage("commit-1"), + ) + commitID2 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch("feature"), gittest.WithMessage("commit-2"), gittest.WithParents(commitID1), + ) + commitID3 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithMessage("commit-3"), gittest.WithParents(commitID1), + ) + + for _, tc := range []struct { + desc string + requests []*gitalypb.CheckObjectsExistRequest + expectedResults map[string]bool + expectedErr error + }{ + { + desc: "no requests", + requests: []*gitalypb.CheckObjectsExistRequest{}, + // Ideally, we'd return an invalid-argument error in case there aren't any + // requests. We can't do this though as this would diverge from Praefect's + // behaviour, which always returns `io.EOF`. + expectedResults: map[string]bool{}, + }, + { + desc: "missing repository", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Revisions: [][]byte{}, + }, + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: empty Repository") + } + return helper.ErrInvalidArgumentf("empty Repository") + }(), + expectedResults: map[string]bool{}, + }, + { + desc: "request without revisions", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + }, + }, + expectedResults: map[string]bool{}, + }, + { + desc: "commit ids and refs that exist", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte(commitID1), + []byte("master"), + []byte(commitID2), + []byte(commitID3), + []byte("feature"), + }, + }, + }, + expectedResults: map[string]bool{ + commitID1.String(): true, + "master": true, + commitID2.String(): true, + commitID3.String(): true, + "feature": true, + }, + }, + { + desc: "ref and objects missing", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte(commitID1), + []byte("master"), + []byte(commitID2), + []byte(commitID3), + []byte("feature"), + []byte("refs/does/not/exist"), + }, + }, + }, + expectedResults: map[string]bool{ + commitID1.String(): true, + "master": true, + commitID2.String(): true, + commitID3.String(): true, + "feature": true, + "refs/does/not/exist": false, + }, + }, + { + desc: "chunked input", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte(commitID1), + }, + }, + { + Revisions: [][]byte{ + []byte(commitID2), + }, + }, + { + Revisions: [][]byte{ + []byte("refs/does/not/exist"), + }, + }, + { + Revisions: [][]byte{ + []byte(commitID3), + }, + }, + }, + expectedResults: map[string]bool{ + commitID1.String(): true, + commitID2.String(): true, + commitID3.String(): true, + "refs/does/not/exist": false, + }, + }, + { + desc: "invalid input", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte("-not-a-rev"), + }, + }, + }, + expectedErr: helper.ErrInvalidArgumentf("invalid revision %q: revision can't start with '-'", "-not-a-rev"), + expectedResults: map[string]bool{}, + }, + { + desc: "input with whitespace", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte(fmt.Sprintf("%s\n%s", commitID1, commitID2)), + }, + }, + }, + expectedErr: helper.ErrInvalidArgumentf("invalid revision %q: revision can't contain whitespace", fmt.Sprintf("%s\n%s", commitID1, commitID2)), + expectedResults: map[string]bool{}, + }, + { + desc: "chunked invalid input", + requests: []*gitalypb.CheckObjectsExistRequest{ + { + Repository: repo, + Revisions: [][]byte{ + []byte(commitID1), + }, + }, + { + Revisions: [][]byte{ + []byte("-not-a-rev"), + }, + }, + }, + expectedErr: helper.ErrInvalidArgumentf("invalid revision %q: revision can't start with '-'", "-not-a-rev"), + expectedResults: map[string]bool{}, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + client, err := client.CheckObjectsExist(ctx) + require.NoError(t, err) + + for _, request := range tc.requests { + require.NoError(t, client.Send(request)) + } + require.NoError(t, client.CloseSend()) + + results := map[string]bool{} + for { + var response *gitalypb.CheckObjectsExistResponse + response, err = client.Recv() + if err != nil { + break + } + + for _, revision := range response.GetRevisions() { + results[string(revision.GetName())] = revision.GetExists() + } + } + + if tc.expectedErr == nil { + tc.expectedErr = io.EOF + } + + testhelper.RequireGrpcError(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResults, results) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages.go index 25b334e9e3..da82f92d6e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages.go @@ -5,11 +5,11 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) GetCommitMessages(request *gitalypb.GetCommitMessagesRequest, stream gitalypb.CommitService_GetCommitMessagesServer) error { @@ -27,10 +27,11 @@ func (s *server) getAndStreamCommitMessages(request *gitalypb.GetCommitMessagesR ctx := stream.Context() repo := s.localrepo(request.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() for _, commitID := range request.GetCommitIds() { msg, err := catfile.GetCommitMessage(ctx, objectReader, repo, git.Revision(commitID)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages_test.go index 7e19673cb0..8a8534426c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_messages_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_messages_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,10 +8,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -17,7 +19,7 @@ func TestSuccessfulGetCommitMessagesRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) message1 := strings.Repeat("a\n", helper.MaxCommitOrTagMessageSize*2) message2 := strings.Repeat("b\n", helper.MaxCommitOrTagMessageSize*2) @@ -59,7 +61,7 @@ func TestFailedGetCommitMessagesRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, _, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, _, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures.go index f2e3a7ac4c..9045e428ce 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures.go @@ -7,11 +7,11 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -30,10 +30,11 @@ func (s *server) getCommitSignatures(request *gitalypb.GetCommitSignaturesReques ctx := stream.Context() repo := s.localrepo(request.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(err) } + defer cancel() for _, commitID := range request.CommitIds { commitObj, err := objectReader.Object(ctx, git.Revision(commitID)+"^{commit}") @@ -137,7 +138,7 @@ func validateGetCommitSignaturesRequest(request *gitalypb.GetCommitSignaturesReq // Do not support shorthand or invalid commit SHAs for _, commitID := range request.CommitIds { - if err := git.ValidateObjectID(commitID); err != nil { + if err := git.ObjectHashSHA1.ValidateHex(commitID); err != nil { return err } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures_test.go index 7481f36339..70882228b5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commit_signatures_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commit_signatures_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -18,7 +20,7 @@ func TestSuccessfulGetCommitSignaturesRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) commitData := testhelper.MustReadFile(t, "testdata/dc00eb001f41dfac08192ead79c2377c588b82ee.commit") commit := text.ChompBytes(gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: bytes.NewReader(commitData)}, @@ -31,7 +33,7 @@ func TestSuccessfulGetCommitSignaturesRequest(t *testing.T) { CommitIds: []string{ "5937ac0a7beb003549fc5fd26fc247adbce4a52e", // has signature "e63f41fe459e62e1228fcef60d7189127aeba95a", // has no signature - git.ZeroOID.String(), // does not exist + git.ObjectHashSHA1.ZeroOID.String(), // does not exist "a17a9f66543673edf0a3d1c6b93bdda3fe600f32", // has signature "8cf8e80a5a0546e391823c250f2b26b9cf15ce88", // has signature and commit message > 4MB "dc00eb001f41dfac08192ead79c2377c588b82ee", // has signature and commit message without newline at the end @@ -87,7 +89,7 @@ func TestFailedGetCommitSignaturesRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message.go index 6353cf0ee7..0211413047 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message.go @@ -3,9 +3,9 @@ package commit import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message_test.go index eeab116011..b064259d31 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_by_message_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_by_message_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package commit import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -38,7 +40,7 @@ func TestSuccessfulCommitsByMessageRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) commits := []*gitalypb.GitCommit{ { @@ -159,7 +161,7 @@ func TestFailedCommitsByMessageRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_helper.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_helper.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_helper.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_helper.go index cb5715992d..3ba02b0f5d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_helper.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_helper.go @@ -4,10 +4,10 @@ import ( "context" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) sendCommits( @@ -29,10 +29,11 @@ func (s *server) sendCommits( return err } - logParser, err := log.NewParser(ctx, s.catfileCache, repo, cmd) + logParser, cancel, err := log.NewParser(ctx, s.catfileCache, repo, cmd) if err != nil { return err } + defer cancel() chunker := chunk.New(sender) for logParser.Parse(ctx) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_sender.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_sender.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_sender.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_sender.go index 65382181c9..e04f119cf6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/commits_sender.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/commits_sender.go @@ -1,7 +1,7 @@ package commit import ( - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits.go index 6dc68e2502..12c0072e1d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits.go @@ -9,8 +9,8 @@ import ( "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits_test.go index 1697ea87e9..301faa7421 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_commits_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,9 +8,9 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -17,7 +19,7 @@ func TestSuccessfulCountCommitsRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo1, _, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo1, _, client := setupCommitServiceWithRepo(ctx, t) repo2, repo2Path := gittest.CreateRepository(ctx, t, cfg) @@ -158,7 +160,7 @@ func TestFailedCountCommitsRequestDueToValidationError(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) revision := []byte("d42783470dc29fde2cf459eb3199ee1d7e3f3a72") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits.go index f47b135da7..a6d6ea27af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits.go @@ -8,9 +8,9 @@ import ( "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // CountDivergingCommits counts the diverging commits between from and to. Important to note that when --max-count is applied, the counts are not guaranteed to be diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits_test.go index b90fa15bb0..25ca341f96 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/count_diverging_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/count_diverging_commits_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -7,10 +9,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -159,7 +161,7 @@ func TestFailedCountDivergentCommitsRequestDueToValidationError(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) revision := []byte("d42783470dc29fde2cf459eb3199ee1d7e3f3a72") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures.go index 09d22d8817..02e7b14dfd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures.go @@ -5,10 +5,10 @@ import ( "errors" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FilterShasWithSignatures(bidi gitalypb.CommitService_FilterShasWithSignaturesServer) error { @@ -38,10 +38,11 @@ func (s *server) filterShasWithSignatures(bidi gitalypb.CommitService_FilterShas ctx := bidi.Context() repo := s.localrepo(firstRequest.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() request := firstRequest for { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures_test.go index 785a541612..ddd59f018b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/filter_shas_with_signatures_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/filter_shas_with_signatures_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -5,15 +7,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestFilterShasWithSignaturesSuccessful(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) type testCase struct { desc string diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits.go index 5be5c51f9a..837ff1318a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits.go @@ -3,9 +3,9 @@ package commit import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FindAllCommits(in *gitalypb.FindAllCommitsRequest, stream gitalypb.CommitService_FindAllCommitsServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits_test.go index 13e4cb3799..aadbb305bf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_all_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_all_commits_test.go @@ -1,14 +1,16 @@ +//go:build !gitaly_test_sha256 + package commit import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -16,7 +18,7 @@ func TestSuccessfulFindAllCommitsRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repoProto, _, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repoProto, _, client := setupCommitServiceWithRepo(ctx, t) repo := localrepo.NewTestRepo(t, cfg, repoProto) refs, err := repo.GetReferences(ctx, "refs/") @@ -159,7 +161,7 @@ func TestFailedFindAllCommitsRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit.go index b0e98ce73a..05705a0ae6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit.go @@ -4,10 +4,10 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FindCommit(ctx context.Context, in *gitalypb.FindCommitRequest) (*gitalypb.FindCommitResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit_test.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit_test.go index 54b2ad459a..d7d2a962e5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commit_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commit_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,15 +8,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -23,17 +22,13 @@ func TestSuccessfulFindCommitRequest(t *testing.T) { windows1251Message := testhelper.MustReadFile(t, "testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt") ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) + cfg, repoProto, repoPath, client := setupCommitServiceWithRepo(ctx, t) bigMessage := "An empty commit with REALLY BIG message\n\n" + strings.Repeat("MOAR!\n", 20*1024) bigCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("local-big-commits"), gittest.WithMessage(bigMessage), gittest.WithParents("60ecb67744cb56576c30214ff52294f8ce2def98"), ) - bigCommit, err := repo.ReadCommit(ctx, git.Revision(bigCommitID)) - require.NoError(t, err) testCases := []struct { description string @@ -198,20 +193,10 @@ func TestSuccessfulFindCommitRequest(t *testing.T) { description: "with a very large message", revision: bigCommitID.String(), commit: &gitalypb.GitCommit{ - Id: bigCommitID.String(), - Subject: []byte("An empty commit with REALLY BIG message"), - Author: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: bigCommit.Author.Date.Seconds}, - Timezone: []byte("+0100"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: bigCommit.Committer.Date.Seconds}, - Timezone: []byte("+0100"), - }, + Id: bigCommitID.String(), + Subject: []byte("An empty commit with REALLY BIG message"), + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, ParentIds: []string{"60ecb67744cb56576c30214ff52294f8ce2def98"}, Body: []byte(bigMessage[:helper.MaxCommitOrTagMessageSize]), BodySize: int64(len(bigMessage)), @@ -255,46 +240,68 @@ func TestFailedFindCommitRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} - testCases := []struct { - description string + for _, tc := range []struct { + desc string revision []byte repo *gitalypb.Repository + expectedErr error }{ - {repo: invalidRepo, revision: []byte("master"), description: "Invalid repo"}, - {repo: repo, revision: []byte(""), description: "Empty revision"}, - {repo: repo, revision: []byte("-master"), description: "Invalid revision"}, - {repo: repo, revision: []byte("mas:ter"), description: "Invalid revision"}, - } - - for _, testCase := range testCases { - t.Run(testCase.description, func(t *testing.T) { + { + desc: "Invalid repo", + repo: invalidRepo, + revision: []byte("master"), + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"fake\"", + "repo scoped: invalid Repository", + )), + }, + { + desc: "Empty revision", + repo: repo, + revision: []byte(""), + expectedErr: helper.ErrInvalidArgumentf("empty revision"), + }, + { + desc: "Invalid revision", + repo: repo, + revision: []byte("-master"), + expectedErr: helper.ErrInvalidArgumentf("revision can't start with '-'"), + }, + { + desc: "Invalid revision", + repo: repo, + revision: []byte("mas:ter"), + expectedErr: helper.ErrInvalidArgumentf("revision can't contain ':'"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { request := &gitalypb.FindCommitRequest{ - Repository: testCase.repo, - Revision: testCase.revision, + Repository: tc.repo, + Revision: tc.revision, } _, err := client.FindCommit(ctx, request) - require.Equal(t, codes.InvalidArgument, status.Code(err), "default lookup should fail") + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } func BenchmarkFindCommitNoCache(b *testing.B) { - benchmarkFindCommit(false, b) + benchmarkFindCommit(b, false) } func BenchmarkFindCommitWithCache(b *testing.B) { - benchmarkFindCommit(true, b) + benchmarkFindCommit(b, true) } -func benchmarkFindCommit(withCache bool, b *testing.B) { +func benchmarkFindCommit(b *testing.B, withCache bool) { ctx := testhelper.Context(b) - cfg, repo, _, client := setupCommitServiceWithRepo(ctx, b, false) + cfg, repo, _, client := setupCommitServiceWithRepo(ctx, b) // get a list of revisions gitCmdFactory := gittest.NewCommandFactory(b, cfg) @@ -332,7 +339,7 @@ func TestFindCommitWithCache(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, _, client := setupCommitServiceWithRepo(ctx, t) // get a list of revisions diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits.go index 8d6aaf0484..13907b10a6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits.go @@ -2,21 +2,26 @@ package commit import ( "bufio" + "bytes" "context" "errors" "fmt" "io" + "regexp" + "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/trailerparser" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/trailerparser" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) +var statsPattern = regexp.MustCompile(`\s(\d+)\sfiles? changed(,\s(\d+)\sinsertions?\(\+\))?(,\s(\d+)\sdeletions?\(-\))?`) + func (s *server) FindCommits(req *gitalypb.FindCommitsRequest, stream gitalypb.CommitService_FindCommitsServer) error { ctx := stream.Context() @@ -58,12 +63,13 @@ func (s *server) findCommits(ctx context.Context, req *gitalypb.FindCommitsReque return fmt.Errorf("error when creating git log command: %v", err) } - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return fmt.Errorf("creating catfile: %v", err) } + defer cancel() - getCommits := NewGetCommits(logCmd, objectReader) + getCommits := NewGetCommits(logCmd, objectReader, req.GetIncludeShortstat()) if calculateOffsetManually(req) { if err := getCommits.Offset(int(req.GetOffset())); err != nil { @@ -78,7 +84,7 @@ func (s *server) findCommits(ctx context.Context, req *gitalypb.FindCommitsReque } } - if err := streamCommits(getCommits, stream, req.GetTrailers()); err != nil { + if err := streamCommits(getCommits, stream, req.GetTrailers(), req.GetIncludeShortstat()); err != nil { return fmt.Errorf("error streaming commits: %v", err) } return nil @@ -95,11 +101,17 @@ type GetCommits struct { } // NewGetCommits returns a new GetCommits object -func NewGetCommits(cmd *command.Command, objectReader catfile.ObjectReader) *GetCommits { - return &GetCommits{ +func NewGetCommits(cmd *command.Command, objectReader catfile.ObjectReader, shortStat bool) *GetCommits { + getCommits := &GetCommits{ scanner: bufio.NewScanner(cmd), objectReader: objectReader, } + // If include shortstat, the scanner splits commits by special token, + // so that the commit hash and stats are combined. + if shortStat { + getCommits.scanner.Split(splitStat) + } + return getCommits } // Scan indicates whether or not there are more commits to return @@ -128,17 +140,24 @@ func (g *GetCommits) Offset(offset int) error { } // Commit returns the current commit -func (g *GetCommits) Commit(ctx context.Context, trailers bool) (*gitalypb.GitCommit, error) { +func (g *GetCommits) Commit(ctx context.Context, trailers, shortStat bool) (*gitalypb.GitCommit, error) { logOutput := strings.TrimSpace(g.scanner.Text()) var revAndTrailers []string + var revAndStats []string var revision string + if shortStat { + revAndStats = strings.SplitN(logOutput, "\n", 2) + logOutput = revAndStats[0] + } + if trailers { revAndTrailers = strings.SplitN(logOutput, "\000", 2) revision = revAndTrailers[0] } else { revision = logOutput } + commit, err := catfile.GetCommit(ctx, g.objectReader, git.Revision(revision)) if err != nil { return nil, fmt.Errorf("cat-file get commit %q: %v", revision, err) @@ -148,10 +167,17 @@ func (g *GetCommits) Commit(ctx context.Context, trailers bool) (*gitalypb.GitCo commit.Trailers = trailerparser.Parse([]byte(revAndTrailers[1])) } + if shortStat && len(revAndStats) == 2 { + commit.ShortStats, err = parseStat(revAndStats[1]) + if err != nil { + return nil, fmt.Errorf("get stats: %w", err) + } + } + return commit, nil } -func streamCommits(getCommits *GetCommits, stream gitalypb.CommitService_FindCommitsServer, trailers bool) error { +func streamCommits(getCommits *GetCommits, stream gitalypb.CommitService_FindCommitsServer, trailers, shortStat bool) error { ctx := stream.Context() chunker := chunk.New(&commitsSender{ @@ -163,7 +189,7 @@ func streamCommits(getCommits *GetCommits, stream gitalypb.CommitService_FindCom }) for getCommits.Scan() { - commit, err := getCommits.Commit(ctx, trailers) + commit, err := getCommits.Commit(ctx, trailers, shortStat) if err != nil { return err } @@ -172,6 +198,7 @@ func streamCommits(getCommits *GetCommits, stream gitalypb.CommitService_FindCom return err } } + if getCommits.Err() != nil { return fmt.Errorf("get commits: %v", getCommits.Err()) } @@ -181,9 +208,14 @@ func streamCommits(getCommits *GetCommits, stream gitalypb.CommitService_FindCom func getLogCommandSubCmd(req *gitalypb.FindCommitsRequest) git.SubCmd { logFormatOption := "--format=%H" + // To split the commits by '\x01' instead of '\n' + if req.GetIncludeShortstat() { + logFormatOption = "--format=%x01%H" + } if req.GetTrailers() { logFormatOption += "%x00%(trailers:unfold,separator=%x00)" } + subCmd := git.SubCmd{Name: "log", Flags: []git.Option{git.Flag{Name: logFormatOption}}} // We will perform the offset in Go because --follow doesn't play well with --skip. @@ -229,6 +261,75 @@ func getLogCommandSubCmd(req *gitalypb.FindCommitsRequest) git.SubCmd { if req.GetOrder() == gitalypb.FindCommitsRequest_TOPO { subCmd.Flags = append(subCmd.Flags, git.Flag{Name: "--topo-order"}) } + if req.GetIncludeShortstat() { + subCmd.Flags = append(subCmd.Flags, git.Flag{Name: "--shortstat"}) + } return subCmd } + +func parseStat(line string) (*gitalypb.CommitStatInfo, error) { + statInfo := &gitalypb.CommitStatInfo{} + + matched := statsPattern.FindStringSubmatch(line) + if len(matched) != 6 { + return nil, fmt.Errorf("unexpected stats format: %q", line) + } + + fileStr, addStr, delStr := matched[1], matched[3], matched[5] + + file64, err := strconv.ParseInt(fileStr, 10, 32) + if err != nil { + return nil, fmt.Errorf("parsing file count: %w", err) + } + statInfo.ChangedFiles = int32(file64) + + if len(addStr) > 0 { + add64, err := strconv.ParseInt(addStr, 10, 32) + if err != nil { + return nil, fmt.Errorf("parsing additions: %w", err) + } + + statInfo.Additions = int32(add64) + } + + if len(delStr) > 0 { + del64, err := strconv.ParseInt(delStr, 10, 32) + if err != nil { + return nil, fmt.Errorf("parsing deletions: %w", err) + } + + statInfo.Deletions = int32(del64) + } + + return statInfo, nil +} + +func splitStat(data []byte, atEOF bool) (int, []byte, error) { + // If there is no more data to be read then we are fine. + if atEOF && len(data) == 0 { + return 0, nil, io.EOF + } + + // Commits are separated by `\x01` bytes, so we require each commit to start with it. If + // that is not the case we return an error. + if !bytes.HasPrefix(data, []byte{'\x01'}) { + return 0, nil, fmt.Errorf("expected \\x01 prefix: %q", string(data)) + } + + // Skip the prefix. We only want to return the actual commit's data to the caller. + data = data[1:] + + // We scan until the next `\x01` byte. If there is none, we're either at EOF (in which case + // we just return remaining bytes) or we don't have sufficient data. + index := bytes.IndexByte(data, '\x01') + if index < 0 { + if atEOF { + return len(data) + 1, data, nil + } + + return 0, nil, nil + } + + return index + 1, data[:index], nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits_test.go index 0252e9c455..226dc3b335 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/find_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/find_commits_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -9,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -21,7 +23,7 @@ func TestFindCommitsFields(t *testing.T) { windows1251Message := testhelper.MustReadFile(t, "testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt") ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { id string @@ -177,7 +179,7 @@ func TestSuccessfulFindCommitsRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string @@ -435,7 +437,7 @@ func TestSuccessfulFindCommitsRequestWithAltGitObjectDirs(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) altObjectsDir := "./alt-objects" commitID := gittest.WriteCommit(t, cfg, repoPath, @@ -482,7 +484,7 @@ func TestSuccessfulFindCommitsRequestWithAmbiguousRef(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, false) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) // These are arbitrary SHAs in the repository. The important part is // that we create a branch using one of them with a different SHA so @@ -490,7 +492,7 @@ func TestSuccessfulFindCommitsRequestWithAmbiguousRef(t *testing.T) { branchName := "1e292f8fedd741b75372e19097c76d327140c312" commitSha := "6907208d755b60ebeacb2e9dfea74c92c3449a1f" - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "-b", branchName, commitSha) + gittest.Exec(t, cfg, "-C", repoPath, "branch", branchName, commitSha) request := &gitalypb.FindCommitsRequest{ Repository: repo, @@ -510,7 +512,7 @@ func TestFailureFindCommitsRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string @@ -554,7 +556,7 @@ func TestFindCommitsRequestWithFollowAndOffset(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) request := &gitalypb.FindCommitsRequest{ Repository: repo, @@ -581,7 +583,7 @@ func TestFindCommitsWithExceedingOffset(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) stream, err := client.FindCommits(ctx, &gitalypb.FindCommitsRequest{ Repository: repo, @@ -612,3 +614,231 @@ func getCommits(ctx context.Context, t *testing.T, request *gitalypb.FindCommits require.Equal(t, io.EOF, err) return commits } + +func TestFindCommits_withStats(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) + + type commitInfo struct { + id string + shortStats *gitalypb.CommitStatInfo + } + + testCases := []struct { + desc string + request *gitalypb.FindCommitsRequest + commitStats []commitInfo + }{ + { + desc: "no merges", + request: &gitalypb.FindCommitsRequest{ + Repository: repo, + Limit: 10, + SkipMerges: true, + IncludeShortstat: true, + Trailers: true, + }, + commitStats: []commitInfo{ + { + id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 0, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "c84ff944ff4529a70788a5e9003c2b7feae29047", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 0, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "55bc176024cfa3baaceb71db584c7e5df900ea65", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 1, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "4a24d82dbca5c11c61556f3b35ca472b7463187e", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 12, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "498214de67004b1da3d820901307bed2a68a8ef6", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 1, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 1, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "c347ca2e140aa667b968e51ed0ffe055501fe4f4", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 6, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "d59c60028b053793cecfb4022de34602e1a9218e", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 0, + Deletions: 6, + ChangedFiles: 1, + }, + }, + { + id: "a5391128b0ef5d21df5dd23d98557f4ef12fae20", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 6, + Deletions: 0, + ChangedFiles: 2, + }, + }, + { + id: "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 1, + Deletions: 0, + ChangedFiles: 1, + }, + }, + }, + }, + { + desc: "with merges", + request: &gitalypb.FindCommitsRequest{ + Repository: repo, + Limit: 5, + IncludeShortstat: true, + Trailers: true, + }, + commitStats: []commitInfo{ + { + id: "1e292f8fedd741b75372e19097c76d327140c312", + shortStats: nil, + }, + { + id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 0, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "7975be0116940bf2ad4321f79d02a55c5f7779aa", + shortStats: nil, + }, + { + id: "c84ff944ff4529a70788a5e9003c2b7feae29047", + shortStats: &gitalypb.CommitStatInfo{ + Additions: 0, + Deletions: 0, + ChangedFiles: 1, + }, + }, + { + id: "60ecb67744cb56576c30214ff52294f8ce2def98", + shortStats: nil, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + commits := getCommits(ctx, t, tc.request, client) + assert.Equal(t, len(tc.commitStats), len(commits)) + + for i, commit := range commits { + assert.Equal(t, tc.commitStats[i].id, commit.Id) + assert.Equal(t, tc.commitStats[i].shortStats, commit.ShortStats) + } + }) + } +} + +func BenchmarkCommitStats(b *testing.B) { + ctx := testhelper.Context(b) + _, repo, _, client := setupCommitServiceWithRepo(ctx, b) + request := &gitalypb.FindCommitsRequest{ + Repository: repo, + Limit: 100, + SkipMerges: true, + All: true, + Trailers: true, + } + + b.Run("without include_shortstat(N+1 query)", func(b *testing.B) { + benchmarkCommitStatsN(b, ctx, request, repo, client) + }) + + b.Run("with include_shortstat", func(b *testing.B) { + benchmarkFindCommitsWithStat(b, ctx, request, client) + }) +} + +func benchmarkCommitStatsN(b *testing.B, ctx context.Context, request *gitalypb.FindCommitsRequest, + repo *gitalypb.Repository, client gitalypb.CommitServiceClient, +) { + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + stream, err := client.FindCommits(ctx, request) + require.NoError(b, err) + + for { + response, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(b, err) + + for _, commit := range response.Commits { + _, err = client.CommitStats(ctx, &gitalypb.CommitStatsRequest{ + Repository: repo, + Revision: []byte(commit.GetId()), + }) + require.NoError(b, err) + } + } + } +} + +func benchmarkFindCommitsWithStat(b *testing.B, ctx context.Context, request *gitalypb.FindCommitsRequest, + client gitalypb.CommitServiceClient, +) { + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + stream, err := client.FindCommits(ctx, request) + require.NoError(b, err) + + for { + _, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(b, err) + } + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor.go index daaf623b88..3fa8bdcccc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor.go @@ -5,8 +5,8 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor_test.go index f850af9dd8..f1d522d338 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/isancestor_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/isancestor_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,12 +8,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -19,7 +21,7 @@ func TestCommitIsAncestorFailure(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) queries := []struct { Request *gitalypb.CommitIsAncestorRequest @@ -79,7 +81,7 @@ func TestCommitIsAncestorSuccess(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) queries := []struct { Request *gitalypb.CommitIsAncestorRequest @@ -166,7 +168,7 @@ func TestSuccessfulIsAncestorRequestWithAltGitObjectDirs(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) parentCommitID := git.ObjectID(text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "--verify", "HEAD"))) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages.go index af136a8541..4363011c06 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages.go @@ -9,10 +9,10 @@ import ( "sort" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) var errAmbigRef = errors.New("ambiguous reference") @@ -38,11 +38,7 @@ func (s *server) CommitLanguages(ctx context.Context, req *gitalypb.CommitLangua return nil, helper.ErrInternalf("looking up revision: %w", err) } - repoPath, err := repo.Path() - if err != nil { - return nil, helper.ErrInternalf("repository path: %w", err) - } - stats, err := s.linguist.Stats(ctx, repoPath, commitID) + stats, err := s.linguist.Stats(ctx, repo, commitID, s.catfileCache) if err != nil { return nil, helper.ErrInternalf("language stats: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages_test.go similarity index 55% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages_test.go index 82a676cd2d..fed295ff72 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/languages_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/languages_test.go @@ -1,23 +1,31 @@ +//go:build !gitaly_test_sha256 + package commit import ( + "context" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) func TestLanguages(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testLanguagesFeatured) +} + +func testLanguagesFeatured(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t, testcfg.WithRealLinguist()) cfg.SocketPath = startTestServices(t, cfg) - ctx := testhelper.Context(t) repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -32,31 +40,26 @@ func TestLanguages(t *testing.T) { resp, err := client.CommitLanguages(ctx, request) require.NoError(t, err) - require.NotZero(t, len(resp.Languages), "number of languages in response") - expectedLanguages := []*gitalypb.CommitLanguagesResponse_Language{ - {Name: "Ruby", Share: 66, Color: "#701516", FileCount: 4, Bytes: 2943}, - {Name: "JavaScript", Share: 22, Color: "#f1e05a", FileCount: 1, Bytes: 1014}, - {Name: "HTML", Share: 7, Color: "#e34c26", FileCount: 1, Bytes: 349}, - {Name: "CoffeeScript", Share: 2, Color: "#244776", FileCount: 1, Bytes: 107}, - // Modula-2 is a special case because Linguist has no color for it. This - // test case asserts that we invent a color for it (SHA256 of the name). - {Name: "Modula-2", Share: 2, Color: "#3fd5e0", FileCount: 1, Bytes: 95}, + {Name: "Ruby", Share: 65.28394, Color: "#701516", Bytes: 2943}, + {Name: "JavaScript", Share: 22.493345, Color: "#f1e05a", Bytes: 1014}, + {Name: "HTML", Share: 7.741792, Color: "#e34c26", Bytes: 349}, + {Name: "CoffeeScript", Share: 2.373558, Color: "#244776", Bytes: 107}, + {Name: "Modula-2", Share: 2.1073646, Color: "#10253f", Bytes: 95}, } - require.Equal(t, len(expectedLanguages), len(resp.Languages)) - - for i, el := range expectedLanguages { - actualLanguage := resp.Languages[i] - requireLanguageEqual(t, el, actualLanguage) - } + testhelper.ProtoEqual(t, expectedLanguages, resp.Languages) } func TestFileCountIsZeroWhenFeatureIsDisabled(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testFileCountIsZeroWhenFeatureIsDisabled) +} + +func testFileCountIsZeroWhenFeatureIsDisabled(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) request := &gitalypb.CommitLanguagesRequest{ Repository: repo, @@ -74,20 +77,15 @@ func TestFileCountIsZeroWhenFeatureIsDisabled(t *testing.T) { } } -func requireLanguageEqual(t *testing.T, expected, actual *gitalypb.CommitLanguagesResponse_Language) { - t.Helper() - - require.Equal(t, expected.Name, actual.Name) - require.Equal(t, expected.Color, actual.Color) - require.False(t, (expected.Share-actual.Share)*(expected.Share-actual.Share) >= 1.0, "shares do not match") - require.Equal(t, expected.Bytes, actual.Bytes) +func TestLanguagesEmptyRevision(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testLanguagesEmptyRevisionFeatured) } -func TestLanguagesEmptyRevision(t *testing.T) { +func testLanguagesEmptyRevisionFeatured(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) request := &gitalypb.CommitLanguagesRequest{ Repository: repo, @@ -107,10 +105,14 @@ func TestLanguagesEmptyRevision(t *testing.T) { } func TestInvalidCommitLanguagesRequestRevision(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testInvalidCommitLanguagesRequestRevisionFeatured) +} + +func testInvalidCommitLanguagesRequestRevisionFeatured(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) _, err := client.CommitLanguages(ctx, &gitalypb.CommitLanguagesRequest{ Repository: repo, @@ -120,10 +122,14 @@ func TestInvalidCommitLanguagesRequestRevision(t *testing.T) { } func TestAmbiguousRefCommitLanguagesRequestRevision(t *testing.T) { + testhelper.NewFeatureSets(featureflag.GoLanguageStats). + Run(t, testAmbiguousRefCommitLanguagesRequestRevisionFeatured) +} + +func testAmbiguousRefCommitLanguagesRequestRevisionFeatured(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) // gitlab-test repo has both a branch and a tag named 'v1.1.0' // b83d6e391c22777fca1ed3012fce84f633d7fed0 refs/heads/v1.1.0 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path.go index 9b8468c92f..48e87c7267 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path.go @@ -3,10 +3,10 @@ package commit import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) LastCommitForPath(ctx context.Context, in *gitalypb.LastCommitForPathRequest) (*gitalypb.LastCommitForPathResponse, error) { @@ -29,10 +29,11 @@ func (s *server) lastCommitForPath(ctx context.Context, in *gitalypb.LastCommitF } repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return nil, err } + defer cancel() options := in.GetGlobalOptions() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path_test.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path_test.go index fa040279cf..84a7297e5b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/last_commit_for_path_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/last_commit_for_path_test.go @@ -1,21 +1,23 @@ +//go:build !gitaly_test_sha256 + package commit import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestSuccessfulLastCommitForPathRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) commit := testhelper.GitLabTestCommit("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") @@ -75,43 +77,56 @@ func TestFailedLastCommitForPathRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} - testCases := []struct { - desc string - request *gitalypb.LastCommitForPathRequest - code codes.Code + for _, tc := range []struct { + desc string + request *gitalypb.LastCommitForPathRequest + expectedErr error }{ { - desc: "Invalid repository", - request: &gitalypb.LastCommitForPathRequest{Repository: invalidRepo}, - code: codes.InvalidArgument, + desc: "Invalid repository", + request: &gitalypb.LastCommitForPathRequest{ + Repository: invalidRepo, + Revision: []byte("some-branch"), + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"fake\"", + "repo scoped: invalid Repository", + )), }, { - desc: "Repository is nil", - request: &gitalypb.LastCommitForPathRequest{Revision: []byte("some-branch")}, - code: codes.InvalidArgument, + desc: "Repository is nil", + request: &gitalypb.LastCommitForPathRequest{ + Revision: []byte("some-branch"), + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), }, { - desc: "Revision is missing", - request: &gitalypb.LastCommitForPathRequest{Repository: repo, Path: []byte("foo/bar")}, - code: codes.InvalidArgument, + desc: "Revision is missing", + request: &gitalypb.LastCommitForPathRequest{ + Repository: repo, Path: []byte("foo/bar"), + }, + expectedErr: helper.ErrInvalidArgumentf("empty revision"), }, { desc: "Revision is invalid", request: &gitalypb.LastCommitForPathRequest{ - Repository: repo, Path: []byte("foo/bar"), Revision: []byte("--output=/meow"), + Repository: repo, + Path: []byte("foo/bar"), + Revision: []byte("--output=/meow"), }, - code: codes.InvalidArgument, + expectedErr: helper.ErrInvalidArgumentf("revision can't start with '-'"), }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - _, err := client.LastCommitForPath(ctx, testCase.request) - testhelper.RequireGrpcCode(t, err, testCase.code) + } { + t.Run(tc.desc, func(t *testing.T) { + _, err := client.LastCommitForPath(ctx, tc.request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } @@ -120,7 +135,7 @@ func TestSuccessfulLastCommitWithGlobCharacters(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) // This is an arbitrary blob known to exist in the test repository const blobID = "c60514b6d3d6bf4bec1030f70026e34dfbd69ad5" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits.go index d5fa18622e..ff368f6d7d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits.go @@ -4,12 +4,12 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func verifyListAllCommitsRequest(request *gitalypb.ListAllCommitsRequest) error { @@ -30,10 +30,11 @@ func (s *server) ListAllCommits( ctx := stream.Context() repo := s.localrepo(request.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternalf("creating object reader: %w", err) } + defer cancel() // If we've got a pagination token, then we will only start to print commits as soon as // we've seen the token. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits_test.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits_test.go index e6ceb94636..ae30a7fa3e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_all_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_all_commits_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -8,10 +10,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/protobuf/types/known/timestamppb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestListAllCommits(t *testing.T) { @@ -47,7 +48,7 @@ func TestListAllCommits(t *testing.T) { }) t.Run("normal repo", func(t *testing.T) { - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) stream, err := client.ListAllCommits(ctx, &gitalypb.ListAllCommitsRequest{ Repository: repo, @@ -78,7 +79,7 @@ func TestListAllCommits(t *testing.T) { }) t.Run("pagination", func(t *testing.T) { - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) stream, err := client.ListAllCommits(ctx, &gitalypb.ListAllCommitsRequest{ Repository: repo, @@ -95,7 +96,7 @@ func TestListAllCommits(t *testing.T) { }) t.Run("quarantine directory", func(t *testing.T) { - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) quarantineDir := filepath.Join("objects", "incoming-123456") require.NoError(t, os.Mkdir(filepath.Join(repoPath, quarantineDir), 0o777)) @@ -115,7 +116,6 @@ func TestListAllCommits(t *testing.T) { // manually here and write the commit into the quarantine object directory. commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithAlternateObjectDirectory(filepath.Join(repoPath, quarantineDir)), - gittest.WithParents(), ) // We now expect only the quarantined commit to be returned. @@ -125,23 +125,13 @@ func TestListAllCommits(t *testing.T) { require.NoError(t, err) require.Equal(t, []*gitalypb.GitCommit{{ - Id: commitID.String(), - Subject: []byte("message"), - Body: []byte("message"), - BodySize: 7, - TreeId: "4b825dc642cb6eb9a060e54bf8d69288fbee4904", - Author: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Id: commitID.String(), + Subject: []byte("message"), + Body: []byte("message"), + BodySize: 7, + TreeId: "4b825dc642cb6eb9a060e54bf8d69288fbee4904", + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, }}, receiveCommits(t, stream)) }) } @@ -150,7 +140,7 @@ func BenchmarkListAllCommits(b *testing.B) { b.StopTimer() ctx := testhelper.Context(b) - _, repo, _, client := setupCommitServiceWithRepo(ctx, b, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, b) b.Run("ListAllCommits", func(b *testing.B) { b.ReportAllocs() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits.go index 826edb9ee0..7fc5858fe8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits.go @@ -5,12 +5,12 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func verifyListCommitsRequest(request *gitalypb.ListCommitsRequest) error { @@ -39,10 +39,11 @@ func (s *server) ListCommits( ctx := stream.Context() repo := s.localrepo(request.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(fmt.Errorf("creating object reader: %w", err)) } + defer cancel() revlistOptions := []gitpipe.RevlistOption{} @@ -83,6 +84,14 @@ func (s *server) ListCommits( revlistOptions = append(revlistOptions, gitpipe.WithAuthor(request.GetAuthor())) } + if request.GetIgnoreCase() { + revlistOptions = append(revlistOptions, gitpipe.WithIgnoreCase(request.GetIgnoreCase())) + } + + if len(request.GetCommitMessagePatterns()) > 0 { + revlistOptions = append(revlistOptions, gitpipe.WithCommitMessagePatterns(request.GetCommitMessagePatterns())) + } + // If we've got a pagination token, then we will only start to print commits as soon as // we've seen the token. if token := request.GetPaginationParams().GetPageToken(); token != "" { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid.go index 7ef89f58aa..9bd423a8e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid.go @@ -3,10 +3,10 @@ package commit import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -25,10 +25,11 @@ func (s *server) ListCommitsByOid(in *gitalypb.ListCommitsByOidRequest, stream g ctx := stream.Context() repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() sender := chunk.New(&commitsByOidSender{stream: stream}) listCommitsbyOidHistogram.Observe(float64(len(in.Oid))) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid_test.go index 100f2eb22f..583224673e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_oid_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_oid_test.go @@ -1,18 +1,20 @@ +//go:build !gitaly_test_sha256 + package commit import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestSuccessfulListCommitsByOidRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) commits := []*gitalypb.GitCommit{ { @@ -154,7 +156,7 @@ func TestSuccessfulListCommitsByOidLargeRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) req := &gitalypb.ListCommitsByOidRequest{ Oid: masterCommitids, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name.go index f6d84e1cdd..77c8b3e61a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name.go @@ -1,11 +1,11 @@ package commit import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -13,10 +13,11 @@ func (s *server) ListCommitsByRefName(in *gitalypb.ListCommitsByRefNameRequest, ctx := stream.Context() repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternal(err) } + defer cancel() sender := chunk.New(&commitsByRefNameSender{stream: stream}) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name_test.go index 0fce1f01dc..73ce4a9efe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_by_ref_name_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_by_ref_name_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -5,15 +7,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestSuccessfulListCommitsByRefNameRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string @@ -169,7 +171,7 @@ func TestSuccessfulListCommitsByRefNameLargeRequest(t *testing.T) { } ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) refNames := [][]byte{} for _, refName := range repositoryRefNames { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_test.go index 75a59a6ace..9a22fb07aa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_commits_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_commits_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,15 +8,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) func TestListCommits(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) for _, tc := range []struct { desc string @@ -256,6 +258,40 @@ func TestListCommits(t *testing.T) { gittest.CommitsByID["1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"], }, }, + { + desc: "revisions by multiple message patterns", + request: &gitalypb.ListCommitsRequest{ + Repository: repo, + Revisions: []string{ + "few-commits", + }, + CommitMessagePatterns: [][]byte{ + []byte("Commit #10"), + []byte("Commit #9 alternate"), + }, + }, + expectedCommits: []*gitalypb.GitCommit{ + gittest.CommitsByID["bf6e164cac2dc32b1f391ca4290badcbe4ffc5fb"], + gittest.CommitsByID["48ca272b947f49eee601639d743784a176574a09"], + }, + }, + { + desc: "revisions by case insensitive commit message", + request: &gitalypb.ListCommitsRequest{ + Repository: repo, + Revisions: []string{ + "few-commits", + }, + IgnoreCase: true, + CommitMessagePatterns: [][]byte{ + []byte("commit #1"), + }, + }, + expectedCommits: []*gitalypb.GitCommit{ + gittest.CommitsByID["bf6e164cac2dc32b1f391ca4290badcbe4ffc5fb"], + gittest.CommitsByID["79b06233d3dc769921576771a4e8bee4b439595d"], + }, + }, } { t.Run(tc.desc, func(t *testing.T) { stream, err := client.ListCommits(ctx, tc.request) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files.go index 4aa1fd448f..9a1da2197a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files.go @@ -5,11 +5,11 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -81,7 +81,7 @@ func (s *server) listFiles(repo git.RepositoryExecutor, revision string, stream sender := chunk.New(&listFilesSender{stream: stream}) - for parser := lstree.NewParser(cmd); ; { + for parser := lstree.NewParser(cmd, git.ObjectHashSHA1); ; { entry, err := parser.NextEntry() if err == io.EOF { break diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files_test.go index cb4857b4df..628cccc289 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_files_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_files_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -5,9 +7,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -38,7 +40,7 @@ var defaultFiles = [][]byte{ func TestListFiles_success(t *testing.T) { ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) gittest.Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/test-do-not-touch") @@ -125,7 +127,7 @@ func TestListFiles_unbornBranch(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, _, _, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, _, _, client := setupCommitServiceWithRepo(ctx, t) repo, _ := gittest.CreateRepository(ctx, t, cfg) tests := []struct { @@ -199,7 +201,7 @@ func TestListFiles_failure(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, _, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, _, _, client := setupCommitServiceWithRepo(ctx, t) tests := []struct { desc string @@ -253,7 +255,7 @@ func TestListFiles_invalidRevision(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) stream, err := client.ListFiles(ctx, &gitalypb.ListFilesRequest{ Repository: repo, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree.go index 99c3ea0a92..7e1c35b830 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree.go @@ -5,12 +5,12 @@ import ( "io" "sort" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) var maxNumStatBatchSize = 10 @@ -35,10 +35,11 @@ func (s *server) listLastCommitsForTree(in *gitalypb.ListLastCommitsForTreeReque ctx := stream.Context() repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() batch := make([]*gitalypb.ListLastCommitsForTreeResponse_CommitForTree, 0, maxNumStatBatchSize) entries, err := getLSTreeEntries(parser) @@ -122,7 +123,7 @@ func (s *server) newLSTreeParser(in *gitalypb.ListLastCommitsForTreeRequest, str return nil, nil, err } - return cmd, lstree.NewParser(cmd), nil + return cmd, lstree.NewParser(cmd, git.ObjectHashSHA1), nil } func sendCommitsForTree(batch []*gitalypb.ListLastCommitsForTreeResponse_CommitForTree, stream gitalypb.CommitService_ListLastCommitsForTreeServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree_test.go index f848e48e66..e9d8978343 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/list_last_commits_for_tree_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/list_last_commits_for_tree_test.go @@ -1,19 +1,17 @@ +//go:build !gitaly_test_sha256 + package commit import ( - "bytes" "io" - "os" - "path/filepath" "testing" "unicode/utf8" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -26,7 +24,7 @@ func TestSuccessfulListLastCommitsForTreeRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { desc string @@ -215,7 +213,7 @@ func TestFailedListLastCommitsForTreeRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "broken", RelativePath: "path"} @@ -323,7 +321,7 @@ func TestNonUtf8ListLastCommitsForTreeRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) // This is an arbitrary blob known to exist in the test repository const blobID = "c60514b6d3d6bf4bec1030f70026e34dfbd69ad5" @@ -354,55 +352,66 @@ func TestSuccessfulListLastCommitsForTreeRequestWithGlobCharacters(t *testing.T) t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, false) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) - path := ":wq" - err := os.Mkdir(filepath.Join(repoPath, path), 0o755) - require.NoError(t, err) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(gittest.TreeEntry{ + Path: ":wq", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "something"}, + }), + })) - gittest.Exec(t, cfg, "-C", repoPath, "mv", "README.md", path) - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-a", "-m", "renamed test file") - commitID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")) + t.Run("with literal pathspecs", func(t *testing.T) { + stream, err := client.ListLastCommitsForTree(ctx, &gitalypb.ListLastCommitsForTreeRequest{ + Repository: repo, + Revision: commitID.String(), + Path: []byte(":wq"), + GlobalOptions: &gitalypb.GlobalOptions{LiteralPathspecs: true}, + Limit: 100, + }) + require.NoError(t, err) + require.Equal(t, []string{":wq"}, fetchCommitPaths(t, stream)) + }) - request := &gitalypb.ListLastCommitsForTreeRequest{ - Repository: repo, - Revision: commitID, - Path: []byte(path), - GlobalOptions: &gitalypb.GlobalOptions{LiteralPathspecs: true}, - Limit: 100, - Offset: 0, - } - stream, err := client.ListLastCommitsForTree(ctx, request) - require.NoError(t, err) - - assert.True(t, fileExistsInCommits(t, stream, path)) - - request.GlobalOptions = &gitalypb.GlobalOptions{LiteralPathspecs: false} - stream, err = client.ListLastCommitsForTree(ctx, request) - require.NoError(t, err) - assert.False(t, fileExistsInCommits(t, stream, path)) + t.Run("without literal pathspecs", func(t *testing.T) { + stream, err := client.ListLastCommitsForTree(ctx, &gitalypb.ListLastCommitsForTreeRequest{ + Repository: repo, + Revision: commitID.String(), + Path: []byte(":wq"), + GlobalOptions: &gitalypb.GlobalOptions{LiteralPathspecs: false}, + Limit: 100, + }) + require.NoError(t, err) + require.Nil(t, fetchCommitPaths(t, stream)) + }) } func fileExistsInCommits(t *testing.T, stream gitalypb.CommitService_ListLastCommitsForTreeClient, path string) bool { t.Helper() - var filenameFound bool - for { - fetchedCommits, err := stream.Recv() - if err == io.EOF { - break - } - - require.NoError(t, err) - - commits := fetchedCommits.GetCommits() - - for _, fetchedCommit := range commits { - if bytes.Equal(fetchedCommit.PathBytes, []byte(path)) { - filenameFound = true - } + for _, commitPath := range fetchCommitPaths(t, stream) { + if commitPath == path { + return true } } - return filenameFound + return false +} + +func fetchCommitPaths(t *testing.T, stream gitalypb.CommitService_ListLastCommitsForTreeClient) []string { + t.Helper() + + var files []string + for { + response, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + + for _, commit := range response.GetCommits() { + files = append(files, string(commit.PathBytes)) + } + } + + return files } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame.go index 8bd76ef109..41c3c83c89 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame.go @@ -6,9 +6,9 @@ import ( "regexp" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame_test.go index 5de729b04d..caaf0fba18 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/raw_blame_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/raw_blame_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -6,9 +8,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) @@ -16,7 +18,7 @@ func TestSuccessfulRawBlameRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { revision, path, data, blameRange []byte @@ -75,7 +77,7 @@ func TestFailedRawBlameRequest(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) invalidRepo := &gitalypb.Repository{StorageName: "fake", RelativePath: "path"} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/server.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/server.go index fe4d2d4337..3965b1dace 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/server.go @@ -1,13 +1,13 @@ package commit import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats.go index 28e2ab7cde..1b9ba02867 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/stats.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats.go @@ -7,9 +7,9 @@ import ( "strconv" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) CommitStats(ctx context.Context, in *gitalypb.CommitStatsRequest) (*gitalypb.CommitStatsResponse, error) { @@ -39,7 +39,7 @@ func (s *server) commitStats(ctx context.Context, in *gitalypb.CommitStatsReques var args []string if len(commit.GetParentIds()) == 0 { - args = append(args, git.EmptyTreeOID.String(), commit.Id) + args = append(args, git.ObjectHashSHA1.EmptyTreeOID.String(), commit.Id) } else { args = append(args, commit.Id+"^", commit.Id) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats_test.go new file mode 100644 index 0000000000..7f506f65dd --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/stats_test.go @@ -0,0 +1,142 @@ +//go:build !gitaly_test_sha256 + +package commit + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestCommitStatsSuccess(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) + + tests := []struct { + desc string + revision string + oid string + additions, deletions int32 + }{ + { + desc: "multiple changes, multiple files", + revision: "test-do-not-touch", + oid: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", + additions: 27, + deletions: 59, + }, + { + desc: "multiple changes, multiple files, reference by commit ID", + revision: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", + oid: "899d3d27b04690ac1cd9ef4d8a74fde0667c57f1", + additions: 27, + deletions: 59, + }, + { + desc: "merge commit", + revision: "60ecb67", + oid: "60ecb67744cb56576c30214ff52294f8ce2def98", + additions: 1, + deletions: 0, + }, + { + desc: "binary file", + revision: "ae73cb0", + oid: "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", + additions: 0, + deletions: 0, + }, + { + desc: "initial commit", + revision: "1a0b36b3", + oid: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", + additions: 43, + deletions: 0, + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + resp, err := client.CommitStats(ctx, &gitalypb.CommitStatsRequest{ + Repository: repo, + Revision: []byte(tc.revision), + }) + require.NoError(t, err) + + assert.Equal(t, tc.oid, resp.GetOid()) + assert.Equal(t, tc.additions, resp.GetAdditions()) + assert.Equal(t, tc.deletions, resp.GetDeletions()) + }) + } +} + +func TestCommitStatsFailure(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, repo, _, client := setupCommitServiceWithRepo(ctx, t) + + for _, tc := range []struct { + desc string + request *gitalypb.CommitStatsRequest + expectedErr error + }{ + { + desc: "repo not found", + request: &gitalypb.CommitStatsRequest{ + Repository: &gitalypb.Repository{ + StorageName: repo.GetStorageName(), + RelativePath: "bar.git", + }, + Revision: []byte("test-do-not-touch"), + }, + expectedErr: helper.ErrNotFoundf(gitalyOrPraefect( + fmt.Sprintf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")), + "accessor call: route repository accessor: consistent storages: repository \"default\"/\"bar.git\" not found", + )), + }, + { + desc: "storage not found", + request: &gitalypb.CommitStatsRequest{ + Repository: &gitalypb.Repository{ + StorageName: "foo", + RelativePath: "bar.git", + }, + Revision: []byte("test-do-not-touch"), + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"foo\"", + "repo scoped: invalid Repository", + )), + }, + { + desc: "ref not found", + request: &gitalypb.CommitStatsRequest{ + Repository: repo, + Revision: []byte("non/existing"), + }, + expectedErr: helper.ErrInternalf("object not found"), + }, + { + desc: "invalid revision", + request: &gitalypb.CommitStatsRequest{ + Repository: repo, + Revision: []byte("--outpu=/meow"), + }, + expectedErr: helper.ErrInvalidArgumentf("revision can't start with '-'"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + _, err := client.CommitStats(ctx, tc.request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signed-text b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signed-text similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signed-text rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/7b5160f9bb23a3d58a0accdbe89da13b96b1ece9-ssh-signed-text diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signed-text b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signed-text similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signed-text rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-5937ac0a7beb003549fc5fd26fc247adbce4a52e-signed-text diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signature.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signature.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signature.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signature.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signed-text.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signed-text.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signed-text.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee-signed-no-newline-signed-text.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee.commit b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee.commit similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee.commit rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/dc00eb001f41dfac08192ead79c2377c588b82ee.commit diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/file-with-multiple-chunks-truncated-blob.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/file-with-multiple-chunks-truncated-blob.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/file-with-multiple-chunks-truncated-blob.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/file-with-multiple-chunks-truncated-blob.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/files-ruby-popen-e63f41f-blame.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/files-ruby-popen-e63f41f-blame.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/files-ruby-popen-e63f41f-blame.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/files-ruby-popen-e63f41f-blame.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signed-text b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signed-text similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signed-text rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitaly-test-commit-8cf8e80a5a0546e391823c250f2b26b9cf15ce88-signed-text diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signed-text b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signed-text similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signed-text rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/gitlab-test-commit-a17a9f66543673edf0a3d1c6b93bdda3fe600f32-signed-text diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/maintenance-md-blob.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/maintenance-md-blob.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/maintenance-md-blob.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/maintenance-md-blob.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/with-space-readme-md-blob.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/with-space-readme-md-blob.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testdata/with-space-readme-md-blob.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testdata/with-space-readme-md-blob.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testhelper_test.go similarity index 53% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testhelper_test.go index b1b7daf037..e3bf2327cc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/testhelper_test.go @@ -1,23 +1,25 @@ +//go:build !gitaly_test_sha256 + package commit import ( "context" "fmt" "io" - "path/filepath" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -26,8 +28,8 @@ func TestMain(m *testing.M) { } // setupCommitService makes a basic configuration and starts the service with the client. -func setupCommitService(ctx context.Context, t testing.TB) (config.Cfg, gitalypb.CommitServiceClient) { - cfg, _, _, client := setupCommitServiceCreateRepo(ctx, t, func(ctx context.Context, tb testing.TB, cfg config.Cfg) (*gitalypb.Repository, string) { +func setupCommitService(ctx context.Context, tb testing.TB) (config.Cfg, gitalypb.CommitServiceClient) { + cfg, _, _, client := setupCommitServiceCreateRepo(ctx, tb, func(ctx context.Context, tb testing.TB, cfg config.Cfg) (*gitalypb.Repository, string) { return nil, "" }) return cfg, client @@ -35,41 +37,34 @@ func setupCommitService(ctx context.Context, t testing.TB) (config.Cfg, gitalypb // setupCommitServiceWithRepo makes a basic configuration, creates a test repository and starts the service with the client. func setupCommitServiceWithRepo( - ctx context.Context, t testing.TB, bare bool, + ctx context.Context, tb testing.TB, ) (config.Cfg, *gitalypb.Repository, string, gitalypb.CommitServiceClient) { - return setupCommitServiceCreateRepo(ctx, t, func(ctx context.Context, tb testing.TB, cfg config.Cfg) (*gitalypb.Repository, string) { + return setupCommitServiceCreateRepo(ctx, tb, func(ctx context.Context, tb testing.TB, cfg config.Cfg) (*gitalypb.Repository, string) { repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) - - if !bare { - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "master") - } - return repo, repoPath }) } func setupCommitServiceCreateRepo( ctx context.Context, - t testing.TB, + tb testing.TB, createRepo func(context.Context, testing.TB, config.Cfg) (*gitalypb.Repository, string), ) (config.Cfg, *gitalypb.Repository, string, gitalypb.CommitServiceClient) { - cfg := testcfg.Build(t) + cfg := testcfg.Build(tb) - cfg.SocketPath = startTestServices(t, cfg) - client := newCommitServiceClient(t, cfg.SocketPath) + cfg.SocketPath = startTestServices(tb, cfg) + client := newCommitServiceClient(tb, cfg.SocketPath) - repo, repoPath := createRepo(ctx, t, cfg) + repo, repoPath := createRepo(ctx, tb, cfg) return cfg, repo, repoPath, client } -func startTestServices(t testing.TB, cfg config.Cfg) string { - t.Helper() - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { +func startTestServices(tb testing.TB, cfg config.Cfg) string { + tb.Helper() + return testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterCommitServiceServer(srv, NewServer( deps.GetLocator(), deps.GetGitCmdFactory(), @@ -90,15 +85,15 @@ func startTestServices(t testing.TB, cfg config.Cfg) string { }) } -func newCommitServiceClient(t testing.TB, serviceSocketPath string) gitalypb.CommitServiceClient { - t.Helper() +func newCommitServiceClient(tb testing.TB, serviceSocketPath string) gitalypb.CommitServiceClient { + tb.Helper() connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serviceSocketPath, connOpts...) - require.NoError(t, err) - t.Cleanup(func() { conn.Close() }) + require.NoError(tb, err) + tb.Cleanup(func() { conn.Close() }) return gitalypb.NewCommitServiceClient(conn) } @@ -116,14 +111,14 @@ type gitCommitsGetter interface { GetCommits() []*gitalypb.GitCommit } -func createCommits(t testing.TB, cfg config.Cfg, repoPath, branch string, commitCount int, parent git.ObjectID) git.ObjectID { +func createCommits(tb testing.TB, cfg config.Cfg, repoPath, branch string, commitCount int, parent git.ObjectID) git.ObjectID { for i := 0; i < commitCount; i++ { var parents []git.ObjectID if parent != "" { parents = append(parents, parent) } - parent = gittest.WriteCommit(t, cfg, repoPath, + parent = gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch(branch), gittest.WithMessage(fmt.Sprintf("%s branch Empty commit %d", branch, i)), gittest.WithParents(parents...), @@ -133,8 +128,8 @@ func createCommits(t testing.TB, cfg config.Cfg, repoPath, branch string, commit return parent } -func getAllCommits(t testing.TB, getter func() (gitCommitsGetter, error)) []*gitalypb.GitCommit { - t.Helper() +func getAllCommits(tb testing.TB, getter func() (gitCommitsGetter, error)) []*gitalypb.GitCommit { + tb.Helper() var commits []*gitalypb.GitCommit for { @@ -142,8 +137,15 @@ func getAllCommits(t testing.TB, getter func() (gitCommitsGetter, error)) []*git if err == io.EOF { return commits } - require.NoError(t, err) + require.NoError(tb, err) commits = append(commits, resp.GetCommits()...) } } + +func gitalyOrPraefect(gitalyMsg, praefectMsg string) string { + if testhelper.IsPraefectEnabled() { + return praefectMsg + } + return gitalyMsg +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries.go index 96bf79693a..2a24895267 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries.go @@ -8,12 +8,12 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -70,6 +70,7 @@ func (s *server) sendTreeEntries( repo *localrepo.Repo, revision, path string, recursive bool, + skipFlatPaths bool, sort gitalypb.GetTreeEntriesRequest_SortBy, p *gitalypb.PaginationParameter, ) error { @@ -147,16 +148,19 @@ func (s *server) sendTreeEntries( } } else { var err error + var cancel func() - objectReader, err = s.catfileCache.ObjectReader(stream.Context(), repo) + objectReader, cancel, err = s.catfileCache.ObjectReader(stream.Context(), repo) if err != nil { return err } + defer cancel() - objectInfoReader, err = s.catfileCache.ObjectInfoReader(stream.Context(), repo) + objectInfoReader, cancel, err = s.catfileCache.ObjectInfoReader(stream.Context(), repo) if err != nil { return err } + defer cancel() entries, err = catfile.TreeEntries(ctx, objectReader, objectInfoReader, revision, path) if err != nil { @@ -184,7 +188,7 @@ func (s *server) sendTreeEntries( treeSender.SetPaginationCursor(cursor) } - if !recursive { + if !recursive && !skipFlatPaths { // When we're not doing a recursive request, then we need to populate flat // paths. A flat path of a tree entry refers to the first subtree of that // entry which either has at least one blob or more than two subtrees. In @@ -293,7 +297,7 @@ func (s *server) GetTreeEntries(in *gitalypb.GetTreeEntriesRequest, stream gital revision := string(in.GetRevision()) path := string(in.GetPath()) - return s.sendTreeEntries(stream, repo, revision, path, in.Recursive, in.GetSort(), in.GetPaginationParams()) + return s.sendTreeEntries(stream, repo, revision, path, in.Recursive, in.SkipFlatPaths, in.GetSort(), in.GetPaginationParams()) } func paginateTreeEntries(entries []*gitalypb.TreeEntry, p *gitalypb.PaginationParameter) ([]*gitalypb.TreeEntry, string, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries_test.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries_test.go index e27e2286b5..e763619a4a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entries_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entries_test.go @@ -1,71 +1,71 @@ +//go:build !gitaly_test_sha256 + package commit import ( "errors" - "fmt" "io" - "os" - "path/filepath" - "strings" + "strconv" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) func TestGetTreeEntries_curlyBraces(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, false) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) - normalFolderName := "issue-46261/folder" - curlyFolderName := "issue-46261/{{curly}}" - normalFolder := filepath.Join(repoPath, normalFolderName) - curlyFolder := filepath.Join(repoPath, curlyFolderName) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(gittest.TreeEntry{ + Path: "issue-46261", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + Path: "folder", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "test1.txt", Mode: "100644", Content: "test1"}, + }), + }, + { + Path: "{{curly}}", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "test2.txt", Mode: "100644", Content: "test2"}, + }), + }, + }), + })) - require.NoError(t, os.MkdirAll(normalFolder, 0o755)) - require.NoError(t, os.MkdirAll(curlyFolder, 0o755)) - - testhelper.MustRunCommand(t, nil, "touch", filepath.Join(normalFolder, "/test1.txt")) - testhelper.MustRunCommand(t, nil, "touch", filepath.Join(curlyFolder, "/test2.txt")) - - gittest.Exec(t, cfg, "-C", repoPath, "add", "--all") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-m", "Test commit") - - testCases := []struct { - description string - revision []byte - path []byte - recursive bool - filename []byte + for _, tc := range []struct { + desc string + revision []byte + path []byte + recursive bool + filename []byte }{ { - description: "with a normal folder", - revision: []byte("master"), - path: []byte(normalFolderName), - filename: []byte("issue-46261/folder/test1.txt"), + desc: "with a normal folder", + revision: []byte("master"), + path: []byte("issue-46261/folder"), + filename: []byte("issue-46261/folder/test1.txt"), }, { - description: "with a folder with curly braces", - revision: []byte("master"), - path: []byte(curlyFolderName), - filename: []byte("issue-46261/{{curly}}/test2.txt"), + desc: "with a folder with curly braces", + revision: []byte("master"), + path: []byte("issue-46261/{{curly}}"), + filename: []byte("issue-46261/{{curly}}/test2.txt"), }, - } - - for _, testCase := range testCases { - t.Run(testCase.description, func(t *testing.T) { + } { + t.Run(tc.desc, func(t *testing.T) { request := &gitalypb.GetTreeEntriesRequest{ Repository: repo, - Revision: []byte("HEAD"), - Path: testCase.path, - Recursive: testCase.recursive, + Revision: []byte(commitID.String()), + Path: tc.path, + Recursive: tc.recursive, } c, err := client.GetTreeEntries(ctx, request) @@ -73,7 +73,7 @@ func TestGetTreeEntries_curlyBraces(t *testing.T) { fetchedEntries, _ := getTreeEntriesFromTreeEntryClient(t, c, nil) require.Equal(t, 1, len(fetchedEntries)) - require.Equal(t, testCase.filename, fetchedEntries[0].FlatPath) + require.Equal(t, tc.filename, fetchedEntries[0].FlatPath) }) } } @@ -85,7 +85,7 @@ func TestGetTreeEntries_successful(t *testing.T) { commitID := "d25b6d94034242f3930dfcfeb6d8d9aac3583992" rootOid := "21bdc8af908562ae485ed46d71dd5426c08b084a" - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) rootEntries := []*gitalypb.TreeEntry{ { @@ -330,16 +330,29 @@ func TestGetTreeEntries_successful(t *testing.T) { }, } + stripFlatPaths := func(entries []*gitalypb.TreeEntry) []*gitalypb.TreeEntry { + strippedEntries := make([]*gitalypb.TreeEntry, 0, len(entries)) + + for _, entry := range entries { + entry := proto.Clone(entry).(*gitalypb.TreeEntry) + entry.FlatPath = nil + strippedEntries = append(strippedEntries, entry) + } + + return strippedEntries + } + testCases := []struct { - description string - revision []byte - path []byte - recursive bool - sortBy gitalypb.GetTreeEntriesRequest_SortBy - entries []*gitalypb.TreeEntry - pageToken string - pageLimit int32 - cursor string + description string + revision []byte + path []byte + recursive bool + sortBy gitalypb.GetTreeEntriesRequest_SortBy + entries []*gitalypb.TreeEntry + pageToken string + pageLimit int32 + cursor string + skipFlatPaths bool }{ { description: "with root path", @@ -347,12 +360,26 @@ func TestGetTreeEntries_successful(t *testing.T) { path: []byte("."), entries: rootEntries, }, + { + description: "with root path and disabled flat paths", + revision: []byte(commitID), + path: []byte("."), + skipFlatPaths: true, + entries: stripFlatPaths(rootEntries), + }, { description: "with a folder", revision: []byte(commitID), path: []byte("files"), entries: filesDirEntries, }, + { + description: "with a folder and disabled flat paths", + revision: []byte(commitID), + path: []byte("files"), + skipFlatPaths: true, + entries: stripFlatPaths(filesDirEntries), + }, { description: "with recursive", revision: []byte(commitID), @@ -454,11 +481,12 @@ func TestGetTreeEntries_successful(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.description, func(t *testing.T) { request := &gitalypb.GetTreeEntriesRequest{ - Repository: repo, - Revision: testCase.revision, - Path: testCase.path, - Recursive: testCase.recursive, - Sort: testCase.sortBy, + Repository: repo, + Revision: testCase.revision, + Path: testCase.path, + Recursive: testCase.recursive, + Sort: testCase.sortBy, + SkipFlatPaths: testCase.skipFlatPaths, } if testCase.pageToken != "" || testCase.pageLimit > 0 { @@ -472,7 +500,7 @@ func TestGetTreeEntries_successful(t *testing.T) { require.NoError(t, err) fetchedEntries, cursor := getTreeEntriesFromTreeEntryClient(t, c, nil) - require.Equal(t, testCase.entries, fetchedEntries) + testhelper.ProtoEqual(t, testCase.entries, fetchedEntries) if testCase.pageLimit > 0 && len(testCase.entries) < len(rootEntries) { require.NotNil(t, cursor) @@ -488,7 +516,7 @@ func TestGetTreeEntries_unsuccessful(t *testing.T) { commitID := "d25b6d94034242f3930dfcfeb6d8d9aac3583992" - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { description string @@ -535,53 +563,58 @@ func TestGetTreeEntries_deepFlatpath(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, false) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) - folderName := "1/2/3/4/5/6/7/8/9/10/11/12" - require.GreaterOrEqual(t, strings.Count(strings.Trim(folderName, "/"), "/"), defaultFlatTreeRecursion, "sanity check: construct folder deeper than default recursion value") + nestingLevel := 12 + require.Greater(t, nestingLevel, defaultFlatTreeRecursion, "sanity check: construct folder deeper than default recursion value") - nestedFolder := filepath.Join(repoPath, folderName) - require.NoError(t, os.MkdirAll(nestedFolder, 0o755)) - // put single file into the deepest directory - testhelper.MustRunCommand(t, nil, "touch", filepath.Join(nestedFolder, ".gitkeep")) - gittest.Exec(t, cfg, "-C", repoPath, "add", "--all") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-m", "Deep folder struct") + // We create a tree structure that is one deeper than the flat-tree recursion limit. + var treeID git.ObjectID + for i := nestingLevel; i >= 0; i-- { + var treeEntry gittest.TreeEntry + if treeID == "" { + treeEntry = gittest.TreeEntry{Path: ".gitkeep", Mode: "100644", Content: "something"} + } else { + // We use a numbered directory name to make it easier to see when things get + // truncated. + treeEntry = gittest.TreeEntry{Path: strconv.Itoa(i), Mode: "040000", OID: treeID} + } - commitID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")) - rootOid := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD^{tree}")) + treeID = gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{treeEntry}) + } + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTree(treeID)) - // make request to folder that contains nothing except one folder - request := &gitalypb.GetTreeEntriesRequest{ + // We make a non-recursive request which tries to fetch tree entrie for the tree structure + // we have created above. This should return a single entry, which is the directory we're + // requesting. + stream, err := client.GetTreeEntries(ctx, &gitalypb.GetTreeEntriesRequest{ Repository: repo, Revision: []byte(commitID), - Path: []byte("1"), + Path: []byte("0"), Recursive: false, - } - - // request entries of the tree with single-folder structure on each level - entriesClient, err := client.GetTreeEntries(ctx, request) + }) require.NoError(t, err) + treeEntries, _ := getTreeEntriesFromTreeEntryClient(t, stream, nil) - fetchedEntries, _ := getTreeEntriesFromTreeEntryClient(t, entriesClient, nil) - // We know that there is a directory "1/2/3/4/5/6/7/8/9/10/11/12" - // but here we only get back "1/2/3/4/5/6/7/8/9/10/11". - // This proves that FlatPath recursion is bounded, which is the point of this test. + // We know that there is a directory "1/2/3/4/5/6/7/8/9/10/11/12", but here we only get + // "1/2/3/4/5/6/7/8/9/10/11" as flat path. This proves that FlatPath recursion is bounded, + // which is the point of this test. require.Equal(t, []*gitalypb.TreeEntry{{ - Oid: "c836b95b37958e7179f5a42a32b7197b5dec7321", - RootOid: rootOid, - Path: []byte("1/2"), - FlatPath: []byte("1/2/3/4/5/6/7/8/9/10/11"), + Oid: "ba0cae41e396836584a4114feac0b943faf786da", + RootOid: treeID.String(), + Path: []byte("0/1"), + FlatPath: []byte("0/1/2/3/4/5/6/7/8/9/10"), Type: gitalypb.TreeEntry_TREE, Mode: 0o40000, - CommitOid: commitID, - }}, fetchedEntries) + CommitOid: commitID.String(), + }}, treeEntries) } func TestGetTreeEntries_file(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t, true) + cfg, repo, repoPath, client := setupCommitServiceWithRepo(ctx, t) commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(gittest.TreeEntry{ @@ -611,26 +644,73 @@ func TestGetTreeEntries_validation(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) revision := []byte("d42783470dc29fde2cf459eb3199ee1d7e3f3a72") path := []byte("a/b/c") - rpcRequests := []*gitalypb.GetTreeEntriesRequest{ - {Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}, Revision: revision, Path: path}, // Repository doesn't exist - {Repository: nil, Revision: revision, Path: path}, // Repository is nil - {Repository: repo, Revision: nil, Path: path}, // Revision is empty - {Repository: repo, Revision: revision}, // Path is empty - {Repository: repo, Revision: []byte("--output=/meow"), Path: path}, // Revision is invalid - } - - for _, rpcRequest := range rpcRequests { - t.Run(fmt.Sprintf("%v", rpcRequest), func(t *testing.T) { - c, err := client.GetTreeEntries(ctx, rpcRequest) + for _, tc := range []struct { + desc string + request *gitalypb.GetTreeEntriesRequest + expectedErr error + }{ + { + desc: "repository does not exist", + request: &gitalypb.GetTreeEntriesRequest{ + Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}, + Revision: revision, + Path: path, + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"fake\"", + "repo scoped: invalid Repository", + )), + }, + { + desc: "repository is nil", + request: &gitalypb.GetTreeEntriesRequest{ + Repository: nil, + Revision: revision, + Path: path, + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), + }, + { + desc: "revision is empty", + request: &gitalypb.GetTreeEntriesRequest{ + Repository: repo, + Revision: nil, + Path: path, + }, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: empty revision"), + }, + { + desc: "path is empty", + request: &gitalypb.GetTreeEntriesRequest{ + Repository: repo, + Revision: revision, + }, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: empty Path"), + }, + { + desc: "revision is invalid", + request: &gitalypb.GetTreeEntriesRequest{ + Repository: repo, + Revision: []byte("--output=/meow"), + Path: path, + }, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: revision can't start with '-'"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + stream, err := client.GetTreeEntries(ctx, tc.request) require.NoError(t, err) - err = drainTreeEntriesResponse(c) - testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) + err = drainTreeEntriesResponse(stream) + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } @@ -639,8 +719,8 @@ func BenchmarkGetTreeEntries(b *testing.B) { ctx := testhelper.Context(b) cfg, client := setupCommitService(ctx, b) - repo, _ := gittest.CloneRepo(b, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - SourceRepo: "benchmark.git", + repo, _ := gittest.CreateRepository(ctx, b, cfg, gittest.CreateRepositoryConfig{ + Seed: "benchmark.git", }) for _, tc := range []struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry.go index 2573fe3c05..4ab6afb3a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry.go @@ -5,11 +5,11 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func sendTreeEntry( @@ -65,7 +65,7 @@ func sendTreeEntry( if strings.ToLower(treeEntry.Type.String()) != objectInfo.Type { return helper.ErrInternalf( - "TreeEntry: mismatched nbject type: tree-oid=%s object-oid=%s entry-type=%s object-type=%s", + "TreeEntry: mismatched object type: tree-oid=%s object-oid=%s entry-type=%s object-type=%s", treeEntry.Oid, objectInfo.Oid, treeEntry.Type.String(), objectInfo.Type, ) } @@ -132,15 +132,17 @@ func (s *server) TreeEntry(in *gitalypb.TreeEntryRequest, stream gitalypb.Commit requestPath = strings.TrimRight(requestPath, "/") } - objectReader, err := s.catfileCache.ObjectReader(stream.Context(), repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(stream.Context(), repo) if err != nil { return err } + defer cancel() - objectInfoReader, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) if err != nil { return err } + defer cancel() return sendTreeEntry(stream, objectReader, objectInfoReader, string(in.GetRevision()), requestPath, in.GetLimit(), in.GetMaxSize()) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry_test.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry_test.go index 08ef53116b..8d408fc48b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit/tree_entry_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit/tree_entry_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commit import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type treeEntry struct { @@ -24,7 +26,7 @@ func TestSuccessfulTreeEntry(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) testCases := []struct { revision []byte @@ -153,80 +155,84 @@ func TestFailedTreeEntry(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, _, client := setupCommitServiceWithRepo(ctx, t, true) + _, repo, _, client := setupCommitServiceWithRepo(ctx, t) revision := []byte("d42783470dc29fde2cf459eb3199ee1d7e3f3a72") path := []byte("a/b/c") - testCases := []struct { - name string - req *gitalypb.TreeEntryRequest - expectedCode codes.Code + for _, tc := range []struct { + name string + req *gitalypb.TreeEntryRequest + expectedErr error }{ { - name: "Repository doesn't exist", - req: &gitalypb.TreeEntryRequest{Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}, Revision: revision, Path: path}, - expectedCode: codes.InvalidArgument, + name: "Repository doesn't exist", + req: &gitalypb.TreeEntryRequest{Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}, Revision: revision, Path: path}, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"fake\"", + "repo scoped: invalid Repository", + )), }, { - name: "Repository is nil", - req: &gitalypb.TreeEntryRequest{Repository: nil, Revision: revision, Path: path}, - expectedCode: codes.InvalidArgument, + name: "Repository is nil", + req: &gitalypb.TreeEntryRequest{Repository: nil, Revision: revision, Path: path}, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), }, { - name: "Revision is empty", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: nil, Path: path}, - expectedCode: codes.InvalidArgument, + name: "Revision is empty", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: nil, Path: path}, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: empty revision"), }, { - name: "Path is empty", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision}, - expectedCode: codes.InvalidArgument, + name: "Path is empty", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision}, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: empty Path"), }, { - name: "Revision is invalid", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("--output=/meow"), Path: path}, - expectedCode: codes.InvalidArgument, + name: "Revision is invalid", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("--output=/meow"), Path: path}, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: revision can't start with '-'"), }, { - name: "Limit is negative", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision, Path: path, Limit: -1}, - expectedCode: codes.InvalidArgument, + name: "Limit is negative", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision, Path: path, Limit: -1}, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: negative Limit"), }, { - name: "MaximumSize is negative", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision, Path: path, MaxSize: -1}, - expectedCode: codes.InvalidArgument, + name: "MaximumSize is negative", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: revision, Path: path, MaxSize: -1}, + expectedErr: helper.ErrInvalidArgumentf("TreeEntry: negative MaxSize"), }, { - name: "Object bigger than MaxSize", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("913c66a37b4a45b9769037c55c2d238bd0942d2e"), Path: []byte("MAINTENANCE.md"), MaxSize: 10}, - expectedCode: codes.FailedPrecondition, + name: "Object bigger than MaxSize", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("913c66a37b4a45b9769037c55c2d238bd0942d2e"), Path: []byte("MAINTENANCE.md"), MaxSize: 10}, + expectedErr: helper.ErrFailedPreconditionf("TreeEntry: object size (1367) is bigger than the maximum allowed size (10)"), }, { - name: "Path is outside of repository", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("913c66a37b4a45b9769037c55c2d238bd0942d2e"), Path: []byte("../bar/.gitkeep")}, // Git blows up on paths like this - expectedCode: codes.NotFound, + name: "Path is outside of repository", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("913c66a37b4a45b9769037c55c2d238bd0942d2e"), Path: []byte("../bar/.gitkeep")}, // Git blows up on paths like this + expectedErr: helper.ErrNotFoundf("not found: ../bar/.gitkeep"), }, { - name: "Missing file with space in path", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("deadfacedeadfacedeadfacedeadfacedeadface"), Path: []byte("with space/README.md")}, - expectedCode: codes.NotFound, + name: "Missing file with space in path", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("deadfacedeadfacedeadfacedeadfacedeadface"), Path: []byte("with space/README.md")}, + expectedErr: helper.ErrNotFoundf("not found: with space/README.md"), }, { - name: "Missing file", - req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("e63f41fe459e62e1228fcef60d7189127aeba95a"), Path: []byte("missing.rb")}, - expectedCode: codes.NotFound, + name: "Missing file", + req: &gitalypb.TreeEntryRequest{Repository: repo, Revision: []byte("e63f41fe459e62e1228fcef60d7189127aeba95a"), Path: []byte("missing.rb")}, + expectedErr: helper.ErrNotFoundf("not found: missing.rb"), }, - } - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - c, err := client.TreeEntry(ctx, testCase.req) + } { + t.Run(tc.name, func(t *testing.T) { + c, err := client.TreeEntry(ctx, tc.req) require.NoError(t, err) err = drainTreeEntryResponse(c) - testhelper.RequireGrpcCode(t, err, testCase.expectedCode) + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files.go index c81fd7962e..c0316e5eba 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files.go @@ -7,11 +7,11 @@ import ( "io" "unicode/utf8" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) ListConflictFiles(request *gitalypb.ListConflictFilesRequest, stream gitalypb.ConflictsService_ListConflictFilesServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files_test.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files_test.go index bfe08d35f4..6052ccd01d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/list_conflict_files_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/list_conflict_files_test.go @@ -1,20 +1,16 @@ +//go:build !gitaly_test_sha256 + package conflicts import ( - "bytes" - "context" "io" - "os" - "path/filepath" + "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -26,7 +22,7 @@ type conflictFile struct { func TestSuccessfulListConflictFilesRequest(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := SetupConflictsService(ctx, t, false, nil) + _, repo, _, client := setupConflictsService(ctx, t, nil) ourCommitOid := "1a35b5a77cf6af7edf6703f88e82f6aff613666f" theirCommitOid := "8309e68585b28d61eb85b7e2834849dda6bf1733" @@ -92,7 +88,7 @@ end func TestSuccessfulListConflictFilesRequestWithAncestor(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := SetupConflictsService(ctx, t, true, nil) + _, repo, _, client := setupConflictsService(ctx, t, nil) ourCommitOid := "824be604a34828eb682305f0d963056cfac87b2d" theirCommitOid := "1450cd639e0bc6721eb02800169e464f212cde06" @@ -138,67 +134,46 @@ func TestSuccessfulListConflictFilesRequestWithAncestor(t *testing.T) { func TestListConflictFilesHugeDiff(t *testing.T) { ctx := testhelper.Context(t) - cfg, repo, repoPath, client := SetupConflictsService(ctx, t, false, nil) + cfg, repo, repoPath, client := setupConflictsService(ctx, t, nil) - our := buildCommit(t, ctx, cfg, repo, repoPath, map[string][]byte{ - "a": bytes.Repeat([]byte("a\n"), 128*1024), - "b": bytes.Repeat([]byte("b\n"), 128*1024), - }) - - their := buildCommit(t, ctx, cfg, repo, repoPath, map[string][]byte{ - "a": bytes.Repeat([]byte("x\n"), 128*1024), - "b": bytes.Repeat([]byte("y\n"), 128*1024), - }) + ourCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Mode: "100644", Content: strings.Repeat("a\n", 128*1024)}, + gittest.TreeEntry{Path: "b", Mode: "100644", Content: strings.Repeat("b\n", 128*1024)}, + )) + theirCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Mode: "100644", Content: strings.Repeat("x\n", 128*1024)}, + gittest.TreeEntry{Path: "b", Mode: "100644", Content: strings.Repeat("y\n", 128*1024)}, + )) request := &gitalypb.ListConflictFilesRequest{ Repository: repo, - OurCommitOid: our, - TheirCommitOid: their, + OurCommitOid: ourCommitID.String(), + TheirCommitOid: theirCommitID.String(), } c, err := client.ListConflictFiles(ctx, request) require.NoError(t, err) receivedFiles := getConflictFiles(t, c) - require.Len(t, receivedFiles, 2) testhelper.ProtoEqual(t, &gitalypb.ConflictFileHeader{ - CommitOid: our, + CommitOid: ourCommitID.String(), OurMode: int32(0o100644), OurPath: []byte("a"), TheirPath: []byte("a"), }, receivedFiles[0].Header) testhelper.ProtoEqual(t, &gitalypb.ConflictFileHeader{ - CommitOid: our, + CommitOid: ourCommitID.String(), OurMode: int32(0o100644), OurPath: []byte("b"), TheirPath: []byte("b"), }, receivedFiles[1].Header) } -func buildCommit(t *testing.T, ctx context.Context, cfg config.Cfg, repo *gitalypb.Repository, repoPath string, files map[string][]byte) string { - t.Helper() - - for file, contents := range files { - filePath := filepath.Join(repoPath, file) - require.NoError(t, os.WriteFile(filePath, contents, 0o666)) - gittest.Exec(t, cfg, "-C", repoPath, "add", filePath) - } - - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-m", "message") - - oid, err := localrepo.NewTestRepo(t, cfg, repo).ResolveRevision(ctx, git.Revision("HEAD")) - require.NoError(t, err) - - gittest.Exec(t, cfg, "-C", repoPath, "reset", "--hard", "HEAD~") - - return oid.String() -} - func TestListConflictFilesFailedPrecondition(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := SetupConflictsService(ctx, t, true, nil) + _, repo, _, client := setupConflictsService(ctx, t, nil) testCases := []struct { desc string @@ -255,7 +230,7 @@ func TestListConflictFilesFailedPrecondition(t *testing.T) { func TestListConflictFilesAllowTreeConflicts(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := SetupConflictsService(ctx, t, true, nil) + _, repo, _, client := setupConflictsService(ctx, t, nil) ourCommitOid := "eb227b3e214624708c474bdab7bde7afc17cefcc" theirCommitOid := "824be604a34828eb682305f0d963056cfac87b2d" @@ -347,7 +322,7 @@ end func TestFailedListConflictFilesRequestDueToValidation(t *testing.T) { ctx := testhelper.Context(t) - _, repo, _, client := SetupConflictsService(ctx, t, true, nil) + _, repo, _, client := setupConflictsService(ctx, t, nil) ourCommitOid := "0b4bc9a49b562e85de7cc9e834518ea6828729b9" theirCommitOid := "bb5206fee213d983da88c47f9cf4cc6caf9c66dc" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts.go index 7f5d016048..11de0412fa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts.go @@ -12,15 +12,15 @@ import ( "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/conflict" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/conflict" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -168,8 +168,8 @@ func (s *server) resolveConflicts(header *gitalypb.ResolveConflictsRequestHeader authorDate = header.Timestamp.AsTime() } - if git.ValidateObjectID(header.GetOurCommitOid()) != nil || - git.ValidateObjectID(header.GetTheirCommitOid()) != nil { + if git.ObjectHashSHA1.ValidateHex(header.GetOurCommitOid()) != nil || + git.ObjectHashSHA1.ValidateHex(header.GetTheirCommitOid()) != nil { return errors.New("Rugged::InvalidError: unable to parse OID - contains invalid characters") } @@ -192,7 +192,7 @@ func (s *server) resolveConflicts(header *gitalypb.ResolveConflictsRequestHeader return err } - commitOID, err := git.NewObjectIDFromHex(result.CommitID) + commitOID, err := git.ObjectHashSHA1.FromHex(result.CommitID) if err != nil { return err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts_test.go index 0cc778069c..d1b0ed41f1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/resolve_conflicts_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/resolve_conflicts_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package conflicts import ( @@ -14,13 +16,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" @@ -56,7 +58,7 @@ var ( ) func TestSuccessfulResolveConflictsRequestHelper(t *testing.T) { - var verifyFunc func(t testing.TB, pushOptions []string, stdin io.Reader) + var verifyFunc func(tb testing.TB, pushOptions []string, stdin io.Reader) verifyFuncProxy := func(t *testing.T, ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, stdin io.Reader, stdout, stderr io.Writer) error { // We use a proxy func here as we need to provide the hookManager dependency while creating the service but we only // know the commit IDs after the service is created. The proxy allows us to modify the verifyFunc after the service @@ -67,7 +69,7 @@ func TestSuccessfulResolveConflictsRequestHelper(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, verifyFuncProxy, verifyFuncProxy, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repoProto, repoPath, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repoProto, repoPath, client := setupConflictsService(ctx, t, hookManager) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -137,12 +139,12 @@ func TestSuccessfulResolveConflictsRequestHelper(t *testing.T) { theirCommitOID = commitConflict(theirCommitOID, targetBranch, "content-2") hookCount := 0 - verifyFunc = func(t testing.TB, pushOptions []string, stdin io.Reader) { + verifyFunc = func(tb testing.TB, pushOptions []string, stdin io.Reader) { changes, err := io.ReadAll(stdin) - require.NoError(t, err) + require.NoError(tb, err) pattern := fmt.Sprintf("%s .* refs/heads/%s\n", ourCommitOID, sourceBranch) - require.Regexp(t, regexp.MustCompile(pattern), string(changes)) - require.Empty(t, pushOptions) + require.Regexp(tb, regexp.MustCompile(pattern), string(changes)) + require.Empty(tb, pushOptions) hookCount++ } @@ -201,7 +203,7 @@ func TestResolveConflictsWithRemoteRepo(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, sourceRepo, sourceRepoPath, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, sourceRepo, sourceRepoPath, client := setupConflictsService(ctx, t, hookManager) testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) @@ -271,7 +273,7 @@ func TestResolveConflictsWithRemoteRepo(t *testing.T) { func TestResolveConflictsLineEndings(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repo, repoPath, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repo, repoPath, client := setupConflictsService(ctx, t, hookManager) ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) @@ -391,7 +393,7 @@ func TestResolveConflictsLineEndings(t *testing.T) { func TestResolveConflictsNonOIDRequests(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repoProto, _, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repoProto, _, client := setupConflictsService(ctx, t, hookManager) ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) @@ -429,7 +431,7 @@ func TestResolveConflictsIdenticalContent(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repoProto, repoPath, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repoProto, repoPath, client := setupConflictsService(ctx, t, hookManager) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -526,7 +528,7 @@ func TestResolveConflictsStableID(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repoProto, _, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repoProto, _, client := setupConflictsService(ctx, t, hookManager) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -594,7 +596,7 @@ func TestResolveConflictsStableID(t *testing.T) { func TestFailedResolveConflictsRequestDueToResolutionError(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repo, _, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repo, _, client := setupConflictsService(ctx, t, hookManager) mdGS := testcfg.GitalyServersMetadataFromCfg(t, cfg) mdFF, _ := metadata.FromOutgoingContext(ctx) @@ -650,7 +652,7 @@ func TestFailedResolveConflictsRequestDueToResolutionError(t *testing.T) { func TestFailedResolveConflictsRequestDueToValidation(t *testing.T) { ctx := testhelper.Context(t) hookManager := hook.NewMockManager(t, hook.NopPreReceive, hook.NopPostReceive, hook.NopUpdate, hook.NopReferenceTransaction) - cfg, repo, _, client := SetupConflictsService(ctx, t, true, hookManager) + cfg, repo, _, client := setupConflictsService(ctx, t, hookManager) mdGS := testcfg.GitalyServersMetadataFromCfg(t, cfg) ourCommitOid := "1450cd639e0bc6721eb02800169e464f212cde06" @@ -816,13 +818,14 @@ func TestResolveConflictsQuarantine(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, sourceRepoProto, sourceRepoPath, client := SetupConflictsService(ctx, t, true, nil) + cfg, sourceRepoProto, sourceRepoPath, client := setupConflictsService(ctx, t, nil) testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) sourceBlobOID := gittest.WriteBlob(t, cfg, sourceRepoPath, []byte("contents-1\n")) sourceCommitOID := gittest.WriteCommit(t, cfg, sourceRepoPath, + gittest.WithParents("1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"), gittest.WithTreeEntries(gittest.TreeEntry{ Path: "file.txt", OID: sourceBlobOID, Mode: "100644", }), @@ -845,6 +848,7 @@ func TestResolveConflictsQuarantine(t *testing.T) { }) targetBlobOID := gittest.WriteBlob(t, cfg, targetRepoPath, []byte("contents-2\n")) targetCommitOID := gittest.WriteCommit(t, cfg, targetRepoPath, + gittest.WithParents("1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"), gittest.WithTreeEntries(gittest.TreeEntry{ Path: "file.txt", OID: targetBlobOID, Mode: "100644", }), @@ -889,7 +893,7 @@ func TestResolveConflictsQuarantine(t *testing.T) { })) response, err := stream.CloseAndRecv() - require.EqualError(t, err, `rpc error: code = Unknown desc = af339cb882d1e3cf8d6751651e58bbaff0265d6e + require.EqualError(t, err, `rpc error: code = Unknown desc = running pre-receive hooks: af339cb882d1e3cf8d6751651e58bbaff0265d6e tree 89fad81bbfa38070b90ca8f4c404625bf0999013 parent 29449b1d52cd77fd060a083a1de691bbaf12d8af parent 26dac52be85c92742b2c0c19eb7303de9feccb63 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/server.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/server.go index 3b8c91ee1b..687bbc00fe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/server.go @@ -1,16 +1,16 @@ package conflicts import ( - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/testhelper_test.go new file mode 100644 index 0000000000..b399e2f69a --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts/testhelper_test.go @@ -0,0 +1,95 @@ +//go:build !gitaly_test_sha256 + +package conflicts + +import ( + "context" + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func setupConflictsService(ctx context.Context, tb testing.TB, hookManager hook.Manager) (config.Cfg, *gitalypb.Repository, string, gitalypb.ConflictsServiceClient) { + cfg := testcfg.Build(tb) + + testcfg.BuildGitalyGit2Go(tb, cfg) + + serverSocketPath := runConflictsServer(tb, cfg, hookManager) + cfg.SocketPath = serverSocketPath + + client, conn := NewConflictsClient(tb, serverSocketPath) + tb.Cleanup(func() { conn.Close() }) + + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + return cfg, repo, repoPath, client +} + +func runConflictsServer(tb testing.TB, cfg config.Cfg, hookManager hook.Manager) string { + return testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + gitalypb.RegisterConflictsServiceServer(srv, NewServer( + deps.GetHookManager(), + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetConnsPool(), + deps.GetGit2goExecutor(), + deps.GetUpdaterWithHooks(), + )) + gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( + deps.GetCfg(), + deps.GetRubyServer(), + deps.GetLocator(), + deps.GetTxManager(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetConnsPool(), + deps.GetGit2goExecutor(), + deps.GetHousekeepingManager(), + )) + gitalypb.RegisterSSHServiceServer(srv, ssh.NewServer( + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetTxManager(), + )) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) + gitalypb.RegisterCommitServiceServer(srv, commit.NewServer( + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetLinguist(), + deps.GetCatfileCache(), + )) + }, testserver.WithHookManager(hookManager)) +} + +func NewConflictsClient(tb testing.TB, serverSocketPath string) (gitalypb.ConflictsServiceClient, *grpc.ClientConn) { + connOpts := []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), + } + + conn, err := grpc.Dial(serverSocketPath, connOpts...) + if err != nil { + tb.Fatal(err) + } + + return gitalypb.NewConflictsServiceClient(conn), conn +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/dependencies.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/dependencies.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/dependencies.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/dependencies.go index 060fbd74d8..d6c89e6b82 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/dependencies.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/dependencies.go @@ -1,44 +1,45 @@ package service import ( - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/streamcache" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/streamcache" ) // Dependencies assembles set of components required by different kinds of services. type Dependencies struct { - Cfg config.Cfg - RubyServer *rubyserver.Server - GitalyHookManager gitalyhook.Manager - TransactionManager transaction.Manager - StorageLocator storage.Locator - ClientPool *client.Pool - GitCmdFactory git.CommandFactory - Linguist *linguist.Instance - BackchannelRegistry *backchannel.Registry - GitlabClient gitlab.Client - CatfileCache catfile.Cache - DiskCache cache.Cache - PackObjectsCache streamcache.Cache - LimitHandler *limithandler.LimiterMiddleware - Git2goExecutor *git2go.Executor - UpdaterWithHooks *updateref.UpdaterWithHooks - HousekeepingManager housekeeping.Manager + Cfg config.Cfg + RubyServer *rubyserver.Server + GitalyHookManager gitalyhook.Manager + TransactionManager transaction.Manager + StorageLocator storage.Locator + ClientPool *client.Pool + GitCmdFactory git.CommandFactory + Linguist *linguist.Instance + BackchannelRegistry *backchannel.Registry + GitlabClient gitlab.Client + CatfileCache catfile.Cache + DiskCache cache.Cache + PackObjectsCache streamcache.Cache + PackObjectsConcurrencyTracker *gitalyhook.ConcurrencyTracker + LimitHandler *limithandler.LimiterMiddleware + Git2goExecutor *git2go.Executor + UpdaterWithHooks *updateref.UpdaterWithHooks + HousekeepingManager housekeeping.Manager } // GetCfg returns service configuration. @@ -106,6 +107,11 @@ func (dc *Dependencies) GetPackObjectsCache() streamcache.Cache { return dc.PackObjectsCache } +// GetPackObjectsConcurrencyTracker returns the pack-objects cache. +func (dc *Dependencies) GetPackObjectsConcurrencyTracker() *gitalyhook.ConcurrencyTracker { + return dc.PackObjectsConcurrencyTracker +} + // GetLimitHandler returns the RPC limit handler. func (dc *Dependencies) GetLimitHandler() *limithandler.LimiterMiddleware { return dc.LimitHandler diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit.go index daa2c981aa..de9258115a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit.go @@ -6,9 +6,9 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit_test.go index 5a58991d91..62f2ed282d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/commit_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/commit_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package diff import ( @@ -7,11 +9,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -34,7 +36,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { }, { FromID: "bdea48ee65c869eb0b86b1283069d76cce0a7254", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/deleted-file"), @@ -53,7 +55,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/file-with-multiple-chunks-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "389c7a36a6e133268b0d36b00e7ffc0f3a5b6651", OldMode: 0, NewMode: 0o100644, @@ -63,7 +65,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/file-with-pluses-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "bc2ef601a538d69ef99d5bdafa605e63f902e8e4", OldMode: 0, NewMode: 0o100644, @@ -93,7 +95,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { }, { FromID: "43d24af4e22580f36b1ca52647c1aff75a766a33", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/named-file-with-mods"), @@ -102,7 +104,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/named-file-with-mods-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b464dff7a75ccc92fbd920fd9ae66a84b9d2bf94", OldMode: 0, NewMode: 0o100644, @@ -121,7 +123,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Binary: false, }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "3856c00e9450a51a62096327167fc43d3be62eef", OldMode: 0, NewMode: 0o100644, @@ -131,7 +133,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/renamed-file-with-mods-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "a135e3e0d4af177a902ca57dcc4c7fc6f30858b1", OldMode: 0, NewMode: 0o100644, @@ -141,7 +143,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/tab-newline-file-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", OldMode: 0, NewMode: 0o100755, @@ -150,7 +152,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { Binary: false, }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b1e67221afe8461efd244b487afca22d46b95eb8", OldMode: 0, NewMode: 0o100644, @@ -235,7 +237,7 @@ func TestSuccessfulCommitDiffRequestWithPaths(t *testing.T) { }, { FromID: "43d24af4e22580f36b1ca52647c1aff75a766a33", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/named-file-with-mods"), @@ -265,7 +267,7 @@ func TestSuccessfulCommitDiffRequestWithTypeChangeDiff(t *testing.T) { expectedDiffs := []diff.Diff{ { FromID: "349cd0f6b1aba8538861d95783cbce6d49d747f8", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o120000, NewMode: 0, FromPath: []byte("gitaly/symlink-to-be-regular"), @@ -274,7 +276,7 @@ func TestSuccessfulCommitDiffRequestWithTypeChangeDiff(t *testing.T) { Patch: testhelper.MustReadFile(t, "testdata/symlink-to-be-regular-deleted-chunks.txt"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "f9e5cc857610185e6feeb494a26bf27551a4f02b", OldMode: 0, NewMode: 0o100644, @@ -347,7 +349,7 @@ func TestSuccessfulCommitDiffRequestWithIgnoreWhitespaceChange(t *testing.T) { }, { FromID: "43d24af4e22580f36b1ca52647c1aff75a766a33", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/named-file-with-mods"), @@ -847,7 +849,7 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { }, { FromID: "bdea48ee65c869eb0b86b1283069d76cce0a7254", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/deleted-file"), @@ -862,7 +864,7 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { ToPath: []byte("gitaly/file-with-multiple-chunks"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "bc2ef601a538d69ef99d5bdafa605e63f902e8e4", OldMode: 0, NewMode: 0o100644, @@ -887,14 +889,14 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { }, { FromID: "43d24af4e22580f36b1ca52647c1aff75a766a33", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/named-file-with-mods"), ToPath: []byte("gitaly/named-file-with-mods"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "b464dff7a75ccc92fbd920fd9ae66a84b9d2bf94", OldMode: 0, NewMode: 0o100644, @@ -910,7 +912,7 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { ToPath: []byte("gitaly/renamed-file"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "3856c00e9450a51a62096327167fc43d3be62eef", OldMode: 0, NewMode: 0o100644, @@ -918,7 +920,7 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { ToPath: []byte("gitaly/renamed-file-with-mods"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "a135e3e0d4af177a902ca57dcc4c7fc6f30858b1", OldMode: 0, NewMode: 0o100644, @@ -926,7 +928,7 @@ func TestSuccessfulCommitDeltaRequest(t *testing.T) { ToPath: []byte("gitaly/tab\tnewline\n file"), }, { - FromID: git.ZeroOID.String(), + FromID: git.ObjectHashSHA1.ZeroOID.String(), ToID: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", OldMode: 0, NewMode: 0o100755, @@ -985,7 +987,7 @@ func TestSuccessfulCommitDeltaRequestWithPaths(t *testing.T) { }, { FromID: "43d24af4e22580f36b1ca52647c1aff75a766a33", - ToID: git.ZeroOID.String(), + ToID: git.ObjectHashSHA1.ZeroOID.String(), OldMode: 0o100644, NewMode: 0, FromPath: []byte("gitaly/named-file-with-mods"), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths.go new file mode 100644 index 0000000000..93016168a2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths.go @@ -0,0 +1,253 @@ +package diff + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "io" + "strconv" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +const ( + numStatDelimiter = 0 +) + +// changedPathsRequestToString converts the given FindChangedPathsRequest to a string that can be passed to git-diff-tree(1). Note +// that this function expects that all revisions have already been resolved to their respective object IDs. +func changedPathsRequestToString(r *gitalypb.FindChangedPathsRequest_Request) (string, error) { + switch t := r.GetType().(type) { + case *gitalypb.FindChangedPathsRequest_Request_CommitRequest_: + return strings.Join(append([]string{t.CommitRequest.GetCommitRevision()}, t.CommitRequest.GetParentCommitRevisions()...), " "), nil + case *gitalypb.FindChangedPathsRequest_Request_TreeRequest_: + return t.TreeRequest.GetLeftTreeRevision() + " " + t.TreeRequest.GetRightTreeRevision(), nil + } + + // This shouldn't happen + return "", fmt.Errorf("unknown FindChangedPathsRequest type") +} + +func (s *server) FindChangedPaths(in *gitalypb.FindChangedPathsRequest, stream gitalypb.DiffService_FindChangedPathsServer) error { + if err := s.validateFindChangedPathsRequestParams(stream.Context(), in); err != nil { + return err + } + + diffChunker := chunk.New(&findChangedPathsSender{stream: stream}) + + requests := make([]string, len(in.GetRequests())) + for i, request := range in.GetRequests() { + str, err := changedPathsRequestToString(request) + if err != nil { + return err + } + requests[i] = str + } + + cmd, err := s.gitCmdFactory.New(stream.Context(), in.Repository, git.SubCmd{ + Name: "diff-tree", + Flags: []git.Option{ + git.Flag{Name: "-z"}, + git.Flag{Name: "--stdin"}, + git.Flag{Name: "-m"}, + git.Flag{Name: "-r"}, + git.Flag{Name: "--no-renames"}, + git.Flag{Name: "--no-commit-id"}, + git.Flag{Name: "--diff-filter=AMDTC"}, + }, + }, git.WithStdin(strings.NewReader(strings.Join(requests, "\n")+"\n"))) + if err != nil { + if _, ok := status.FromError(err); ok { + return fmt.Errorf("stdin err: %w", err) + } + return helper.ErrInternalf("cmd err: %v", err) + } + + if err := parsePaths(bufio.NewReader(cmd), diffChunker); err != nil { + return fmt.Errorf("parsing err: %w", err) + } + + if err := cmd.Wait(); err != nil { + return helper.ErrUnavailablef("cmd wait err: %v", err) + } + + return diffChunker.Flush() +} + +func parsePaths(reader *bufio.Reader, chunker *chunk.Chunker) error { + for { + path, err := nextPath(reader) + if err != nil { + if err == io.EOF { + break + } + + return fmt.Errorf("next path err: %w", err) + } + + if err := chunker.Send(path); err != nil { + return fmt.Errorf("err sending to chunker: %v", err) + } + } + + return nil +} + +func nextPath(reader *bufio.Reader) (*gitalypb.ChangedPaths, error) { + _, err := reader.ReadBytes(':') + if err != nil { + return nil, err + } + + line, err := reader.ReadBytes(numStatDelimiter) + if err != nil { + return nil, err + } + split := bytes.Split(line[:len(line)-1], []byte(" ")) + if len(split) != 5 || len(split[4]) != 1 { + return nil, fmt.Errorf("git diff-tree parsing failed on: %v", line) + } + + oldMode, err := strconv.ParseInt(string(split[0]), 8, 32) + if err != nil { + return nil, fmt.Errorf("parsing old mode: %w", err) + } + + newMode, err := strconv.ParseInt(string(split[1]), 8, 32) + if err != nil { + return nil, fmt.Errorf("parsing new mode: %w", err) + } + + pathStatus := split[4] + + path, err := reader.ReadBytes(numStatDelimiter) + if err != nil { + return nil, err + } + + statusTypeMap := map[string]gitalypb.ChangedPaths_Status{ + "M": gitalypb.ChangedPaths_MODIFIED, + "D": gitalypb.ChangedPaths_DELETED, + "T": gitalypb.ChangedPaths_TYPE_CHANGE, + "C": gitalypb.ChangedPaths_COPIED, + "A": gitalypb.ChangedPaths_ADDED, + } + + parsedPath, ok := statusTypeMap[string(pathStatus)] + if !ok { + return nil, helper.ErrInternalf("unknown changed paths returned: %v", string(pathStatus)) + } + + changedPath := &gitalypb.ChangedPaths{ + Status: parsedPath, + Path: path[:len(path)-1], + OldMode: int32(oldMode), + NewMode: int32(newMode), + } + + return changedPath, nil +} + +// This sender implements the interface in the chunker class +type findChangedPathsSender struct { + paths []*gitalypb.ChangedPaths + stream gitalypb.DiffService_FindChangedPathsServer +} + +func (t *findChangedPathsSender) Reset() { + t.paths = nil +} + +func (t *findChangedPathsSender) Append(m proto.Message) { + t.paths = append(t.paths, m.(*gitalypb.ChangedPaths)) +} + +func (t *findChangedPathsSender) Send() error { + return t.stream.Send(&gitalypb.FindChangedPathsResponse{ + Paths: t.paths, + }) +} + +func resolveObjectWithType(ctx context.Context, repo *localrepo.Repo, revision string, expectedType string) (git.ObjectID, error) { + if revision == "" { + return "", helper.ErrInvalidArgumentf("revision cannot be empty") + } + + oid, err := repo.ResolveRevision(ctx, git.Revision(fmt.Sprintf("%s^{%s}", revision, expectedType))) + if err != nil { + if errors.Is(err, git.ErrReferenceNotFound) { + return "", helper.ErrNotFoundf("revision can not be found: %q", revision) + } + return "", err + } + + return oid, nil +} + +func (s *server) validateFindChangedPathsRequestParams(ctx context.Context, in *gitalypb.FindChangedPathsRequest) error { + repo := in.GetRepository() + if _, err := s.locator.GetRepoPath(repo); err != nil { + return err + } + + gitRepo := s.localrepo(in.GetRepository()) + + if len(in.GetCommits()) > 0 { //nolint:staticcheck + if len(in.GetRequests()) > 0 { + return helper.ErrInvalidArgumentf("cannot specify both commits and requests") + } + + in.Requests = make([]*gitalypb.FindChangedPathsRequest_Request, len(in.GetCommits())) //nolint:staticcheck + for i, commit := range in.GetCommits() { //nolint:staticcheck + in.Requests[i] = &gitalypb.FindChangedPathsRequest_Request{ + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: commit, + }, + }, + } + } + } + + for _, request := range in.GetRequests() { + switch t := request.Type.(type) { + case *gitalypb.FindChangedPathsRequest_Request_CommitRequest_: + oid, err := resolveObjectWithType(ctx, gitRepo, t.CommitRequest.GetCommitRevision(), "commit") + if err != nil { + return helper.ErrInternalf("resolving commit: %w", err) + } + t.CommitRequest.CommitRevision = oid.String() + + for i, commit := range t.CommitRequest.GetParentCommitRevisions() { + oid, err := resolveObjectWithType(ctx, gitRepo, commit, "commit") + if err != nil { + return helper.ErrInternalf("resolving commit parent: %w", err) + } + t.CommitRequest.ParentCommitRevisions[i] = oid.String() + } + case *gitalypb.FindChangedPathsRequest_Request_TreeRequest_: + oid, err := resolveObjectWithType(ctx, gitRepo, t.TreeRequest.GetLeftTreeRevision(), "tree") + if err != nil { + return helper.ErrInternalf("resolving left tree: %w", err) + } + t.TreeRequest.LeftTreeRevision = oid.String() + + oid, err = resolveObjectWithType(ctx, gitRepo, t.TreeRequest.GetRightTreeRevision(), "tree") + if err != nil { + return helper.ErrInternalf("resolving right tree: %w", err) + } + t.TreeRequest.RightTreeRevision = oid.String() + } + } + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths_test.go new file mode 100644 index 0000000000..1d771d9bd2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/find_changed_paths_test.go @@ -0,0 +1,598 @@ +//go:build !gitaly_test_sha256 + +package diff + +import ( + "io" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestFindChangedPathsRequest_success(t *testing.T) { + ctx := testhelper.Context(t) + _, repo, _, client := setupDiffService(ctx, t) + + testCases := []struct { + desc string + commits []string + requests []*gitalypb.FindChangedPathsRequest_Request + expectedPaths []*gitalypb.ChangedPaths + }{ + { + desc: "Returns the expected results without a merge commit", + commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "57290e673a4c87f51294f5216672cbc58d485d25", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", "d59c60028b053793cecfb4022de34602e1a9218e"}, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("MAINTENANCE.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/テスト.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/deleted-file"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/file-with-multiple-chunks"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/mode-file"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/mode-file-with-mods"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/named-file"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitaly/named-file-with-mods"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("files/js/commit.js.coffee"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + }, + }, + { + desc: "Returns the expected results with a merge commit", + commits: []string{"7975be0116940bf2ad4321f79d02a55c5f7779aa", "55bc176024cfa3baaceb71db584c7e5df900ea65"}, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("files/images/emoji.png"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte(".gitattributes"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Commit request without parents uses actual parents", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results between distant commits", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", + ParentCommitRevisions: []string{ + "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51", + }, + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results when a file is renamed", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "94bb47ca1297b7b3731ff2a36923640991e9236f", + ParentCommitRevisions: []string{ + "e63f41fe459e62e1228fcef60d7189127aeba95a", + }, + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("CHANGELOG"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CHANGELOG.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results with diverging commits", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "f0f390655872bb2772c85a0128b2fbc2d88670cb", + ParentCommitRevisions: []string{ + "5b4bb08538b9249995b94aa69121365ba9d28082", + }, + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results with trees", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", + RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results when multiple parent commits are specified", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", + ParentCommitRevisions: []string{ + "5d03ab53225e8d8fe4f0597c70fc21c6542a7a10", + "f0f390655872bb2772c85a0128b2fbc2d88670cb", + }, + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results with multiple requests", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", + RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", + }, + }, + }, + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", + ParentCommitRevisions: []string{ + "5d03ab53225e8d8fe4f0597c70fc21c6542a7a10", + "f0f390655872bb2772c85a0128b2fbc2d88670cb", + }, + }, + }, + }, + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", + RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + }, + }, + { + desc: "Returns the expected results with refs and tags as commits", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "v1.0.0", + ParentCommitRevisions: []string{ + "v1.0.0^^", + }, + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte(".DS_Store"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte(".gitmodules"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("files/.DS_Store"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("gitlab-shell"), + OldMode: 0o000000, + NewMode: 0o160000, + }, + }, + }, + { + desc: "Returns the expected results with commits as trees", + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51", + RightTreeRevision: "be93687618e4b132087f430a4d8fc3a609c9b77c", + }, + }, + }, + }, + expectedPaths: []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("README"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + rpcRequest := &gitalypb.FindChangedPathsRequest{Repository: repo, Commits: tc.commits, Requests: tc.requests} + + stream, err := client.FindChangedPaths(ctx, rpcRequest) + require.NoError(t, err) + + var paths []*gitalypb.ChangedPaths + for { + fetchedPaths, err := stream.Recv() + if err == io.EOF { + break + } + + require.NoError(t, err) + + paths = append(paths, fetchedPaths.GetPaths()...) + } + + require.Equal(t, tc.expectedPaths, paths) + }) + } +} + +func TestFindChangedPathsRequest_failing(t *testing.T) { + ctx := testhelper.Context(t) + cfg, repo, _, client := setupDiffService(ctx, t, testserver.WithDisablePraefect()) + + tests := []struct { + desc string + repo *gitalypb.Repository + commits []string + requests []*gitalypb.FindChangedPathsRequest_Request + err error + }{ + { + desc: "Repo not found", + repo: &gitalypb.Repository{StorageName: repo.GetStorageName(), RelativePath: "bar.git"}, + commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + err: helper.ErrNotFoundf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")), + }, + { + desc: "Storage not found", + repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, + commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + err: helper.ErrInvalidArgumentf("GetStorageByName: no such storage: \"foo\""), + }, + { + desc: "Commits cannot contain an empty commit", + repo: repo, + commits: []string{""}, + err: helper.ErrInvalidArgumentf("resolving commit: revision cannot be empty"), + }, + { + desc: "Specifying both commits and requests", + repo: repo, + commits: []string{"8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + }, + }, + }, + }, + err: helper.ErrInvalidArgumentf("cannot specify both commits and requests"), + }, + { + desc: "Invalid commit", + repo: repo, + commits: []string{"invalidinvalidinvalid", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + err: helper.ErrNotFoundf(`resolving commit: revision can not be found: "invalidinvalidinvalid"`), + }, + { + desc: "Commit not found", + repo: repo, + commits: []string{"z4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + err: helper.ErrNotFoundf(`resolving commit: revision can not be found: "z4003da16c1c2c3fc4567700121b17bf8e591c6c"`), + }, + { + desc: "Tree object as commit", + repo: repo, + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + }, + }, + }, + }, + err: helper.ErrNotFoundf(`resolving commit: revision can not be found: "07f8147e8e73aab6c935c296e8cdc5194dee729b"`), + }, + { + desc: "Tree object as parent commit", + repo: repo, + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + ParentCommitRevisions: []string{ + "07f8147e8e73aab6c935c296e8cdc5194dee729b", + }, + }, + }, + }, + }, + err: helper.ErrNotFoundf(`resolving commit parent: revision can not be found: "07f8147e8e73aab6c935c296e8cdc5194dee729b"`), + }, + { + desc: "Blob object as left tree", + repo: repo, + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "50b27c6518be44c42c4d87966ae2481ce895624c", + RightTreeRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + }, + }, + }, + }, + err: helper.ErrNotFoundf(`resolving left tree: revision can not be found: "50b27c6518be44c42c4d87966ae2481ce895624c"`), + }, + { + desc: "Blob object as right tree", + repo: repo, + requests: []*gitalypb.FindChangedPathsRequest_Request{ + { + Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ + TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ + LeftTreeRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + RightTreeRevision: "50b27c6518be44c42c4d87966ae2481ce895624c", + }, + }, + }, + }, + err: helper.ErrNotFoundf(`resolving right tree: revision can not be found: "50b27c6518be44c42c4d87966ae2481ce895624c"`), + }, + } + + for _, tc := range tests { + rpcRequest := &gitalypb.FindChangedPathsRequest{Repository: tc.repo, Commits: tc.commits, Requests: tc.requests} + stream, err := client.FindChangedPaths(ctx, rpcRequest) + require.NoError(t, err) + + t.Run(tc.desc, func(t *testing.T) { + _, err := stream.Recv() + testhelper.RequireGrpcError(t, tc.err, err) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat.go index 324ff3f5a6..db6442ed0e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat.go @@ -3,9 +3,9 @@ package diff import ( "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat_test.go index 334123906d..730e632598 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/numstat_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/numstat_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package diff import ( @@ -5,9 +7,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/diff" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/diff" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw.go index a5c1e3662b..6eaa712092 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/raw.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw.go @@ -4,9 +4,9 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw_test.go new file mode 100644 index 0000000000..9dff354514 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/raw_test.go @@ -0,0 +1,265 @@ +//go:build !gitaly_test_sha256 + +package diff + +import ( + "io" + "regexp" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" + "google.golang.org/grpc/codes" +) + +func TestRawDiff_successful(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, repoProto, repoPath, client := setupDiffService(ctx, t) + testcfg.BuildGitalyGit2Go(t, cfg) + + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + locator := config.NewLocator(cfg) + git2goExecutor := git2go.NewExecutor(cfg, gitCmdFactory, locator) + + leftCommit := "57290e673a4c87f51294f5216672cbc58d485d25" + rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" + + stream, err := client.RawDiff(ctx, &gitalypb.RawDiffRequest{ + Repository: repoProto, + LeftCommitId: leftCommit, + RightCommitId: rightCommit, + }) + require.NoError(t, err) + + rawDiff, err := io.ReadAll(streamio.NewReader(func() ([]byte, error) { + response, err := stream.Recv() + return response.GetData(), err + })) + require.NoError(t, err) + + signature := git2go.Signature{ + Name: gittest.DefaultCommitterName, + Email: gittest.DefaultCommitterMail, + When: gittest.DefaultCommitTime, + } + + // Now that we have read the patch in we verify that it indeed round-trips to the same tree + // as the right commit is referring to by reapplying the diff on top of the left commit. + patchedCommitID, err := git2goExecutor.Apply(ctx, gittest.RewrittenRepository(ctx, t, cfg, repoProto), git2go.ApplyParams{ + Repository: repoPath, + Committer: signature, + ParentCommit: leftCommit, + Patches: git2go.NewSlicePatchIterator([]git2go.Patch{{ + Author: signature, + Message: "Applying received raw diff", + Diff: rawDiff, + }}), + }) + require.NoError(t, err) + + // Peel both right commit and patched commit to their trees and assert that they refer to + // the same one. + require.Equal(t, + gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", rightCommit+"^{tree}"), + gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", patchedCommitID.String()+"^{tree}"), + ) +} + +func TestRawDiff_inputValidation(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupDiffService(ctx, t) + + testCases := []struct { + desc string + request *gitalypb.RawDiffRequest + code codes.Code + }{ + { + desc: "empty left commit", + request: &gitalypb.RawDiffRequest{ + Repository: repo, + LeftCommitId: "", + RightCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + { + desc: "empty right commit", + request: &gitalypb.RawDiffRequest{ + Repository: repo, + RightCommitId: "", + LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + { + desc: "empty repo", + request: &gitalypb.RawDiffRequest{ + Repository: nil, + RightCommitId: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + c, _ := client.RawDiff(ctx, testCase.request) + testhelper.RequireGrpcCode(t, drainRawDiffResponse(c), testCase.code) + }) + } +} + +func TestRawPatch_successful(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, repoProto, repoPath, client := setupDiffService(ctx, t) + testcfg.BuildGitalyGit2Go(t, cfg) + + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + locator := config.NewLocator(cfg) + git2goExecutor := git2go.NewExecutor(cfg, gitCmdFactory, locator) + + rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" + leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" + + stream, err := client.RawPatch(ctx, &gitalypb.RawPatchRequest{ + Repository: repoProto, + LeftCommitId: leftCommit, + RightCommitId: rightCommit, + }) + require.NoError(t, err) + + rawPatch, err := io.ReadAll(streamio.NewReader(func() ([]byte, error) { + response, err := stream.Recv() + return response.GetData(), err + })) + require.NoError(t, err) + + signature := git2go.Signature{ + Name: gittest.DefaultCommitterName, + Email: gittest.DefaultCommitterMail, + When: gittest.DefaultCommitTime, + } + + // Now that we have read the patch in we verify that it indeed round-trips to the same tree + // as the right commit is referring to by reapplying the diff on top of the left commit. + patchedCommitID, err := git2goExecutor.Apply(ctx, gittest.RewrittenRepository(ctx, t, cfg, repoProto), git2go.ApplyParams{ + Repository: repoPath, + Committer: signature, + ParentCommit: leftCommit, + Patches: git2go.NewSlicePatchIterator([]git2go.Patch{{ + Author: signature, + Message: "Applying received raw patch", + Diff: rawPatch, + }}), + }) + require.NoError(t, err) + + // Peel both right commit and patched commit to their trees and assert that they refer to + // the same one. + require.Equal(t, + gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", rightCommit+"^{tree}"), + gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", patchedCommitID.String()+"^{tree}"), + ) +} + +func TestRawPatch_inputValidation(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupDiffService(ctx, t) + + testCases := []struct { + desc string + request *gitalypb.RawPatchRequest + code codes.Code + }{ + { + desc: "empty left commit", + request: &gitalypb.RawPatchRequest{ + Repository: repo, + LeftCommitId: "", + RightCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + { + desc: "empty right commit", + request: &gitalypb.RawPatchRequest{ + Repository: repo, + RightCommitId: "", + LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + { + desc: "empty repo", + request: &gitalypb.RawPatchRequest{ + Repository: nil, + RightCommitId: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + LeftCommitId: "e395f646b1499e8e0279445fc99a0596a65fab7e", + }, + code: codes.InvalidArgument, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + c, _ := client.RawPatch(ctx, testCase.request) + testhelper.RequireGrpcCode(t, drainRawPatchResponse(c), testCase.code) + }) + } +} + +func TestRawPatch_gitlabSignature(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupDiffService(ctx, t) + + rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e" + leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" + rpcRequest := &gitalypb.RawPatchRequest{Repository: repo, RightCommitId: rightCommit, LeftCommitId: leftCommit} + + c, err := client.RawPatch(ctx, rpcRequest) + require.NoError(t, err) + + reader := streamio.NewReader(func() ([]byte, error) { + response, err := c.Recv() + return response.GetData(), err + }) + + patch, err := io.ReadAll(reader) + require.NoError(t, err) + + require.Regexp(t, regexp.MustCompile(`\n-- \nGitLab\s+$`), string(patch)) +} + +func drainRawDiffResponse(c gitalypb.DiffService_RawDiffClient) error { + var err error + for err == nil { + _, err = c.Recv() + } + return err +} + +func drainRawPatchResponse(c gitalypb.DiffService_RawPatchClient) error { + var err error + for err == nil { + _, err = c.Recv() + } + return err +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/server.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/server.go index d9755f2c00..693b0e8380 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/server.go @@ -1,12 +1,12 @@ package diff import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const msgSizeThreshold = 5 * 1024 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/binary-changes-patch.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/binary-changes-patch.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/binary-changes-patch.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/binary-changes-patch.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/contributing-md-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/contributing-md-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/contributing-md-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/contributing-md-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/deleted-file-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/deleted-file-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/deleted-file-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/deleted-file-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/file-with-multiple-chunks-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/file-with-multiple-chunks-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/file-with-multiple-chunks-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/file-with-multiple-chunks-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/file-with-pluses-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/file-with-pluses-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/file-with-pluses-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/file-with-pluses-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/initial-commit-patch.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/initial-commit-patch.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/initial-commit-patch.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/initial-commit-patch.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/maintenance-md-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/maintenance-md-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/maintenance-md-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/maintenance-md-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/mode-file-with-mods-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/mode-file-with-mods-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/mode-file-with-mods-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/mode-file-with-mods-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/named-file-with-mods-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/named-file-with-mods-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/named-file-with-mods-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/named-file-with-mods-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/no-newline-at-the-end-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/no-newline-at-the-end-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/no-newline-at-the-end-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/no-newline-at-the-end-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/readme-md-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/readme-md-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/readme-md-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/readme-md-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/renamed-file-with-mods-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/renamed-file-with-mods-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/renamed-file-with-mods-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/renamed-file-with-mods-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/symlink-to-be-regular-added-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/symlink-to-be-regular-added-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/symlink-to-be-regular-added-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/symlink-to-be-regular-added-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/tab-newline-file-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/tab-newline-file-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/tab-newline-file-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/tab-newline-file-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/z-short-diff-chunks.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/z-short-diff-chunks.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff/testdata/z-short-diff-chunks.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testdata/z-short-diff-chunks.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testhelper_test.go new file mode 100644 index 0000000000..fe1c4db287 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff/testhelper_test.go @@ -0,0 +1,58 @@ +//go:build !gitaly_test_sha256 + +package diff + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func setupDiffService(ctx context.Context, tb testing.TB, opt ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.DiffServiceClient) { + cfg := testcfg.Build(tb) + + addr := testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + gitalypb.RegisterDiffServiceServer(srv, NewServer( + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + )) + gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( + cfg, + deps.GetRubyServer(), + deps.GetLocator(), + deps.GetTxManager(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetConnsPool(), + deps.GetGit2goExecutor(), + deps.GetHousekeepingManager(), + )) + }, opt...) + cfg.SocketPath = addr + + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(tb, err) + tb.Cleanup(func() { testhelper.MustClose(tb, conn) }) + + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + return cfg, repo, repoPath, gitalypb.NewDiffServiceClient(conn) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects.go index 45cff4d8bf..3028a46bc6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects.go @@ -18,14 +18,13 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" ) var ( @@ -43,8 +42,8 @@ var ( }) ) -func (s *server) packObjectsHook(ctx context.Context, repo *gitalypb.Repository, reqHash proto.Message, args *packObjectsArgs, stdinReader io.Reader, output io.Writer) error { - data, err := protojson.Marshal(reqHash) +func (s *server) packObjectsHook(ctx context.Context, req *gitalypb.PackObjectsHookWithSidechannelRequest, args *packObjectsArgs, stdinReader io.Reader, output io.Writer) error { + data, err := protojson.Marshal(req) if err != nil { return err } @@ -74,7 +73,7 @@ func (s *server) packObjectsHook(ctx context.Context, repo *gitalypb.Repository, key := hex.EncodeToString(h.Sum(nil)) r, created, err := s.packObjectsCache.FindOrCreate(key, func(w io.Writer) error { - return s.runPackObjects(ctx, w, repo, args, stdin, key) + return s.runPackObjects(ctx, w, req, args, stdin, key) }) if err != nil { return err @@ -105,39 +104,48 @@ func (s *server) packObjectsHook(ctx context.Context, repo *gitalypb.Repository, return r.Wait(ctx) } -type contextWithoutCancel struct { - context.Context - valueCtx context.Context -} - -func (cwc *contextWithoutCancel) Value(key interface{}) interface{} { return cwc.valueCtx.Value(key) } - -func cloneContextValues(ctx context.Context) context.Context { - return &contextWithoutCancel{ - Context: context.Background(), - valueCtx: ctx, - } -} - -func (s *server) runPackObjects(ctx context.Context, w io.Writer, repo *gitalypb.Repository, args *packObjectsArgs, stdin io.ReadCloser, key string) error { +func (s *server) runPackObjects( + ctx context.Context, + w io.Writer, + req *gitalypb.PackObjectsHookWithSidechannelRequest, + args *packObjectsArgs, + stdin io.ReadCloser, + key string, +) error { // We want to keep the context for logging, but we want to block all its - // cancelation signals (deadline, cancel etc.). This is because of + // cancellation signals (deadline, cancel etc.). This is because of // the following scenario. Imagine client1 calls PackObjectsHook and // causes runPackObjects to run in a goroutine. Now suppose that client2 // calls PackObjectsHook with the same arguments and stdin, so it joins // client1 in waiting for this goroutine. Now client1 hangs up before the // runPackObjects goroutine is done. // - // If the cancelation of client1 propagated into the runPackObjects + // If the cancellation of client1 propagated into the runPackObjects // goroutine this would affect client2. We don't want that. So to prevent - // that, we suppress the cancelation of the originating context. - ctx = cloneContextValues(ctx) + // that, we suppress the cancellation of the originating context. + ctx = helper.SuppressCancellation(ctx) ctx, cancel := context.WithCancel(ctx) defer cancel() defer stdin.Close() + repo := req.GetRepository() + + if s.concurrencyTracker != nil { + finishRepoLog := s.concurrencyTracker.LogConcurrency(ctx, "repository", repo.GetRelativePath()) + defer finishRepoLog() + + userID := req.GetGlId() + + if userID == "" { + userID = "none" + } + + finishUserLog := s.concurrencyTracker.LogConcurrency(ctx, "user_id", userID) + defer finishUserLog() + } + counter := &helper.CountingWriter{W: w} sw := pktline.NewSidebandWriter(counter) stdout := bufio.NewWriterSize(sw.Writer(stream.BandStdout), pktline.MaxSidebandData) @@ -299,7 +307,7 @@ func (s *server) PackObjectsHookWithSidechannel(ctx context.Context, req *gitaly } defer c.Close() - if err := s.packObjectsHook(ctx, req.Repository, req, args, c, c); err != nil { + if err := s.packObjectsHook(ctx, req, args, c, c); err != nil { if errors.Is(err, syscall.EPIPE) { // EPIPE is the error we get if we try to write to c after the client has // closed its side of the connection. By convention, we label server side diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects_test.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects_test.go index e2ffb15b8a..0bf4262da2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pack_objects_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pack_objects_test.go @@ -1,39 +1,45 @@ +//go:build !gitaly_test_sha256 + package hook import ( "bytes" + "context" "io" "net" "strings" "sync" "testing" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - hookPkg "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/streamcache" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + hookPkg "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/streamcache" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) -func runTestsWithRuntimeDir(t *testing.T, testFunc func(*testing.T, string)) { +func runTestsWithRuntimeDir(t *testing.T, testFunc func(*testing.T, context.Context, string)) func(*testing.T, context.Context) { t.Helper() - t.Run("no runtime dir", func(t *testing.T) { - testFunc(t, "") - }) + return func(t *testing.T, ctx context.Context) { + t.Run("no runtime dir", func(t *testing.T) { + testFunc(t, ctx, "") + }) - t.Run("with runtime dir", func(t *testing.T) { - testFunc(t, testhelper.TempDir(t)) - }) + t.Run("with runtime dir", func(t *testing.T) { + testFunc(t, ctx, testhelper.TempDir(t)) + }) + } } func cfgWithCache(t *testing.T) config.Cfg { @@ -73,14 +79,18 @@ func TestParsePackObjectsArgs(t *testing.T) { func TestServer_PackObjectsHook_separateContext(t *testing.T) { t.Parallel() - runTestsWithRuntimeDir(t, testServerPackObjectsHookSeparateContextWithRuntimeDir) + runTestsWithRuntimeDir( + t, + testServerPackObjectsHookSeparateContextWithRuntimeDir, + )(t, testhelper.Context(t)) } -func testServerPackObjectsHookSeparateContextWithRuntimeDir(t *testing.T, runtimeDir string) { +func testServerPackObjectsHookSeparateContextWithRuntimeDir(t *testing.T, ctx context.Context, runtimeDir string) { cfg := cfgWithCache(t) cfg.SocketPath = runHooksServer(t, cfg, nil) - ctx1 := testhelper.Context(t) + ctx1, cancel := context.WithCancel(ctx) + defer cancel() repo, repoPath := gittest.CreateRepository(ctx1, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -137,7 +147,8 @@ func testServerPackObjectsHookSeparateContextWithRuntimeDir(t *testing.T, runtim client2, conn2 := newHooksClient(t, cfg.SocketPath) defer conn2.Close() - ctx2 := testhelper.Context(t) + ctx2, cancel := context.WithCancel(ctx) + defer cancel() var stdout2 []byte ctx2, wt2, err := hookPkg.SetupSidechannel( @@ -186,10 +197,13 @@ func testServerPackObjectsHookSeparateContextWithRuntimeDir(t *testing.T, runtim func TestServer_PackObjectsHook_usesCache(t *testing.T) { t.Parallel() - runTestsWithRuntimeDir(t, testServerPackObjectsHookUsesCache) + runTestsWithRuntimeDir( + t, + testServerPackObjectsHookUsesCache, + )(t, testhelper.Context(t)) } -func testServerPackObjectsHookUsesCache(t *testing.T, runtimeDir string) { +func testServerPackObjectsHookUsesCache(t *testing.T, ctx context.Context, runtimeDir string) { cfg := cfgWithCache(t) tlc := &streamcache.TestLoggingCache{} @@ -198,7 +212,6 @@ func testServerPackObjectsHookUsesCache(t *testing.T, runtimeDir string) { s.packObjectsCache = tlc }}) - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -268,10 +281,14 @@ func testServerPackObjectsHookUsesCache(t *testing.T, runtimeDir string) { func TestServer_PackObjectsHookWithSidechannel(t *testing.T) { t.Parallel() - runTestsWithRuntimeDir(t, testServerPackObjectsHookWithSidechannelWithRuntimeDir) + + runTestsWithRuntimeDir( + t, + testServerPackObjectsHookWithSidechannelWithRuntimeDir, + )(t, testhelper.Context(t)) } -func testServerPackObjectsHookWithSidechannelWithRuntimeDir(t *testing.T, runtimeDir string) { +func testServerPackObjectsHookWithSidechannelWithRuntimeDir(t *testing.T, ctx context.Context, runtimeDir string) { testCases := []struct { desc string stdin string @@ -292,10 +309,17 @@ func testServerPackObjectsHookWithSidechannelWithRuntimeDir(t *testing.T, runtim for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { cfg := cfgWithCache(t) - ctx := testhelper.Context(t) logger, hook := test.NewNullLogger() - cfg.SocketPath = runHooksServer(t, cfg, nil, testserver.WithLogger(logger)) + concurrencyTracker := hookPkg.NewConcurrencyTracker() + + cfg.SocketPath = runHooksServer( + t, + cfg, + nil, + testserver.WithLogger(logger), + testserver.WithConcurrencyTracker(concurrencyTracker), + ) repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -384,6 +408,68 @@ func testServerPackObjectsHookWithSidechannelWithRuntimeDir(t *testing.T, runtim require.True(t, strings.HasPrefix(total, "Total ")) require.False(t, strings.Contains(total, "\n")) }) + + expectedMetrics := `# HELP gitaly_pack_objects_concurrent_processes Number of concurrent processes +# TYPE gitaly_pack_objects_concurrent_processes histogram +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="0"} 0 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="5"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="10"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="15"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="20"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="25"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="30"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="35"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="40"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="45"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="50"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="55"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="60"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="65"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="70"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="75"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="80"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="85"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="90"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="95"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="repository",le="+Inf"} 1 +gitaly_pack_objects_concurrent_processes_sum{segment="repository"} 1 +gitaly_pack_objects_concurrent_processes_count{segment="repository"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="0"} 0 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="5"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="10"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="15"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="20"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="25"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="30"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="35"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="40"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="45"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="50"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="55"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="60"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="65"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="70"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="75"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="80"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="85"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="90"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="95"} 1 +gitaly_pack_objects_concurrent_processes_bucket{segment="user_id",le="+Inf"} 1 +gitaly_pack_objects_concurrent_processes_sum{segment="user_id"} 1 +gitaly_pack_objects_concurrent_processes_count{segment="user_id"} 1 +# HELP gitaly_pack_objects_process_active_callers Number of unique callers that have an active pack objects processes +# TYPE gitaly_pack_objects_process_active_callers gauge +gitaly_pack_objects_process_active_callers{segment="repository"} 0 +gitaly_pack_objects_process_active_callers{segment="user_id"} 0 +# HELP gitaly_pack_objects_process_active_callers_total Total unique callers that have initiated a pack objects processes +# TYPE gitaly_pack_objects_process_active_callers_total counter +gitaly_pack_objects_process_active_callers_total{segment="repository"} 1 +gitaly_pack_objects_process_active_callers_total{segment="user_id"} 1 +` + require.NoError(t, testutil.CollectAndCompare( + concurrencyTracker, + bytes.NewBufferString(expectedMetrics), + )) }) } } @@ -430,12 +516,15 @@ func TestServer_PackObjectsHookWithSidechannel_invalidArgument(t *testing.T) { func TestServer_PackObjectsHookWithSidechannel_Canceled(t *testing.T) { t.Parallel() - runTestsWithRuntimeDir(t, testServerPackObjectsHookWithSidechannelCanceledWithRuntimeDir) + + runTestsWithRuntimeDir( + t, + testServerPackObjectsHookWithSidechannelCanceledWithRuntimeDir, + )(t, testhelper.Context(t)) } -func testServerPackObjectsHookWithSidechannelCanceledWithRuntimeDir(t *testing.T, runtimeDir string) { +func testServerPackObjectsHookWithSidechannelCanceledWithRuntimeDir(t *testing.T, ctx context.Context, runtimeDir string) { cfg := cfgWithCache(t) - ctx := testhelper.Context(t) ctx, wt, err := hookPkg.SetupSidechannel( ctx, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive.go index 0ec9606c7f..88e2d15a0f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive.go @@ -6,9 +6,9 @@ import ( "os/exec" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func postReceiveHookResponse(stream gitalypb.HookService_PostReceiveHookServer, code int32, stderr string) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive_test.go index 1952635ea9..90a84a1b89 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/post_receive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/post_receive_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -8,18 +10,18 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) @@ -103,13 +105,13 @@ func TestHooksMissingStdin(t *testing.T) { Node: "node-1", Primary: tc.primary, }, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key_id", Username: "username", Protocol: "protocol", }, git.PostReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -231,13 +233,13 @@ To create a merge request for okay, visit: cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key_id", Username: "username", Protocol: "protocol", }, git.PostReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive.go index 24266cbb7b..442af0e261 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive.go @@ -6,9 +6,9 @@ import ( "os/exec" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) PreReceiveHook(stream gitalypb.HookService_PreReceiveHookServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive_test.go index 6d67b52b1d..c6171174db 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/pre_receive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/pre_receive_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -11,19 +13,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) @@ -143,13 +145,13 @@ func TestPreReceiveHook_GitlabAPIAccess(t *testing.T) { cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: glID, Username: "username", Protocol: protocol, }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -222,7 +224,7 @@ func TestPreReceive_APIErrors(t *testing.T) { expectedStderr: "GitLab: not allowed", }, { - desc: "/pre_receive endpoint fails to increase reference coutner", + desc: "/pre_receive endpoint fails to increase reference counter", allowedHandler: allowedHandler(t, true), preReceiveHandler: preReceiveHandler(t, false), expectedExitStatus: 1, @@ -265,13 +267,13 @@ func TestPreReceive_APIErrors(t *testing.T) { cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key-123", Username: "username", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -339,13 +341,13 @@ exit %d cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key-123", Username: "username", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) @@ -472,13 +474,13 @@ func TestPreReceiveHook_Primary(t *testing.T) { Node: "node-1", Primary: tc.primary, }, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key-123", Username: "username", Protocol: "web", }, git.PreReceiveHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction.go index ff5a027eaa..e018415876 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction.go @@ -3,11 +3,11 @@ package hook import ( "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction_test.go index aa9ec674fc..f8e32ed245 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/reference_transaction_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/reference_transaction_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -7,18 +9,19 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" ) type testTransactionServer struct { @@ -109,7 +112,7 @@ func TestReferenceTransactionHook(t *testing.T) { listener, err := net.Listen("tcp", "127.0.0.1:0") require.NoError(t, err) - backchannelConn, err := grpc.Dial(listener.Addr().String(), grpc.WithInsecure()) + backchannelConn, err := grpc.Dial(listener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer backchannelConn.Close() @@ -154,7 +157,7 @@ func TestReferenceTransactionHook(t *testing.T) { }, nil, git.ReferenceTransactionHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/server.go new file mode 100644 index 0000000000..c04f82edb1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/server.go @@ -0,0 +1,33 @@ +package hook + +import ( + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/streamcache" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +type server struct { + gitalypb.UnimplementedHookServiceServer + manager gitalyhook.Manager + gitCmdFactory git.CommandFactory + packObjectsCache streamcache.Cache + concurrencyTracker *gitalyhook.ConcurrencyTracker +} + +// NewServer creates a new instance of a gRPC namespace server +func NewServer( + manager gitalyhook.Manager, + gitCmdFactory git.CommandFactory, + packObjectsCache streamcache.Cache, + concurrencyTracker *gitalyhook.ConcurrencyTracker, +) gitalypb.HookServiceServer { + srv := &server{ + manager: manager, + gitCmdFactory: gitCmdFactory, + packObjectsCache: packObjectsCache, + concurrencyTracker: concurrencyTracker, + } + + return srv +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/testhelper_test.go new file mode 100644 index 0000000000..926d16ca47 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/testhelper_test.go @@ -0,0 +1,86 @@ +//go:build !gitaly_test_sha256 + +package hook + +import ( + "context" + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func setupHookService(ctx context.Context, tb testing.TB) (config.Cfg, *gitalypb.Repository, string, gitalypb.HookServiceClient) { + tb.Helper() + + cfg := testcfg.Build(tb) + cfg.SocketPath = runHooksServer(tb, cfg, nil) + client, conn := newHooksClient(tb, cfg.SocketPath) + tb.Cleanup(func() { conn.Close() }) + + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + return cfg, repo, repoPath, client +} + +func newHooksClient(tb testing.TB, serverSocketPath string) (gitalypb.HookServiceClient, *grpc.ClientConn) { + tb.Helper() + + connOpts := []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), + } + conn, err := grpc.Dial(serverSocketPath, connOpts...) + if err != nil { + tb.Fatal(err) + } + + return gitalypb.NewHookServiceClient(conn), conn +} + +type serverOption func(*server) + +func runHooksServer(tb testing.TB, cfg config.Cfg, opts []serverOption, serverOpts ...testserver.GitalyServerOpt) string { + tb.Helper() + + serverOpts = append(serverOpts, testserver.WithDisablePraefect()) + + return testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + hookServer := NewServer( + gitalyhook.NewManager(deps.GetCfg(), deps.GetLocator(), deps.GetGitCmdFactory(), deps.GetTxManager(), deps.GetGitlabClient()), + deps.GetGitCmdFactory(), + deps.GetPackObjectsCache(), + deps.GetPackObjectsConcurrencyTracker(), + ) + for _, opt := range opts { + opt(hookServer.(*server)) + } + + gitalypb.RegisterHookServiceServer(srv, hookServer) + gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( + cfg, + deps.GetRubyServer(), + deps.GetLocator(), + deps.GetTxManager(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetConnsPool(), + deps.GetGit2goExecutor(), + deps.GetHousekeepingManager(), + )) + }, serverOpts...) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update.go index 53ec53c8e3..81f0a6a460 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update.go @@ -5,9 +5,9 @@ import ( "os/exec" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func validateUpdateHookRequest(in *gitalypb.UpdateHookRequest) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update_test.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update_test.go index 2748bf0036..0152dae4f2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook/update_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook/update_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package hook import ( @@ -9,13 +11,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -41,13 +43,13 @@ func TestUpdate_CustomHooks(t *testing.T) { cfg, repo, nil, - &git.ReceiveHooksPayload{ + &git.UserDetails{ UserID: "key-123", Username: "username", Protocol: "web", }, git.UpdateHook, - featureflag.RawFromContext(ctx), + featureflag.FromContext(ctx), ).Env() require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/server.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/server.go index c3f3c0ea62..a6f44fe45d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/server.go @@ -1,8 +1,8 @@ package internalgitaly import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/testhelper_test.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/testhelper_test.go index b1ba1d0502..aa6270d194 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/testhelper_test.go @@ -1,15 +1,18 @@ +//go:build !gitaly_test_sha256 + package internalgitaly import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func TestMain(m *testing.M) { @@ -20,7 +23,7 @@ func setupInternalGitalyService(t *testing.T, cfg config.Cfg, internalService gi add := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterInternalGitalyServer(srv, internalService) }, testserver.WithDisablePraefect()) - conn, err := grpc.Dial(add, grpc.WithInsecure()) + conn, err := grpc.Dial(add, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { testhelper.MustClose(t, conn) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos.go index 71a023fdde..fec13966c3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos_test.go index 23a3aaec40..a29313e5a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly/walkrepos_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly/walkrepos_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package internalgitaly import ( @@ -9,11 +11,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -37,20 +39,28 @@ func (w *streamWrapper) Send(resp *gitalypb.WalkReposResponse) error { } func TestWalkRepos(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t) + storageName := cfg.Storages[0].Name storageRoot := cfg.Storages[0].Path // file walk happens lexicographically, so we delete repository in the middle - // of the seqeuence to ensure the walk proceeds normally - testRepo1, testRepo1Path := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - RelativePath: "a", + // of the sequence to ensure the walk proceeds normally + testRepo1, testRepo1Path := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: "a", }) - deletedRepo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - RelativePath: "b", + deletedRepo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: "b", }) - testRepo2, testRepo2Path := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - RelativePath: "c", + testRepo2, testRepo2Path := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + RelativePath: "c", }) modifiedDate := time.Now().Add(-1 * time.Hour) @@ -85,7 +95,6 @@ func TestWalkRepos(t *testing.T) { } client := setupInternalGitalyService(t, cfg, wsrv) - ctx := testhelper.Context(t) stream, err := client.WalkRepos(ctx, &gitalypb.WalkReposRequest{ StorageName: "invalid storage name", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace.go index 4023144b2c..b3a5215d11 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace.go @@ -7,8 +7,8 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace_test.go index 5319f67ab3..51b4b64a94 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/namespace_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/namespace_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package namespace import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/server.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/server.go index 3442313eed..aac47e822d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/server.go @@ -1,8 +1,8 @@ package namespace import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/testhelper_test.go new file mode 100644 index 0000000000..2fba9813b8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace/testhelper_test.go @@ -0,0 +1,32 @@ +//go:build !gitaly_test_sha256 + +package namespace + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func setupNamespaceService(tb testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, gitalypb.NamespaceServiceClient) { + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages("default", "other")) + cfg := cfgBuilder.Build(tb) + + addr := testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + gitalypb.RegisterNamespaceServiceServer(srv, NewServer(deps.GetLocator())) + }, opts...) + + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(tb, err) + tb.Cleanup(func() { testhelper.MustClose(tb, conn) }) + + return cfg, gitalypb.NewNamespaceServiceClient(conn) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates.go index 03951cc17a..8f87031145 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates.go @@ -11,11 +11,11 @@ import ( "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // DisconnectGitAlternates is a slightly dangerous RPC. It optimistically diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates_test.go index 851dafb8e1..b1129d81c4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/alternates_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/alternates_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestDisconnectGitAlternates(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create.go index 2dfd35f0a6..fb078a07e8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create.go @@ -3,9 +3,9 @@ package objectpool import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create_test.go index c8b77063c4..f040d6f8f3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/create_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/create_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -7,11 +9,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestCreate(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool.go index ff65b77c38..a825d3fc31 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/fetch_into_object_pool.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FetchIntoObjectPool(ctx context.Context, req *gitalypb.FetchIntoObjectPoolRequest) (*gitalypb.FetchIntoObjectPoolResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go new file mode 100644 index 0000000000..03262537b3 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go @@ -0,0 +1,436 @@ +//go:build !gitaly_test_sha256 + +package objectpool + +import ( + "context" + "fmt" + "os" + "path/filepath" + "sync" + "testing" + "time" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/peer" +) + +func TestFetchIntoObjectPool_Success(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchIntoObjectPoolSuccess) +} + +func testFetchIntoObjectPoolSuccess(t *testing.T, ctx context.Context) { + t.Parallel() + + cfg, repo, repoPath, locator, client := setup(ctx, t) + + repoCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(t.Name())) + + pool := initObjectPool(t, cfg, cfg.Storages[0]) + _, err := client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + req := &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + } + + _, err = client.FetchIntoObjectPool(ctx, req) + require.NoError(t, err) + + pool = rewrittenObjectPool(ctx, t, cfg, pool) + + require.True(t, pool.IsValid(), "ensure underlying repository is valid") + + // No problems + gittest.Exec(t, cfg, "-C", pool.FullPath(), "fsck") + + // Verify that the newly written commit exists in the repository now. + gittest.Exec(t, cfg, "-C", pool.FullPath(), "rev-parse", "--verify", repoCommit.String()) + + _, err = client.FetchIntoObjectPool(ctx, req) + require.NoError(t, err, "calling FetchIntoObjectPool twice should be OK") + require.True(t, pool.IsValid(), "ensure that pool is valid") + + // Simulate a broken ref + poolPath, err := locator.GetRepoPath(pool) + require.NoError(t, err) + brokenRef := filepath.Join(poolPath, "refs", "heads", "broken") + require.NoError(t, os.MkdirAll(filepath.Dir(brokenRef), 0o755)) + require.NoError(t, os.WriteFile(brokenRef, []byte{}, 0o777)) + + oldTime := time.Now().Add(-25 * time.Hour) + require.NoError(t, os.Chtimes(brokenRef, oldTime, oldTime)) + + _, err = client.FetchIntoObjectPool(ctx, req) + require.NoError(t, err) + + _, err = os.Stat(brokenRef) + require.Error(t, err, "Expected refs/heads/broken to be deleted") +} + +func TestFetchIntoObjectPool_transactional(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchIntoObjectPoolTransactional) +} + +func testFetchIntoObjectPoolTransactional(t *testing.T, ctx context.Context) { + t.Parallel() + + var votes []voting.Vote + var votesMutex sync.Mutex + txManager := transaction.MockManager{ + VoteFn: func(_ context.Context, _ txinfo.Transaction, vote voting.Vote, _ voting.Phase) error { + votesMutex.Lock() + defer votesMutex.Unlock() + votes = append(votes, vote) + return nil + }, + } + + cfg := testcfg.Build(t) + cfg.SocketPath = runObjectPoolServer( + t, cfg, config.NewLocator(cfg), + testhelper.NewDiscardingLogger(t), + testserver.WithTransactionManager(&txManager), + // We need to disable Praefect given that we replace transactions with our own logic + // here. + testserver.WithDisablePraefect(), + ) + testcfg.BuildGitalyHooks(t, cfg) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + conn, err := grpc.Dial(cfg.SocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer testhelper.MustClose(t, conn) + + client := gitalypb.NewObjectPoolServiceClient(conn) + + pool := initObjectPool(t, cfg, cfg.Storages[0]) + _, err = client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + // CreateObjectPool has a bug because it will leave the configuration of the origin remote + // in the gitconfig. This will get cleaned up at a later point by our housekeeping logic, so + // it doesn't hurt much in the first place to have it. But the cleanup logic would trigger + // another transactional vote which we want to avoid, so we simply unset the configuration + // here. + gittest.Exec(t, cfg, "-C", pool.FullPath(), "config", "--unset", "remote.origin.url") + + // Inject transaction information so that FetchInotObjectPool knows to perform + // transactional voting. + ctx, err = txinfo.InjectTransaction(peer.NewContext(ctx, &peer.Peer{}), 1, "node", true) + require.NoError(t, err) + ctx = metadata.IncomingToOutgoing(ctx) + + t.Run("without changed data", func(t *testing.T) { + votes = nil + + _, err = client.FetchIntoObjectPool(ctx, &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + if featureflag.FetchIntoObjectPoolPruneRefs.IsEnabled(ctx) { + require.Equal(t, []voting.Vote{ + // We expect to see two votes that demonstrate we're voting on no deleted + // references. + voting.VoteFromData(nil), voting.VoteFromData(nil), + // It is a bug though that we don't have a vote on the unchanged references + // in git-fetch(1). + }, votes) + } else { + require.Nil(t, votes) + } + }) + + t.Run("with a new reference", func(t *testing.T) { + votes = nil + + // Create a new reference that we'd in fact fetch into the object pool so that we + // know that something will be voted on. + repoCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithBranch("new-branch")) + + _, err = client.FetchIntoObjectPool(ctx, &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + vote := voting.VoteFromData([]byte(fmt.Sprintf( + "%s %s refs/remotes/origin/heads/new-branch\n", git.ObjectHashSHA1.ZeroOID, repoCommit, + ))) + if featureflag.FetchIntoObjectPoolPruneRefs.IsEnabled(ctx) { + require.Equal(t, []voting.Vote{ + // The first two votes stem from the fact that we're voting on no + // deleted references. + voting.VoteFromData(nil), voting.VoteFromData(nil), + // And the other two votes are from the new branch we pull in. + vote, vote, + }, votes) + } else { + require.Equal(t, []voting.Vote{vote, vote}, votes) + } + }) + + t.Run("with a stale reference in pool", func(t *testing.T) { + votes = nil + + reference := "refs/remotes/origin/heads/to-be-pruned" + + // Create a commit in the pool repository itself. Right now, we don't touch this + // commit at all, but this will change in one of the next commits. + gittest.WriteCommit(t, cfg, pool.FullPath(), gittest.WithParents(), gittest.WithReference(reference)) + + _, err = client.FetchIntoObjectPool(ctx, &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + if featureflag.FetchIntoObjectPoolPruneRefs.IsEnabled(ctx) { + // We expect a single vote on the reference we have deleted. + vote := voting.VoteFromData([]byte(fmt.Sprintf( + "%[1]s %[1]s %s\n", git.ObjectHashSHA1.ZeroOID, reference, + ))) + require.Equal(t, []voting.Vote{vote, vote}, votes) + } else { + require.Nil(t, votes) + } + + exists, err := pool.Repo.HasRevision(ctx, git.Revision(reference)) + require.NoError(t, err) + require.Equal(t, exists, featureflag.FetchIntoObjectPoolPruneRefs.IsDisabled(ctx)) + }) +} + +func TestFetchIntoObjectPool_CollectLogStatistics(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchIntoObjectPoolCollectLogStatistics) +} + +func testFetchIntoObjectPoolCollectLogStatistics(t *testing.T, ctx context.Context) { + t.Parallel() + + cfg := testcfg.Build(t) + testcfg.BuildGitalyHooks(t, cfg) + + locator := config.NewLocator(cfg) + + logger, hook := test.NewNullLogger() + cfg.SocketPath = runObjectPoolServer(t, cfg, locator, logger) + + ctx = ctxlogrus.ToContext(ctx, log.WithField("test", "logging")) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + conn, err := grpc.Dial(cfg.SocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + t.Cleanup(func() { testhelper.MustClose(t, conn) }) + client := gitalypb.NewObjectPoolServiceClient(conn) + + pool := initObjectPool(t, cfg, cfg.Storages[0]) + _, err = client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + req := &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + } + + _, err = client.FetchIntoObjectPool(ctx, req) + require.NoError(t, err) + + const key = "count_objects" + for _, logEntry := range hook.AllEntries() { + if stats, ok := logEntry.Data[key]; ok { + require.IsType(t, map[string]interface{}{}, stats) + + var keys []string + for key := range stats.(map[string]interface{}) { + keys = append(keys, key) + } + + require.ElementsMatch(t, []string{ + "count", + "garbage", + "in-pack", + "packs", + "prune-packable", + "size", + "size-garbage", + "size-pack", + }, keys) + return + } + } + require.FailNow(t, "no info about statistics") +} + +func TestFetchIntoObjectPool_Failure(t *testing.T) { + cfgBuilder := testcfg.NewGitalyCfgBuilder() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + locator := config.NewLocator(cfg) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + txManager := transaction.NewManager(cfg, backchannel.NewRegistry()) + + server := NewServer( + locator, + gitCmdFactory, + catfileCache, + txManager, + housekeeping.NewManager(cfg.Prometheus, txManager), + ) + ctx := testhelper.Context(t) + + pool := initObjectPool(t, cfg, cfg.Storages[0]) + + poolWithDifferentStorage := pool.ToProto() + poolWithDifferentStorage.Repository.StorageName = "some other storage" + + testCases := []struct { + description string + request *gitalypb.FetchIntoObjectPoolRequest + code codes.Code + errMsg string + }{ + { + description: "empty origin", + request: &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + }, + code: codes.InvalidArgument, + errMsg: "origin is empty", + }, + { + description: "empty pool", + request: &gitalypb.FetchIntoObjectPoolRequest{ + Origin: repos[0], + }, + code: codes.InvalidArgument, + errMsg: "object pool is empty", + }, + { + description: "origin and pool do not share the same storage", + request: &gitalypb.FetchIntoObjectPoolRequest{ + Origin: repos[0], + ObjectPool: poolWithDifferentStorage, + }, + code: codes.InvalidArgument, + errMsg: "origin has different storage than object pool", + }, + } + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + _, err := server.FetchIntoObjectPool(ctx, tc.request) + require.Error(t, err) + testhelper.RequireGrpcCode(t, err, tc.code) + assert.Contains(t, err.Error(), tc.errMsg) + }) + } +} + +func TestFetchIntoObjectPool_dfConflict(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FetchIntoObjectPoolPruneRefs).Run(t, testFetchIntoObjectPoolDfConflict) +} + +func testFetchIntoObjectPoolDfConflict(t *testing.T, ctx context.Context) { + t.Parallel() + + cfg, repo, repoPath, _, client := setup(ctx, t) + + pool := initObjectPool(t, cfg, cfg.Storages[0]) + _, err := client.CreateObjectPool(ctx, &gitalypb.CreateObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("branch")) + + // Perform an initial fetch into the object pool with the given object that exists in the + // pool member's repository. + _, err = client.FetchIntoObjectPool(ctx, &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + // Now we delete the reference in the pool member and create a new reference that has the + // same prefix, but is stored in a subdirectory. This will create a D/F conflict. + gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "-d", "refs/heads/branch") + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("branch/conflict")) + + gitVersion, err := gittest.NewCommandFactory(t, cfg).GitVersion(ctx) + require.NoError(t, err) + + // Due to a bug in old Git versions we may get an unexpected exit status. + expectedExitStatus := 254 + if !gitVersion.FlushesUpdaterefStatus() { + expectedExitStatus = 1 + } + + // Verify that we can still fetch into the object pool regardless of the D/F conflict. While + // it is not possible to store both references at the same time due to the conflict, we + // should know to delete the old conflicting reference and replace it with the new one. + _, err = client.FetchIntoObjectPool(ctx, &gitalypb.FetchIntoObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + if featureflag.FetchIntoObjectPoolPruneRefs.IsEnabled(ctx) { + require.NoError(t, err) + + poolPath, err := config.NewLocator(cfg).GetRepoPath(gittest.RewrittenRepository(ctx, t, cfg, pool.ToProto().GetRepository())) + require.NoError(t, err) + + // Verify that the conflicting reference exists now. + gittest.Exec(t, cfg, "-C", poolPath, "rev-parse", "refs/remotes/origin/heads/branch/conflict") + } else { + // But right now it fails due to a bug. + testhelper.RequireGrpcError(t, helper.ErrInternalf( + "fetch into object pool: exit status %d, stderr: %q", + expectedExitStatus, + "error: cannot lock ref 'refs/remotes/origin/heads/branch/conflict': 'refs/remotes/origin/heads/branch' exists; cannot create 'refs/remotes/origin/heads/branch/conflict'\n", + ), err) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get.go index 063d42908a..5a7ada7c65 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get.go @@ -5,9 +5,9 @@ import ( "errors" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) GetObjectPool(ctx context.Context, in *gitalypb.GetObjectPoolRequest) (*gitalypb.GetObjectPoolResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get_test.go index 41764461fa..3fcef9f971 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/get_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/get_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -6,9 +8,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestGetObjectPoolSuccess(t *testing.T) { @@ -37,10 +39,10 @@ func TestGetObjectPoolSuccess(t *testing.T) { func TestGetObjectPoolNoFile(t *testing.T) { ctx := testhelper.Context(t) - _, repoo, _, _, client := setup(ctx, t) + _, repo, _, _, client := setup(ctx, t) resp, err := client.GetObjectPool(ctx, &gitalypb.GetObjectPoolRequest{ - Repository: repoo, + Repository: repo, }) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link.go index cbb16f0ac0..4a89f99a92 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link.go @@ -3,8 +3,8 @@ package objectpool import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link_test.go index 9b58be35af..0ccae96a62 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/link_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/link_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -6,12 +8,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate.go index d96c98dd2c..b067f899f2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate.go @@ -3,8 +3,8 @@ package objectpool import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate_test.go index 721fc6f26a..e05a863093 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/reduplicate_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/reduplicate_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestReduplicate(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/server.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/server.go index cf3ba2e4f6..a2bc65bc00 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/server.go @@ -1,14 +1,14 @@ package objectpool import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/testhelper_test.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/testhelper_test.go index 3ea7f981c3..0d37c3f23e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package objectpool import ( @@ -8,22 +10,23 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func TestMain(m *testing.M) { @@ -52,7 +55,7 @@ func setup(ctx context.Context, t *testing.T, opts ...testserver.GitalyServerOpt locator := config.NewLocator(cfg) cfg.SocketPath = runObjectPoolServer(t, cfg, locator, testhelper.NewDiscardingLogger(t), opts...) - conn, err := grpc.Dial(cfg.SocketPath, grpc.WithInsecure()) + conn, err := grpc.Dial(cfg.SocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { testhelper.MustClose(t, conn) }) @@ -60,6 +63,14 @@ func setup(ctx context.Context, t *testing.T, opts ...testserver.GitalyServerOpt Seed: gittest.SeedGitLabTest, }) + // For the time being we need to fix up the repository to make it work in the context of + // commit-graphs. Because initializing the pool from the repository will just copy over + // objects 1:1 we also need to repack the repository, or otherwise it would still have a + // reference to the deleted commit. And because we make sure to keep alive dangling objects + // via keep-around references we'd thus make the broken commit reachable again. + gittest.FixGitLabTestRepoForCommitGraphs(t, cfg, repoPath) + gittest.Exec(t, cfg, "-C", repoPath, "repack", "-a", "-d") + return cfg, repo, repoPath, locator, clientWithConn{ObjectPoolServiceClient: gitalypb.NewObjectPoolServiceClient(conn), conn: conn} } @@ -75,8 +86,7 @@ func runObjectPoolServer(t *testing.T, cfg config.Cfg, locator storage.Locator, gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer( deps.GetHookManager(), deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - )) + deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( cfg, deps.GetRubyServer(), @@ -91,46 +101,46 @@ func runObjectPoolServer(t *testing.T, cfg config.Cfg, locator storage.Locator, }, append(opts, testserver.WithLocator(locator), testserver.WithLogger(logger))...) } -func newObjectPool(t testing.TB, cfg config.Cfg, storage, relativePath string) *objectpool.ObjectPool { +func newObjectPool(tb testing.TB, cfg config.Cfg, storage, relativePath string) *objectpool.ObjectPool { catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) + tb.Cleanup(catfileCache.Stop) txManager := transaction.NewManager(cfg, backchannel.NewRegistry()) pool, err := objectpool.NewObjectPool( config.NewLocator(cfg), - gittest.NewCommandFactory(t, cfg), + gittest.NewCommandFactory(tb, cfg), catfileCache, txManager, housekeeping.NewManager(cfg.Prometheus, txManager), storage, relativePath, ) - require.NoError(t, err) + require.NoError(tb, err) return pool } // initObjectPool creates a new empty object pool in the given storage. -func initObjectPool(t testing.TB, cfg config.Cfg, storage config.Storage) *objectpool.ObjectPool { - t.Helper() +func initObjectPool(tb testing.TB, cfg config.Cfg, storage config.Storage) *objectpool.ObjectPool { + tb.Helper() - relativePath := gittest.NewObjectPoolName(t) - gittest.InitRepoDir(t, storage.Path, relativePath) + relativePath := gittest.NewObjectPoolName(tb) + gittest.InitRepoDir(tb, storage.Path, relativePath) catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) + tb.Cleanup(catfileCache.Stop) - pool := newObjectPool(t, cfg, storage.Name, relativePath) + pool := newObjectPool(tb, cfg, storage.Name, relativePath) poolPath := filepath.Join(storage.Path, relativePath) - t.Cleanup(func() { require.NoError(t, os.RemoveAll(poolPath)) }) + tb.Cleanup(func() { require.NoError(tb, os.RemoveAll(poolPath)) }) return pool } // rewrittenObjectPool returns a pool that is rewritten as if it was passed through Praefect. This should be used // to access the pool on the disk if the tests are running with Praefect in front of them. -func rewrittenObjectPool(ctx context.Context, t testing.TB, cfg config.Cfg, pool *objectpool.ObjectPool) *objectpool.ObjectPool { - replicaPath := gittest.GetReplicaPath(ctx, t, cfg, pool) - return newObjectPool(t, cfg, pool.GetStorageName(), replicaPath) +func rewrittenObjectPool(ctx context.Context, tb testing.TB, cfg config.Cfg, pool *objectpool.ObjectPool) *objectpool.ObjectPool { + replicaPath := gittest.GetReplicaPath(ctx, tb, cfg, pool) + return newObjectPool(tb, cfg, pool.GetStorageName(), replicaPath) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch.go index f87cec9699..c86297abc5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch.go @@ -10,12 +10,12 @@ import ( "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -33,7 +33,7 @@ func (er gitError) Error() string { return er.ErrMsg + ": " + er.Err.Error() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserApplyPatch(stream gitalypb.OperationService_UserApplyPatchServer) error { firstRequest, err := stream.Recv() if err != nil { @@ -169,14 +169,14 @@ func (s *Server) userApplyPatch(ctx context.Context, header *gitalypb.UserApplyP return fmt.Errorf("get patched commit: %w", gitError{ErrMsg: revParseStderr.String(), Err: err}) } - patchedCommit, err := git.NewObjectIDFromHex(text.ChompBytes(revParseStdout.Bytes())) + patchedCommit, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(revParseStdout.Bytes())) if err != nil { return fmt.Errorf("parse patched commit oid: %w", err) } currentCommit := parentCommitID if branchCreated { - currentCommit = git.ZeroOID + currentCommit = git.ObjectHashSHA1.ZeroOID } if err := s.updateReferenceWithHooks(ctx, header.Repository, header.User, nil, targetBranch, patchedCommit, currentCommit); err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch_test.go index c7e5ffb15b..e1a38ab824 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/apply_patch_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/apply_patch_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -10,20 +12,20 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/peer" "google.golang.org/grpc/status" @@ -40,18 +42,18 @@ func TestUserApplyPatch(t *testing.T) { type actionFunc func(testing.TB, *localrepo.Repo) git2go.Action createFile := func(filepath string, content string) actionFunc { - return func(t testing.TB, repo *localrepo.Repo) git2go.Action { + return func(tb testing.TB, repo *localrepo.Repo) git2go.Action { fileOID, err := repo.WriteBlob(ctx, filepath, strings.NewReader(content)) - require.NoError(t, err) + require.NoError(tb, err) return git2go.CreateFile{Path: filepath, OID: fileOID.String()} } } updateFile := func(filepath string, content string) actionFunc { - return func(t testing.TB, repo *localrepo.Repo) git2go.Action { + return func(tb testing.TB, repo *localrepo.Repo) git2go.Action { fileOID, err := repo.WriteBlob(ctx, filepath, strings.NewReader(content)) - require.NoError(t, err) + require.NoError(tb, err) return git2go.UpdateFile{Path: filepath, OID: fileOID.String()} } @@ -291,7 +293,7 @@ To restore the original branch and stop patching, run "git am --abort". var baseCommit git.ObjectID for _, action := range tc.baseCommit { var err error - baseCommit, err = executor.Commit(ctx, rewrittenRepo, git2go.CommitParams{ + baseCommit, err = executor.Commit(ctx, rewrittenRepo, git2go.CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -303,11 +305,11 @@ To restore the original branch and stop patching, run "git am --abort". } if baseCommit != "" { - require.NoError(t, repo.UpdateRef(ctx, tc.baseReference, baseCommit, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, tc.baseReference, baseCommit, git.ObjectHashSHA1.ZeroOID)) } if tc.extraBranches != nil { - emptyCommit, err := executor.Commit(ctx, rewrittenRepo, git2go.CommitParams{ + emptyCommit, err := executor.Commit(ctx, rewrittenRepo, git2go.CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -317,7 +319,7 @@ To restore the original branch and stop patching, run "git am --abort". for _, extraBranch := range tc.extraBranches { require.NoError(t, repo.UpdateRef(ctx, - git.NewReferenceNameFromBranchName(extraBranch), emptyCommit, git.ZeroOID), + git.NewReferenceNameFromBranchName(extraBranch), emptyCommit, git.ObjectHashSHA1.ZeroOID), ) } } @@ -327,7 +329,7 @@ To restore the original branch and stop patching, run "git am --abort". commit := baseCommit for _, action := range commitActions { var err error - commit, err = executor.Commit(ctx, rewrittenRepo, git2go.CommitParams{ + commit, err = executor.Commit(ctx, rewrittenRepo, git2go.CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -373,14 +375,30 @@ To restore the original branch and stop patching, run "git am --abort". }, })) + outerLoop: for _, patch := range patches { // we stream the patches one rune at a time to exercise the streaming code for _, r := range patch { - require.NoError(t, stream.Send(&gitalypb.UserApplyPatchRequest{ + err := stream.Send(&gitalypb.UserApplyPatchRequest{ UserApplyPatchRequestPayload: &gitalypb.UserApplyPatchRequest_Patches{ Patches: []byte{r}, }, - })) + }) + + // In case the request we're sending to the server results + // in an error it can happen that the server already noticed + // the request and thus returned an error while we're still + // streaming the actual patch data. If so, the server closes + // the stream and we are left unable to continue sending, + // which means we get an EOF here. + // + // Abort the loop here so that we can observe the actual + // error in `CloseAndRecv()`. + if err == io.EOF { + break outerLoop + } + + require.NoError(t, err) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches.go index 736f3c1550..adaa0442d7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches.go @@ -4,14 +4,17 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateBranchRequest) (*gitalypb.UserCreateBranchResponse, error) { if len(req.BranchName) == 0 { return nil, status.Errorf(codes.InvalidArgument, "Bad Request (empty branch name)") @@ -42,7 +45,7 @@ func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateB return nil, status.Errorf(codes.FailedPrecondition, "revspec '%s' not found", req.StartPoint) } - startPointOID, err := git.NewObjectIDFromHex(startPointCommit.Id) + startPointOID, err := git.ObjectHashSHA1.FromHex(startPointCommit.Id) if err != nil { return nil, status.Errorf(codes.Internal, "could not parse start point commit ID: %v", err) } @@ -55,12 +58,34 @@ func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateB return nil, status.Error(codes.Internal, err.Error()) } - if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, startPointOID, git.ZeroOID); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { - return &gitalypb.UserCreateBranchResponse{ - PreReceiveError: hookError.Error(), - }, nil + if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, startPointOID, git.ObjectHashSHA1.ZeroOID); err != nil { + var customHookErr updateref.CustomHookError + + if errors.As(err, &customHookErr) { + if featureflag.UserCreateBranchStructuredErrors.IsEnabled(ctx) { + detailedErr, err := helper.ErrWithDetails( + // We explicitly don't include the custom hook error itself + // in the returned error because that would also contain the + // standard output or standard error in the error message. + // It's thus needlessly verbose and duplicates information + // we have available in the structured error anyway. + helper.ErrPermissionDeniedf("creation denied by custom hooks"), + &gitalypb.UserCreateBranchError{ + Error: &gitalypb.UserCreateBranchError_CustomHook{ + CustomHook: customHookErr.Proto(), + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } else { + return &gitalypb.UserCreateBranchResponse{ + PreReceiveError: customHookErr.Error(), + }, nil + } } var updateRefError updateref.Error @@ -99,19 +124,19 @@ func validateUserUpdateBranchGo(req *gitalypb.UserUpdateBranchRequest) error { return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserUpdateBranch(ctx context.Context, req *gitalypb.UserUpdateBranchRequest) (*gitalypb.UserUpdateBranchResponse, error) { // Validate the request if err := validateUserUpdateBranchGo(req); err != nil { return nil, err } - newOID, err := git.NewObjectIDFromHex(string(req.Newrev)) + newOID, err := git.ObjectHashSHA1.FromHex(string(req.Newrev)) if err != nil { return nil, status.Errorf(codes.Internal, "could not parse newrev: %v", err) } - oldOID, err := git.NewObjectIDFromHex(string(req.Oldrev)) + oldOID, err := git.ObjectHashSHA1.FromHex(string(req.Oldrev)) if err != nil { return nil, status.Errorf(codes.Internal, "could not parse oldrev: %v", err) } @@ -124,10 +149,10 @@ func (s *Server) UserUpdateBranch(ctx context.Context, req *gitalypb.UserUpdateB } if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, newOID, oldOID); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + var customHookErr updateref.CustomHookError + if errors.As(err, &customHookErr) { return &gitalypb.UserUpdateBranchResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErr.Error(), }, nil } @@ -143,40 +168,83 @@ func (s *Server) UserUpdateBranch(ctx context.Context, req *gitalypb.UserUpdateB return &gitalypb.UserUpdateBranchResponse{}, nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +// UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes +// hooks and contacts Rails to verify that the user is indeed allowed to delete that branch. func (s *Server) UserDeleteBranch(ctx context.Context, req *gitalypb.UserDeleteBranchRequest) (*gitalypb.UserDeleteBranchResponse, error) { - // That we do the branch name & user check here first only in - // UserDelete but not UserCreate is "intentional", i.e. it's - // always been that way. if len(req.BranchName) == 0 { - return nil, status.Errorf(codes.InvalidArgument, "Bad Request (empty branch name)") + return nil, helper.ErrInvalidArgumentf("bad request: empty branch name") } if req.User == nil { - return nil, status.Errorf(codes.InvalidArgument, "Bad Request (empty user)") + return nil, helper.ErrInvalidArgumentf("bad request: empty user") } referenceName := git.NewReferenceNameFromBranchName(string(req.BranchName)) referenceValue, err := s.localrepo(req.GetRepository()).ResolveRevision(ctx, referenceName.Revision()) if err != nil { - return nil, status.Errorf(codes.FailedPrecondition, "branch not found: %s", req.BranchName) + return nil, helper.ErrFailedPreconditionf("branch not found: %q", req.BranchName) } - if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, nil, referenceName, git.ZeroOID, referenceValue); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { - return &gitalypb.UserDeleteBranchResponse{ - PreReceiveError: hookError.Error(), - }, nil - } - + if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, nil, referenceName, git.ObjectHashSHA1.ZeroOID, referenceValue); err != nil { + var notAllowedError hook.NotAllowedError + var customHookErr updateref.CustomHookError var updateRefError updateref.Error - if errors.As(err, &updateRefError) { - return nil, status.Error(codes.FailedPrecondition, err.Error()) + + if errors.As(err, ¬AllowedError) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrPermissionDeniedf("deletion denied by access checks: %w", err), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: notAllowedError.Message, + UserId: notAllowedError.UserID, + Protocol: notAllowedError.Protocol, + Changes: notAllowedError.Changes, + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } else if errors.As(err, &customHookErr) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrPermissionDeniedf("deletion denied by custom hooks: %w", err), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_CustomHook{ + CustomHook: customHookErr.Proto(), + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } else if errors.As(err, &updateRefError) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("reference update failed: %w", updateRefError), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_ReferenceUpdate{ + ReferenceUpdate: &gitalypb.ReferenceUpdateError{ + ReferenceName: []byte(updateRefError.Reference.String()), + OldOid: updateRefError.OldOID.String(), + NewOid: updateRefError.NewOID.String(), + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr } - return nil, err + return nil, helper.ErrInternalf("deleting reference: %w", err) } return &gitalypb.UserDeleteBranchResponse{}, nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches_test.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches_test.go index 7a660f91d6..bea7771101 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/branches_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/branches_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -6,18 +8,22 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -35,9 +41,13 @@ func (s *testTransactionServer) VoteTransaction(ctx context.Context, in *gitalyp }, nil } -func TestSuccessfulCreateBranchRequest(t *testing.T) { +func TestUserCreateBranch_successful(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchSuccessful) +} + +func testUserCreateBranchSuccessful(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) @@ -112,9 +122,13 @@ func TestSuccessfulCreateBranchRequest(t *testing.T) { } } -func TestUserCreateBranchWithTransaction(t *testing.T) { +func TestUserCreateBranch_Transactions(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchTransactions) +} + +func testUserCreateBranchTransactions(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) cfg, repo, repoPath := testcfg.BuildWithRepo(t) @@ -132,7 +146,7 @@ func TestUserCreateBranchWithTransaction(t *testing.T) { deps.GetCatfileCache(), deps.GetUpdaterWithHooks(), )) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) // Praefect proxy execution disabled as praefect runs only on the UNIX socket, but // the test requires a TCP listening address. }, testserver.WithDisablePraefect()) @@ -147,7 +161,7 @@ func TestUserCreateBranchWithTransaction(t *testing.T) { }, { desc: "Unix socket", - address: "unix://" + cfg.GitalyInternalSocketPath(), + address: "unix://" + cfg.InternalSocketPath(), }, } @@ -186,9 +200,13 @@ func TestUserCreateBranchWithTransaction(t *testing.T) { } } -func TestSuccessfulGitHooksForUserCreateBranchRequest(t *testing.T) { +func TestUserCreateBranch_hook(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchHook) +} + +func testUserCreateBranchHook(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) @@ -216,9 +234,13 @@ func TestSuccessfulGitHooksForUserCreateBranchRequest(t *testing.T) { } } -func TestSuccessfulCreateBranchRequestWithStartPointRefPrefix(t *testing.T) { +func TestUserCreateBranch_startPoint(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchStartPoint) +} + +func testUserCreateBranchStartPoint(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) @@ -256,7 +278,7 @@ func TestSuccessfulCreateBranchRequestWithStartPointRefPrefix(t *testing.T) { t.Run(testCase.desc, func(t *testing.T) { gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/"+testCase.startPoint, testCase.startPointCommit, - git.ZeroOID.String(), + git.ObjectHashSHA1.ZeroOID.String(), ) request := &gitalypb.UserCreateBranchRequest{ Repository: repoProto, @@ -289,9 +311,13 @@ func TestSuccessfulCreateBranchRequestWithStartPointRefPrefix(t *testing.T) { } } -func TestFailedUserCreateBranchDueToHooks(t *testing.T) { +func TestUserCreateBranch_hookFailure(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchHookFailure) +} + +func testUserCreateBranchHookFailure(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) ctx, _, repo, repoPath, client := setupOperationsService(t, ctx) @@ -301,22 +327,42 @@ func TestFailedUserCreateBranchDueToHooks(t *testing.T) { StartPoint: []byte("c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd"), User: gittest.TestUser, } - // Write a hook that will fail with the environment as the error message - // so we can check that string for our env variables. - hookContent := []byte("#!/bin/sh\nprintenv | paste -sd ' ' -\nexit 1") + + hookContent := []byte("#!/bin/sh\necho GL_ID=$GL_ID\nexit 1") + + expectedObject := "GL_ID=" + gittest.TestUser.GlId for _, hookName := range gitlabPreHooks { gittest.WriteCustomHook(t, repoPath, hookName, hookContent) response, err := client.UserCreateBranch(ctx, request) - require.Nil(t, err) - require.Contains(t, response.PreReceiveError, "GL_USERNAME="+gittest.TestUser.GlUsername) + + if featureflag.UserCreateBranchStructuredErrors.IsEnabled(ctx) { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("creation denied by custom hooks"), + &gitalypb.UserCreateBranchError{ + Error: &gitalypb.UserCreateBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + Stdout: []byte(expectedObject + "\n"), + }, + }, + }, + ), err) + } else { + require.Nil(t, err) + require.Contains(t, response.PreReceiveError, expectedObject) + } } } -func TestFailedUserCreateBranchRequest(t *testing.T) { +func TestUserCreateBranch_Failure(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testUserCreateBranchFailure) +} + +func testUserCreateBranchFailure(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) ctx, _, repo, _, client := setupOperationsService(t, ctx) @@ -374,10 +420,10 @@ func TestFailedUserCreateBranchRequest(t *testing.T) { } } -func TestSuccessfulUserDeleteBranchRequest(t *testing.T) { +func TestUserDeleteBranch_success(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + ctx := testhelper.Context(t) ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) testCases := []struct { @@ -429,8 +475,129 @@ func TestSuccessfulUserDeleteBranchRequest(t *testing.T) { } } -func TestSuccessfulGitHooksForUserDeleteBranchRequest(t *testing.T) { +func TestUserDeleteBranch_allowed(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) + + for _, tc := range []struct { + desc string + allowed func(context.Context, gitlab.AllowedParams) (bool, string, error) + expectedErr error + expectedResponse *gitalypb.UserDeleteBranchResponse + }{ + { + desc: "allowed", + allowed: func(context.Context, gitlab.AllowedParams) (bool, string, error) { + return true, "", nil + }, + expectedResponse: &gitalypb.UserDeleteBranchResponse{}, + }, + { + desc: "not allowed", + allowed: func(context.Context, gitlab.AllowedParams) (bool, string, error) { + return false, "something something", nil + }, + expectedErr: errWithDetails(t, + helper.ErrPermissionDeniedf("deletion denied by access checks: running pre-receive hooks: GitLab: something something"), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + Protocol: "web", + UserId: "user-123", + ErrorMessage: "something something", + Changes: []byte(fmt.Sprintf( + "%s %s refs/heads/branch\n", "549090fbeacc6607bc70648d3ba554c355e670c5", git.ObjectHashSHA1.ZeroOID, + )), + }, + }, + }, + ), + }, + { + desc: "error", + allowed: func(context.Context, gitlab.AllowedParams) (bool, string, error) { + return false, "something something", fmt.Errorf("something else") + }, + expectedErr: errWithDetails(t, + helper.ErrPermissionDeniedf("deletion denied by access checks: running pre-receive hooks: GitLab: something else"), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + Protocol: "web", + UserId: "user-123", + ErrorMessage: "something else", + Changes: []byte(fmt.Sprintf( + "%s %s refs/heads/branch\n", "549090fbeacc6607bc70648d3ba554c355e670c5", git.ObjectHashSHA1.ZeroOID, + )), + }, + }, + }, + ), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx, testserver.WithGitLabClient( + gitlab.NewMockClient(t, tc.allowed, gitlab.MockPreReceive, gitlab.MockPostReceive), + )) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("branch")) + + response, err := client.UserDeleteBranch(ctx, &gitalypb.UserDeleteBranchRequest{ + Repository: repo, + BranchName: []byte("branch"), + User: gittest.TestUser, + }) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + testhelper.ProtoEqual(t, tc.expectedResponse, response) + }) + } +} + +func TestUserDeleteBranch_concurrentUpdate(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("concurrent-update")) + + // Create a git-update-ref(1) process that's locking the "concurrent-update" branch. We do + // not commit the update yet though to keep the reference locked to simulate concurrent + // writes to the same reference. + updater, err := updateref.New(ctx, localrepo.NewTestRepo(t, cfg, repo)) + require.NoError(t, err) + require.NoError(t, updater.Delete("refs/heads/concurrent-update")) + require.NoError(t, updater.Prepare()) + defer func() { + require.NoError(t, updater.Cancel()) + }() + + response, err := client.UserDeleteBranch(ctx, &gitalypb.UserDeleteBranchRequest{ + Repository: repo, + BranchName: []byte("concurrent-update"), + User: gittest.TestUser, + }) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPreconditionf("reference update failed: Could not update refs/heads/concurrent-update. Please refresh and try again."), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_ReferenceUpdate{ + ReferenceUpdate: &gitalypb.ReferenceUpdateError{ + OldOid: commitID.String(), + NewOid: git.ObjectHashSHA1.ZeroOID.String(), + ReferenceName: []byte("refs/heads/concurrent-update"), + }, + }, + }, + ), err) + require.Nil(t, response) +} + +func TestUserDeleteBranch_hooks(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) @@ -460,6 +627,8 @@ func TestSuccessfulGitHooksForUserDeleteBranchRequest(t *testing.T) { func TestUserDeleteBranch_transaction(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) cfg, repo, repoPath := testcfg.BuildWithRepo(t) // This creates a new branch "delete-me" which exists both in the packed-refs file and as a @@ -485,12 +654,12 @@ func TestUserDeleteBranch_transaction(t *testing.T) { deps.GetUpdaterWithHooks(), )) }) - ctx := testhelper.Context(t) + ctx, err := txinfo.InjectTransaction(ctx, 1, "node", true) require.NoError(t, err) ctx = metadata.IncomingToOutgoing(ctx) - client := newMuxedOperationClient(t, ctx, fmt.Sprintf("unix://"+cfg.GitalyInternalSocketPath()), cfg.Auth.Token, + client := newMuxedOperationClient(t, ctx, fmt.Sprintf("unix://"+cfg.InternalSocketPath()), cfg.Auth.Token, backchannel.NewClientHandshaker( testhelper.NewDiscardingLogEntry(t), func() backchannel.Server { @@ -510,8 +679,9 @@ func TestUserDeleteBranch_transaction(t *testing.T) { require.Equal(t, 2, transactionServer.called) } -func TestFailedUserDeleteBranchDueToValidation(t *testing.T) { +func TestUserDeleteBranch_invalidArgument(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) ctx, _, repo, _, client := setupOperationsService(t, ctx) @@ -529,7 +699,7 @@ func TestFailedUserDeleteBranchDueToValidation(t *testing.T) { BranchName: []byte("does-matter-the-name-if-user-is-empty"), }, response: nil, - err: status.Error(codes.InvalidArgument, "Bad Request (empty user)"), + err: status.Error(codes.InvalidArgument, "bad request: empty user"), }, { desc: "empty branch name", @@ -538,7 +708,7 @@ func TestFailedUserDeleteBranchDueToValidation(t *testing.T) { User: gittest.TestUser, }, response: nil, - err: status.Error(codes.InvalidArgument, "Bad Request (empty branch name)"), + err: status.Error(codes.InvalidArgument, "bad request: empty branch name"), }, { desc: "non-existent branch name", @@ -548,7 +718,7 @@ func TestFailedUserDeleteBranchDueToValidation(t *testing.T) { BranchName: []byte("i-do-not-exist"), }, response: nil, - err: status.Errorf(codes.FailedPrecondition, "branch not found: %s", "i-do-not-exist"), + err: status.Errorf(codes.FailedPrecondition, "branch not found: %q", "i-do-not-exist"), }, } @@ -561,8 +731,9 @@ func TestFailedUserDeleteBranchDueToValidation(t *testing.T) { } } -func TestFailedUserDeleteBranchDueToHooks(t *testing.T) { +func TestUserDeleteBranch_hookFailure(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) @@ -578,13 +749,36 @@ func TestFailedUserDeleteBranchDueToHooks(t *testing.T) { hookContent := []byte("#!/bin/sh\necho GL_ID=$GL_ID\nexit 1") - for _, hookName := range gitlabPreHooks { - t.Run(hookName, func(t *testing.T) { - gittest.WriteCustomHook(t, repoPath, hookName, hookContent) + for _, tc := range []struct { + hookName string + hookType gitalypb.CustomHookError_HookType + }{ + { + hookName: "pre-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + }, + { + hookName: "update", + hookType: gitalypb.CustomHookError_HOOK_TYPE_UPDATE, + }, + } { + t.Run(tc.hookName, func(t *testing.T) { + gittest.WriteCustomHook(t, repoPath, tc.hookName, hookContent) response, err := client.UserDeleteBranch(ctx, request) - require.NoError(t, err) - require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("deletion denied by custom hooks: running %s hooks: %s\n", tc.hookName, "GL_ID=user-123"), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: tc.hookType, + Stdout: []byte("GL_ID=user-123\n"), + }, + }, + }, + ), err) + + require.Nil(t, response) branches := gittest.Exec(t, cfg, "-C", repoPath, "for-each-ref", "--", "refs/heads/"+branchNameInput) require.Contains(t, string(branches), branchNameInput, "branch name does not exist in branches list") @@ -594,14 +788,20 @@ func TestFailedUserDeleteBranchDueToHooks(t *testing.T) { func TestBranchHookOutput(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + testhelper.NewFeatureSets(featureflag.UserCreateBranchStructuredErrors).Run(t, testBranchHookOutput) +} + +func testBranchHookOutput(t *testing.T, ctx context.Context) { + t.Parallel() ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) testCases := []struct { - desc string - hookContent string - output func(hookPath string) string + desc string + hookContent string + output func(hookPath string) string + expectedStderr string + expectedStdout string }{ { desc: "empty stdout and empty stderr", @@ -611,35 +811,55 @@ func TestBranchHookOutput(t *testing.T) { }, }, { - desc: "empty stdout and some stderr", - hookContent: "#!/bin/sh\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, + desc: "empty stdout and some stderr", + hookContent: "#!/bin/sh\necho stderr >&2\nexit 1", + output: func(string) string { return "stderr\n" }, + expectedStderr: "stderr\n", }, { - desc: "some stdout and empty stderr", - hookContent: "#!/bin/sh\necho stdout\nexit 1", - output: func(string) string { return "stdout\n" }, + desc: "some stdout and empty stderr", + hookContent: "#!/bin/sh\necho stdout\nexit 1", + output: func(string) string { return "stdout\n" }, + expectedStdout: "stdout\n", }, { - desc: "some stdout and some stderr", - hookContent: "#!/bin/sh\necho stdout\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, + desc: "some stdout and some stderr", + hookContent: "#!/bin/sh\necho stdout\necho stderr >&2\nexit 1", + output: func(string) string { return "stderr\n" }, + expectedStderr: "stderr\n", + expectedStdout: "stdout\n", }, { - desc: "whitespace stdout and some stderr", - hookContent: "#!/bin/sh\necho ' '\necho stderr >&2\nexit 1", - output: func(string) string { return "stderr\n" }, + desc: "whitespace stdout and some stderr", + hookContent: "#!/bin/sh\necho ' '\necho stderr >&2\nexit 1", + output: func(string) string { return "stderr\n" }, + expectedStderr: "stderr\n", + expectedStdout: " \n", }, { - desc: "some stdout and whitespace stderr", - hookContent: "#!/bin/sh\necho stdout\necho ' ' >&2\nexit 1", - output: func(string) string { return "stdout\n" }, + desc: "some stdout and whitespace stderr", + hookContent: "#!/bin/sh\necho stdout\necho ' ' >&2\nexit 1", + output: func(string) string { return "stdout\n" }, + expectedStderr: " \n", + expectedStdout: "stdout\n", }, } - for _, hookName := range gitlabPreHooks { + for _, hookTestCase := range []struct { + hookName string + hookType gitalypb.CustomHookError_HookType + }{ + { + hookName: "pre-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + }, + { + hookName: "update", + hookType: gitalypb.CustomHookError_HOOK_TYPE_UPDATE, + }, + } { for _, testCase := range testCases { - t.Run(hookName+"/"+testCase.desc, func(t *testing.T) { + t.Run(hookTestCase.hookName+"/"+testCase.desc, func(t *testing.T) { branchNameInput := "some-branch" createRequest := &gitalypb.UserCreateBranchRequest{ Repository: repo, @@ -653,19 +873,46 @@ func TestBranchHookOutput(t *testing.T) { User: gittest.TestUser, } - hookFilename := gittest.WriteCustomHook(t, repoPath, hookName, []byte(testCase.hookContent)) + hookFilename := gittest.WriteCustomHook(t, repoPath, hookTestCase.hookName, []byte(testCase.hookContent)) expectedError := testCase.output(hookFilename) createResponse, err := client.UserCreateBranch(ctx, createRequest) - require.NoError(t, err) - require.Equal(t, expectedError, createResponse.PreReceiveError) + + if featureflag.UserCreateBranchStructuredErrors.IsEnabled(ctx) { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("creation denied by custom hooks"), + &gitalypb.UserCreateBranchError{ + Error: &gitalypb.UserCreateBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: hookTestCase.hookType, + Stdout: []byte(testCase.expectedStdout), + Stderr: []byte(testCase.expectedStderr), + }, + }, + }, + ), err) + } else { + require.NoError(t, err) + require.Equal(t, expectedError, createResponse.PreReceiveError) + } gittest.Exec(t, cfg, "-C", repoPath, "branch", branchNameInput) defer gittest.Exec(t, cfg, "-C", repoPath, "branch", "-d", branchNameInput) deleteResponse, err := client.UserDeleteBranch(ctx, deleteRequest) - require.NoError(t, err) - require.Equal(t, expectedError, deleteResponse.PreReceiveError) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("deletion denied by custom hooks: running %s hooks: %s", hookTestCase.hookName, expectedError), + &gitalypb.UserDeleteBranchError{ + Error: &gitalypb.UserDeleteBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: hookTestCase.hookType, + Stdout: []byte(testCase.expectedStdout), + Stderr: []byte(testCase.expectedStderr), + }, + }, + }, + ), err) + require.Nil(t, deleteResponse) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick.go new file mode 100644 index 0000000000..fa45958fe1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick.go @@ -0,0 +1,187 @@ +package operations + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +//nolint: stylecheck // This is unintentionally missing documentation. +func (s *Server) UserCherryPick(ctx context.Context, req *gitalypb.UserCherryPickRequest) (*gitalypb.UserCherryPickResponse, error) { + if err := validateCherryPickOrRevertRequest(req); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "UserCherryPick: %v", err) + } + + quarantineDir, quarantineRepo, err := s.quarantinedRepo(ctx, req.GetRepository()) + if err != nil { + return nil, err + } + + startRevision, err := s.fetchStartRevision(ctx, quarantineRepo, req) + if err != nil { + return nil, err + } + + repoHadBranches, err := quarantineRepo.HasBranches(ctx) + if err != nil { + return nil, err + } + + repoPath, err := quarantineRepo.Path() + if err != nil { + return nil, err + } + + var mainline uint + if len(req.Commit.ParentIds) > 1 { + mainline = 1 + } + + committerDate := time.Now() + if req.Timestamp != nil { + committerDate = req.Timestamp.AsTime() + } + + newrev, err := s.git2goExecutor.CherryPick(ctx, quarantineRepo, git2go.CherryPickCommand{ + Repository: repoPath, + CommitterName: string(req.User.Name), + CommitterMail: string(req.User.Email), + CommitterDate: committerDate, + Message: string(req.Message), + Commit: req.Commit.Id, + Ours: startRevision.String(), + Mainline: mainline, + }) + if err != nil { + var conflictErr git2go.ConflictingFilesError + var emptyErr git2go.EmptyError + + switch { + case errors.As(err, &conflictErr): + conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) + for _, conflictingFile := range conflictErr.ConflictingFiles { + conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) + } + + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("cherry pick: %w", err), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_CherryPickConflict{ + CherryPickConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: conflictingFiles, + }, + }, + }, + ) + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + case errors.As(err, &emptyErr): + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(err), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, + }, + ) + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + case errors.Is(err, git2go.ErrInvalidArgument): + return nil, helper.ErrInvalidArgument(err) + default: + return nil, helper.ErrInternalf("cherry-pick command: %w", err) + } + } + + referenceName := git.NewReferenceNameFromBranchName(string(req.BranchName)) + + branchCreated := false + oldrev, err := quarantineRepo.ResolveRevision(ctx, referenceName.Revision()+"^{commit}") + if errors.Is(err, git.ErrReferenceNotFound) { + branchCreated = true + oldrev = git.ObjectHashSHA1.ZeroOID + } else if err != nil { + return nil, helper.ErrInvalidArgumentf("resolve ref: %w", err) + } + + if req.DryRun { + newrev = startRevision + } + + if !branchCreated { + ancestor, err := quarantineRepo.IsAncestor(ctx, oldrev.Revision(), newrev.Revision()) + if err != nil { + return nil, err + } + if !ancestor { + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(errors.New("cherry-pick: branch diverged")), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_TargetBranchDiverged{ + TargetBranchDiverged: &gitalypb.NotAncestorError{ + ParentRevision: []byte(oldrev.Revision()), + ChildRevision: []byte(newrev), + }, + }, + }) + + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } + } + + if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, newrev, oldrev); err != nil { + var customHookErr updateref.CustomHookError + + if errors.As(err, &customHookErr) { + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(errors.New("access check failed")), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: strings.TrimSuffix(customHookErr.Error(), "\n"), + }, + }, + }) + + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } + + if errors.As(err, &customHookErr) { + return &gitalypb.UserCherryPickResponse{ + PreReceiveError: customHookErr.Error(), + }, nil + } + + return nil, fmt.Errorf("update reference with hooks: %w", err) + } + + return &gitalypb.UserCherryPickResponse{ + BranchUpdate: &gitalypb.OperationBranchUpdate{ + CommitId: newrev.String(), + BranchCreated: branchCreated, + RepoCreated: !repoHadBranches, + }, + }, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick_test.go index deb3a07069..6fad1115f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/cherry_pick_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/cherry_pick_test.go @@ -1,18 +1,24 @@ +//go:build !gitaly_test_sha256 + package operations import ( + "errors" "fmt" "path/filepath" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -340,9 +346,8 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) { func TestServer_UserCherryPick_failedWithPreReceiveError(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -367,17 +372,27 @@ func TestServer_UserCherryPick_failedWithPreReceiveError(t *testing.T) { gittest.WriteCustomHook(t, repoPath, hookName, hookContent) response, err := client.UserCherryPick(ctx, request) - require.NoError(t, err) - require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) + require.Nil(t, response) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPrecondition( + errors.New("access check failed"), + ), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: "GL_ID=user-123", + }, + }, + }, + ), err) }) } } func TestServer_UserCherryPick_failedWithCreateTreeError(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -397,16 +412,21 @@ func TestServer_UserCherryPick_failedWithCreateTreeError(t *testing.T) { } response, err := client.UserCherryPick(ctx, request) - require.NoError(t, err) - require.NotEmpty(t, response.CreateTreeError) - require.Equal(t, gitalypb.UserCherryPickResponse_EMPTY, response.CreateTreeErrorCode) + require.Nil(t, response) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPrecondition( + errors.New("cherry-pick: could not apply because the result was empty"), + ), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, + }, + ), err) } func TestServer_UserCherryPick_failedWithCommitError(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -428,15 +448,24 @@ func TestServer_UserCherryPick_failedWithCommitError(t *testing.T) { } response, err := client.UserCherryPick(ctx, request) - require.NoError(t, err) - require.Equal(t, "Branch diverged", response.CommitError) + require.Nil(t, response) + s, ok := status.FromError(err) + require.True(t, ok) + + details := s.Details() + require.Len(t, details, 1) + detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) + require.True(t, ok) + + targetBranchDivergedErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_TargetBranchDiverged) + require.True(t, ok) + assert.Equal(t, []byte("8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"), targetBranchDivergedErr.TargetBranchDiverged.ParentRevision) } -func TestServer_UserCherryPick_failedWithConflict(t *testing.T) { +func TestServerUserCherryPickRailedWithConflict(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -456,9 +485,19 @@ func TestServer_UserCherryPick_failedWithConflict(t *testing.T) { } response, err := client.UserCherryPick(ctx, request) - require.NoError(t, err) - require.NotEmpty(t, response.CreateTreeError) - require.Equal(t, gitalypb.UserCherryPickResponse_CONFLICT, response.CreateTreeErrorCode) + require.Nil(t, response) + s, ok := status.FromError(err) + require.True(t, ok) + + details := s.Details() + require.Len(t, details, 1) + detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) + require.True(t, ok) + + conflictErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_CherryPickConflict) + require.True(t, ok) + require.Len(t, conflictErr.CherryPickConflict.ConflictingFiles, 1) + assert.Equal(t, []byte("NEW_FILE.md"), conflictErr.CherryPickConflict.ConflictingFiles[0]) } func TestServer_UserCherryPick_successfulWithGivenCommits(t *testing.T) { @@ -518,9 +557,8 @@ func TestServer_UserCherryPick_successfulWithGivenCommits(t *testing.T) { func TestServer_UserCherryPick_quarantine(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Set up a hook that parses the new object and then aborts the update. Like this, we can @@ -545,11 +583,12 @@ func TestServer_UserCherryPick_quarantine(t *testing.T) { } response, err := client.UserCherryPick(ctx, request) - require.NoError(t, err) - require.NotNil(t, response) + require.Nil(t, response) + require.NotNil(t, err) + assert.Contains(t, err.Error(), "access check failed") hookOutput := testhelper.MustReadFile(t, outputPath) - oid, err := git.NewObjectIDFromHex(text.ChompBytes(hookOutput)) + oid, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(hookOutput)) require.NoError(t, err) exists, err := repo.HasRevision(ctx, oid.Revision()+"^{commit}") require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files.go index 6b4f4539d5..0637ee0215 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files.go @@ -11,14 +11,14 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -60,9 +60,9 @@ func (s *Server) UserCommitFiles(stream gitalypb.OperationService_UserCommitFile } var ( - response gitalypb.UserCommitFilesResponse - indexError git2go.IndexError - hookError updateref.HookError + response gitalypb.UserCommitFilesResponse + indexError git2go.IndexError + customHookErr updateref.CustomHookError ) switch { @@ -74,8 +74,8 @@ func (s *Server) UserCommitFiles(stream gitalypb.OperationService_UserCommitFile response = gitalypb.UserCommitFilesResponse{IndexError: "A file with this name already exists"} case errors.As(err, new(git2go.FileNotFoundError)): response = gitalypb.UserCommitFilesResponse{IndexError: "A file with this name doesn't exist"} - case errors.As(err, &hookError): - response = gitalypb.UserCommitFilesResponse{PreReceiveError: hookError.Error()} + case errors.As(err, &customHookErr): + response = gitalypb.UserCommitFilesResponse{PreReceiveError: customHookErr.Error()} case errors.As(err, new(git2go.InvalidArgumentError)): return helper.ErrInvalidArgument(err) default: @@ -161,7 +161,7 @@ func (s *Server) userCommitFiles(ctx context.Context, header *gitalypb.UserCommi return fmt.Errorf("resolve parent commit: %w", err) } } else { - parentCommitOID, err = git.NewObjectIDFromHex(header.StartSha) + parentCommitOID, err = git.ObjectHashSHA1.FromHex(header.StartSha) if err != nil { return helper.ErrInvalidArgumentf("cannot resolve parent commit: %w", err) } @@ -291,7 +291,7 @@ func (s *Server) userCommitFiles(ctx context.Context, header *gitalypb.UserCommi author = git2go.NewSignature(string(header.CommitAuthorName), string(header.CommitAuthorEmail), now) } - commitID, err := s.git2goExecutor.Commit(ctx, quarantineRepo, git2go.CommitParams{ + commitID, err := s.git2goExecutor.Commit(ctx, quarantineRepo, git2go.CommitCommand{ Repository: repoPath, Author: author, Committer: committer, @@ -310,7 +310,7 @@ func (s *Server) userCommitFiles(ctx context.Context, header *gitalypb.UserCommi oldRevision := parentCommitOID if targetBranchCommit == "" { - oldRevision = git.ZeroOID + oldRevision = git.ObjectHashSHA1.ZeroOID } else if header.Force { oldRevision = targetBranchCommit } @@ -326,7 +326,7 @@ func (s *Server) userCommitFiles(ctx context.Context, header *gitalypb.UserCommi return stream.SendAndClose(&gitalypb.UserCommitFilesResponse{BranchUpdate: &gitalypb.OperationBranchUpdate{ CommitId: commitID.String(), RepoCreated: !hasBranches, - BranchCreated: oldRevision.IsZeroOID(), + BranchCreated: git.ObjectHashSHA1.IsZeroOID(oldRevision), }}) } @@ -434,7 +434,7 @@ func validateUserCommitFilesHeader(header *gitalypb.UserCommitFilesRequestHeader startSha := header.GetStartSha() if len(startSha) > 0 { - err := git.ValidateObjectID(startSha) + err := git.ObjectHashSHA1.ValidateHex(startSha) if err != nil { return err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files_test.go index 6b788e214a..1c23a7646f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/commit_files_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/commit_files_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -10,13 +12,13 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" @@ -1014,7 +1016,7 @@ func TestUserCommitFilesQuarantine(t *testing.T) { require.NoError(t, err) hookOutput := testhelper.MustReadFile(t, outputPath) - oid, err := git.NewObjectIDFromHex(text.ChompBytes(hookOutput)) + oid, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(hookOutput)) require.NoError(t, err) exists, err := repo.HasRevision(ctx, oid.Revision()+"^{commit}") require.NoError(t, err) @@ -1291,7 +1293,7 @@ func testSuccessfulUserCommitFilesRemoteRepositoryRequest(setHeader func(header repo := localrepo.NewTestRepo(t, cfg, repoProto) - newRepoProto, _ := gittest.InitRepo(t, cfg, cfg.Storages[0]) + newRepoProto, _ := gittest.CreateRepository(ctx, t, cfg) newRepo := localrepo.NewTestRepo(t, cfg, newRepoProto) targetBranchName := "new" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge.go index c193fa6d68..8886340c79 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge.go @@ -8,12 +8,12 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func validateMergeBranchRequest(request *gitalypb.UserMergeBranchRequest) error { @@ -21,6 +21,14 @@ func validateMergeBranchRequest(request *gitalypb.UserMergeBranchRequest) error return fmt.Errorf("empty user") } + if len(request.User.Email) == 0 { + return fmt.Errorf("empty user email") + } + + if len(request.User.Name) == 0 { + return fmt.Errorf("empty user name") + } + if len(request.Branch) == 0 { return fmt.Errorf("empty branch name") } @@ -36,7 +44,7 @@ func validateMergeBranchRequest(request *gitalypb.UserMergeBranchRequest) error return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranchServer) error { ctx := stream.Context() @@ -85,14 +93,38 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc return helper.ErrInvalidArgument(err) } - if strings.Contains(err.Error(), "could not auto-merge due to conflicts") || errors.As(err, &git2go.ConflictingFilesError{}) { - return helper.ErrFailedPreconditionf("Failed to merge for source_sha %s into target_sha %s", - firstRequest.CommitId, revision.String()) + var conflictErr git2go.ConflictingFilesError + if errors.As(err, &conflictErr) { + conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) + for _, conflictingFile := range conflictErr.ConflictingFiles { + conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) + } + + detailedErr, err := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("merging commits: %w", err), + &gitalypb.UserMergeBranchError{ + Error: &gitalypb.UserMergeBranchError_MergeConflict{ + MergeConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: conflictingFiles, + ConflictingCommitIds: []string{ + revision.String(), + firstRequest.CommitId, + }, + }, + }, + }, + ) + if err != nil { + return helper.ErrInternalf("error details: %w", err) + } + + return detailedErr } + return helper.ErrInternal(err) } - mergeOID, err := git.NewObjectIDFromHex(merge.CommitID) + mergeOID, err := git.ObjectHashSHA1.FromHex(merge.CommitID) if err != nil { return helper.ErrInternalf("could not parse merge ID: %w", err) } @@ -113,6 +145,7 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc if err := s.updateReferenceWithHooks(ctx, firstRequest.GetRepository(), firstRequest.User, quarantineDir, referenceName, mergeOID, revision); err != nil { var notAllowedError hook.NotAllowedError + var customHookErr updateref.CustomHookError var updateRefError updateref.Error if errors.As(err, ¬AllowedError) { @@ -133,6 +166,23 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc return helper.ErrInternalf("error details: %w", err) } + return detailedErr + } else if errors.As(err, &customHookErr) { + // When an error happens updating the reference, e.g. because of a + // race with another update, then we should tell the user that a + // precondition failed. A retry may fix this. + detailedErr, err := helper.ErrWithDetails( + helper.ErrPermissionDenied(customHookErr), + &gitalypb.UserMergeBranchError{ + Error: &gitalypb.UserMergeBranchError_CustomHook{ + CustomHook: customHookErr.Proto(), + }, + }, + ) + if err != nil { + return helper.ErrInternalf("error details: %w", err) + } + return detailedErr } else if errors.As(err, &updateRefError) { // When an error happens updating the reference, e.g. because of a @@ -193,7 +243,7 @@ func validateFFRequest(in *gitalypb.UserFFBranchRequest) error { return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserFFBranch(ctx context.Context, in *gitalypb.UserFFBranchRequest) (*gitalypb.UserFFBranchResponse, error) { if err := validateFFRequest(in); err != nil { return nil, helper.ErrInvalidArgument(err) @@ -214,7 +264,7 @@ func (s *Server) UserFFBranch(ctx context.Context, in *gitalypb.UserFFBranchRequ return nil, helper.ErrInvalidArgument(err) } - commitID, err := git.NewObjectIDFromHex(in.CommitId) + commitID, err := git.ObjectHashSHA1.FromHex(in.CommitId) if err != nil { return nil, helper.ErrInvalidArgumentf("cannot parse commit ID: %w", err) } @@ -228,10 +278,10 @@ func (s *Server) UserFFBranch(ctx context.Context, in *gitalypb.UserFFBranchRequ } if err := s.updateReferenceWithHooks(ctx, in.GetRepository(), in.User, quarantineDir, referenceName, commitID, revision); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + var customHookErr updateref.CustomHookError + if errors.As(err, &customHookErr) { return &gitalypb.UserFFBranchResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErr.Error(), }, nil } @@ -323,14 +373,14 @@ func (s *Server) UserMergeToRef(ctx context.Context, request *gitalypb.UserMerge return nil, helper.ErrFailedPreconditionf("target reference is symbolic: %q", request.TargetRef) } - oid, err := git.NewObjectIDFromHex(targetRef.Target) + oid, err := git.ObjectHashSHA1.FromHex(targetRef.Target) if err != nil { return nil, helper.ErrInternalf("invalid target revision: %v", err) } oldTargetOID = oid } else if errors.Is(err, git.ErrReferenceNotFound) { - oldTargetOID = git.ZeroOID + oldTargetOID = git.ObjectHashSHA1.ZeroOID } else { return nil, helper.ErrInternalf("could not read target reference: %v", err) } @@ -362,7 +412,7 @@ func (s *Server) UserMergeToRef(ctx context.Context, request *gitalypb.UserMerge sourceOID, oid, string(request.TargetRef)) } - mergeOID, err := git.NewObjectIDFromHex(merge.CommitID) + mergeOID, err := git.ObjectHashSHA1.FromHex(merge.CommitID) if err != nil { return nil, err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge_test.go index db133eeb3b..7e7ab424bc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/merge_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/merge_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -12,20 +14,20 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -118,6 +120,108 @@ func TestUserMergeBranch_successful(t *testing.T) { } } +func TestUserMergeBranch_failure(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) + + _ = localrepo.NewTestRepo(t, cfg, repoProto) + + testCases := []struct { + user *gitalypb.User + repo *gitalypb.Repository + desc string + commitID string + branch []byte + message []byte + expectedErr error + }{ + { + desc: "empty user", + repo: repoProto, + branch: []byte(mergeBranchName), + commitID: commitToMerge, + message: []byte("sample-message"), + expectedErr: helper.ErrInvalidArgumentf("empty user"), + }, + { + desc: "empty user name", + user: &gitalypb.User{ + GlId: gittest.TestUser.GlId, + GlUsername: gittest.TestUser.GlUsername, + Email: gittest.TestUser.Email, + Timezone: gittest.TestUser.Timezone, + }, + repo: repoProto, + branch: []byte(mergeBranchName), + commitID: commitToMerge, + message: []byte("sample-message"), + expectedErr: helper.ErrInvalidArgumentf("empty user name"), + }, + { + desc: "empty user email", + user: &gitalypb.User{ + GlId: gittest.TestUser.GlId, + Name: gittest.TestUser.Name, + GlUsername: gittest.TestUser.GlUsername, + Timezone: gittest.TestUser.Timezone, + }, + repo: repoProto, + branch: []byte(mergeBranchName), + commitID: commitToMerge, + message: []byte("sample-message"), + expectedErr: helper.ErrInvalidArgumentf("empty user email"), + }, + { + desc: "empty commit", + repo: repoProto, + user: gittest.TestUser, + branch: []byte(mergeBranchName), + message: []byte("sample-message"), + expectedErr: helper.ErrInvalidArgumentf("empty commit ID"), + }, + { + desc: "empty branch", + repo: repoProto, + user: gittest.TestUser, + commitID: commitToMerge, + message: []byte("sample-message"), + expectedErr: helper.ErrInvalidArgumentf("empty branch name"), + }, + { + desc: "empty message", + repo: repoProto, + user: gittest.TestUser, + branch: []byte(mergeBranchName), + commitID: commitToMerge, + expectedErr: helper.ErrInvalidArgumentf("empty message"), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + request := &gitalypb.UserMergeBranchRequest{ + Repository: testCase.repo, + User: testCase.user, + Branch: testCase.branch, + CommitId: testCase.commitID, + Message: testCase.message, + } + + mergeBidi, err := client.UserMergeBranch(ctx) + require.NoError(t, err) + + require.NoError(t, mergeBidi.Send(request), "apply merge") + _, err = mergeBidi.Recv() + + testhelper.RequireGrpcError(t, testCase.expectedErr, err) + }) + } +} + func TestUserMergeBranch_quarantine(t *testing.T) { t.Parallel() @@ -131,7 +235,8 @@ func TestUserMergeBranch_quarantine(t *testing.T) { gittest.WriteCustomHook(t, repoPath, "pre-receive", []byte( `#!/bin/sh read oldval newval ref && - git rev-parse $newval^{commit} && + git rev-parse $newval^{commit} >&2 && + git rev-parse $oldval^{commit} && exit 1 `)) @@ -153,10 +258,21 @@ func TestUserMergeBranch_quarantine(t *testing.T) { require.NoError(t, stream.Send(&gitalypb.UserMergeBranchRequest{Apply: true}), "apply merge") secondResponse, err := stream.Recv() - testhelper.RequireGrpcError(t, helper.ErrInternalf("%s\n", firstResponse.CommitId), err) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("%s\n", firstResponse.CommitId), + &gitalypb.UserMergeBranchError{ + Error: &gitalypb.UserMergeBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + Stdout: []byte(fmt.Sprintf("%s\n", mergeBranchHeadBefore)), + Stderr: []byte(fmt.Sprintf("%s\n", firstResponse.CommitId)), + }, + }, + }, + ), err) require.Nil(t, secondResponse) - oid, err := git.NewObjectIDFromHex(strings.TrimSpace(firstResponse.CommitId)) + oid, err := git.ObjectHashSHA1.FromHex(strings.TrimSpace(firstResponse.CommitId)) require.NoError(t, err) exists, err := repo.HasRevision(ctx, oid.Revision()+"^{commit}") require.NoError(t, err) @@ -379,7 +495,7 @@ func TestUserMergeBranch_ambiguousReference(t *testing.T) { "refs/tags/heads/" + mergeBranchName, "refs/tags/refs/heads/" + mergeBranchName, } { - require.NoError(t, repo.UpdateRef(ctx, git.ReferenceName(reference), masterOID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, git.ReferenceName(reference), masterOID, git.ObjectHashSHA1.ZeroOID)) } mergeCommitMessage := "Merged by Gitaly" @@ -423,11 +539,33 @@ func TestUserMergeBranch_failingHooks(t *testing.T) { gittest.Exec(t, cfg, "-C", repoPath, "branch", mergeBranchName, mergeBranchHeadBefore) - hookContent := []byte("#!/bin/sh\necho 'failure'\nexit 1") + hookContent := []byte("#!/bin/sh\necho 'stdout' && echo 'stderr' >&2\nexit 1") - for _, hookName := range gitlabPreHooks { - t.Run(hookName, func(t *testing.T) { - gittest.WriteCustomHook(t, repoPath, hookName, hookContent) + for _, tc := range []struct { + hookName string + hookType gitalypb.CustomHookError_HookType + shouldFail bool + }{ + { + hookName: "pre-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + shouldFail: true, + }, + { + hookName: "update", + hookType: gitalypb.CustomHookError_HOOK_TYPE_UPDATE, + shouldFail: true, + }, + { + hookName: "post-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_POSTRECEIVE, + // The post-receive hook runs after references have been updated and any + // failures of it are ignored. + shouldFail: false, + }, + } { + t.Run(tc.hookName, func(t *testing.T) { + gittest.WriteCustomHook(t, repoPath, tc.hookName, hookContent) mergeBidi, err := client.UserMergeBranch(ctx) require.NoError(t, err) @@ -443,18 +581,42 @@ func TestUserMergeBranch_failingHooks(t *testing.T) { require.NoError(t, mergeBidi.Send(firstRequest), "send first request") - _, err = mergeBidi.Recv() + firstResponse, err := mergeBidi.Recv() require.NoError(t, err, "receive first response") require.NoError(t, mergeBidi.Send(&gitalypb.UserMergeBranchRequest{Apply: true}), "apply merge") require.NoError(t, mergeBidi.CloseSend(), "close send") secondResponse, err := mergeBidi.Recv() - testhelper.RequireGrpcError(t, helper.ErrInternalf("failure\n"), err) - require.Nil(t, secondResponse) + if tc.shouldFail { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("stderr\n"), + &gitalypb.UserMergeBranchError{ + Error: &gitalypb.UserMergeBranchError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: tc.hookType, + Stdout: []byte("stdout\n"), + Stderr: []byte("stderr\n"), + }, + }, + }, + ), err) + require.Nil(t, secondResponse) + } else { + testhelper.ProtoEqual(t, &gitalypb.UserMergeBranchResponse{ + BranchUpdate: &gitalypb.OperationBranchUpdate{ + CommitId: firstResponse.CommitId, + }, + }, secondResponse) + require.NoError(t, err) + } currentBranchHead := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", mergeBranchName) - require.Equal(t, mergeBranchHeadBefore, text.ChompBytes(currentBranchHead), "branch head updated") + if !tc.shouldFail { + require.Equal(t, firstResponse.CommitId, text.ChompBytes(currentBranchHead), "branch head updated") + } else { + require.Equal(t, mergeBranchHeadBefore, text.ChompBytes(currentBranchHead), "branch head updated") + } }) } } @@ -496,7 +658,22 @@ func TestUserMergeBranch_conflict(t *testing.T) { }), "send first request") firstResponse, err := mergeBidi.Recv() - testhelper.RequireGrpcError(t, helper.ErrFailedPreconditionf("Failed to merge for source_sha %s into target_sha %s", divergedFrom, divergedInto), err) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPreconditionf("merging commits: merge: there are conflicting files"), + &gitalypb.UserMergeBranchError{ + Error: &gitalypb.UserMergeBranchError_MergeConflict{ + MergeConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: [][]byte{ + []byte(conflictingFile), + }, + ConflictingCommitIds: []string{ + divergedInto.String(), + divergedFrom.String(), + }, + }, + }, + }, + ), err) require.Nil(t, firstResponse) } @@ -508,13 +685,12 @@ func TestUserMergeBranch_allowed(t *testing.T) { mergeBranchHeadAfter := "ff0ac4dfa30d6b26fd14aa83a75650355270bf76" for _, tc := range []struct { - desc string - allowed bool - allowedMessage string - allowedErr error - expectedErr error - expectedResponse *gitalypb.UserMergeBranchResponse - expectedResponseWithoutFF *gitalypb.UserMergeBranchResponse + desc string + allowed bool + allowedMessage string + allowedErr error + expectedErr error + expectedResponse *gitalypb.UserMergeBranchResponse }{ { desc: "allowed", @@ -524,11 +700,6 @@ func TestUserMergeBranch_allowed(t *testing.T) { CommitId: mergeBranchHeadAfter, }, }, - expectedResponseWithoutFF: &gitalypb.UserMergeBranchResponse{ - BranchUpdate: &gitalypb.OperationBranchUpdate{ - CommitId: mergeBranchHeadAfter, - }, - }, }, { desc: "disallowed", @@ -547,9 +718,6 @@ func TestUserMergeBranch_allowed(t *testing.T) { }, }, ), - expectedResponseWithoutFF: &gitalypb.UserMergeBranchResponse{ - PreReceiveError: "GitLab: you shall not pass", - }, }, { desc: "failing", @@ -567,9 +735,6 @@ func TestUserMergeBranch_allowed(t *testing.T) { }, }, ), - expectedResponseWithoutFF: &gitalypb.UserMergeBranchResponse{ - PreReceiveError: "GitLab: failure", - }, }, } { t.Run(tc.desc, func(t *testing.T) { @@ -1052,8 +1217,8 @@ func TestUserMergeToRef_conflicts(t *testing.T) { }) } -func buildUserMergeToRefRequest(t testing.TB, cfg config.Cfg, repo *gitalypb.Repository, repoPath string, sourceSha string, targetSha string, mergeBranchName string) *gitalypb.UserMergeToRefRequest { - gittest.Exec(t, cfg, "-C", repoPath, "branch", mergeBranchName, targetSha) +func buildUserMergeToRefRequest(tb testing.TB, cfg config.Cfg, repo *gitalypb.Repository, repoPath string, sourceSha string, targetSha string, mergeBranchName string) *gitalypb.UserMergeToRefRequest { + gittest.Exec(tb, cfg, "-C", repoPath, "branch", mergeBranchName, targetSha) return &gitalypb.UserMergeToRefRequest{ Repository: repo, @@ -1237,10 +1402,8 @@ func TestUserMergeToRef_ignoreHooksRequest(t *testing.T) { t.Run(hookName, func(t *testing.T) { gittest.WriteCustomHook(t, repoPath, hookName, hookContent) - resp, err := client.UserMergeToRef(ctx, request) + _, err := client.UserMergeToRef(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, resp.PreReceiveError) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase.go index e23a18fe9a..b1bbc7448c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase.go @@ -5,17 +5,16 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserRebaseConfirmable(stream gitalypb.OperationService_UserRebaseConfirmableServer) error { firstRequest, err := stream.Recv() if err != nil { @@ -44,7 +43,7 @@ func (s *Server) UserRebaseConfirmable(stream gitalypb.OperationService_UserReba } branch := git.NewReferenceNameFromBranchName(string(header.Branch)) - oldrev, err := git.NewObjectIDFromHex(header.BranchSha) + oldrev, err := git.ObjectHashSHA1.FromHex(header.BranchSha) if err != nil { return helper.ErrNotFound(err) } @@ -68,37 +67,35 @@ func (s *Server) UserRebaseConfirmable(stream gitalypb.OperationService_UserReba SkipEmptyCommits: true, }) if err != nil { - if featureflag.UserRebaseConfirmableImprovedErrorHandling.IsEnabled(ctx) { - var conflictErr git2go.ConflictingFilesError - if errors.As(err, &conflictErr) { - conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) - for _, conflictingFile := range conflictErr.ConflictingFiles { - conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) - } + var conflictErr git2go.ConflictingFilesError + if errors.As(err, &conflictErr) { + conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) + for _, conflictingFile := range conflictErr.ConflictingFiles { + conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) + } - detailedErr, err := helper.ErrWithDetails( - helper.ErrFailedPreconditionf("rebasing commits: %w", err), - &gitalypb.UserRebaseConfirmableError{ - Error: &gitalypb.UserRebaseConfirmableError_RebaseConflict{ - RebaseConflict: &gitalypb.MergeConflictError{ - ConflictingFiles: conflictingFiles, + detailedErr, err := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("rebasing commits: %w", err), + &gitalypb.UserRebaseConfirmableError{ + Error: &gitalypb.UserRebaseConfirmableError_RebaseConflict{ + RebaseConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: conflictingFiles, + ConflictingCommitIds: []string{ + startRevision.String(), + oldrev.String(), }, }, }, - ) - if err != nil { - return helper.ErrInternalf("error details: %w", err) - } - - return detailedErr + }, + ) + if err != nil { + return helper.ErrInternalf("error details: %w", err) } - return helper.ErrInternalf("rebasing commits: %w", err) + return detailedErr } - return stream.Send(&gitalypb.UserRebaseConfirmableResponse{ - GitError: err.Error(), - }) + return helper.ErrInternalf("rebasing commits: %w", err) } if err := stream.Send(&gitalypb.UserRebaseConfirmableResponse{ @@ -126,28 +123,25 @@ func (s *Server) UserRebaseConfirmable(stream gitalypb.OperationService_UserReba branch, newrev, oldrev, - header.GitPushOptions...); err != nil { + header.GitPushOptions..., + ); err != nil { + var customHookErr updateref.CustomHookError switch { - case errors.As(err, &updateref.HookError{}): - if featureflag.UserRebaseConfirmableImprovedErrorHandling.IsEnabled(ctx) { - detailedErr, err := helper.ErrWithDetails( - helper.ErrPermissionDeniedf("access check: %q", err), - &gitalypb.UserRebaseConfirmableError{ - Error: &gitalypb.UserRebaseConfirmableError_AccessCheck{ - AccessCheck: &gitalypb.AccessCheckError{ - ErrorMessage: err.Error(), - }, + case errors.As(err, &customHookErr): + detailedErr, err := helper.ErrWithDetails( + helper.ErrPermissionDeniedf("access check: %q", err), + &gitalypb.UserRebaseConfirmableError{ + Error: &gitalypb.UserRebaseConfirmableError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: customHookErr.Error(), }, }, - ) - if err != nil { - return helper.ErrInternalf("error details: %w", err) - } - return detailedErr + }, + ) + if err != nil { + return helper.ErrInternalf("error details: %w", err) } - return stream.Send(&gitalypb.UserRebaseConfirmableResponse{ - PreReceiveError: err.Error(), - }) + return detailedErr case errors.Is(err, git2go.ErrInvalidArgument): return fmt.Errorf("update ref: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase_test.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase_test.go index a43f084f30..d8e216d94d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/rebase_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/rebase_test.go @@ -1,28 +1,25 @@ +//go:build !gitaly_test_sha256 + package operations import ( - "context" "errors" "fmt" "io" - "path/filepath" - "strings" "testing" "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -30,8 +27,9 @@ import ( var rebaseBranchName = "many_files" -func TestSuccessfulUserRebaseConfirmableRequest(t *testing.T) { +func TestUserRebaseConfirmable_successful(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) @@ -45,7 +43,7 @@ func TestSuccessfulUserRebaseConfirmableRequest(t *testing.T) { Seed: gittest.SeedGitLabTest, }) - branchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + branchOID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) @@ -53,7 +51,7 @@ func TestSuccessfulUserRebaseConfirmableRequest(t *testing.T) { preReceiveHookOutputPath := gittest.WriteEnvToCustomHook(t, repoPath, "pre-receive") postReceiveHookOutputPath := gittest.WriteEnvToCustomHook(t, repoPath, "post-receive") - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchSha, repoCopyProto, "master") + headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchOID, repoCopyProto, "master") headerRequest.GetHeader().GitPushOptions = pushOptions require.NoError(t, rebaseStream.Send(headerRequest), "send header") @@ -75,10 +73,10 @@ func TestSuccessfulUserRebaseConfirmableRequest(t *testing.T) { _, err = repo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) require.NoError(t, err) - newBranchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + newBranchCommit := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) - require.NotEqual(t, newBranchSha, branchSha) - require.Equal(t, newBranchSha, firstResponse.GetRebaseSha()) + require.NotEqual(t, newBranchCommit, branchOID) + require.Equal(t, newBranchCommit.String(), firstResponse.GetRebaseSha()) require.True(t, secondResponse.GetRebaseApplied(), "the second rebase is applied") @@ -99,7 +97,6 @@ func TestUserRebaseConfirmable_skipEmptyCommits(t *testing.T) { // This is the base commit from which both "theirs" and "ours" branch from". baseCommit := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithParents(), gittest.WithTreeEntries( gittest.TreeEntry{Mode: "100644", Path: "README", Content: "a\nb\nc\nd\ne\nf\n"}, ), @@ -176,12 +173,7 @@ func TestUserRebaseConfirmable_skipEmptyCommits(t *testing.T) { Id: "ef7f98be1f753f1a9fa895d999a855611d691629", ParentIds: []string{theirs.String()}, TreeId: "b68aeb18813d7f2e180f2cc0bccc128511438b29", - Author: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Author: gittest.DefaultCommitAuthor, Committer: &gitalypb.CommitAuthor{ Name: gittest.TestUser.Name, Email: gittest.TestUser.Email, @@ -191,7 +183,7 @@ func TestUserRebaseConfirmable_skipEmptyCommits(t *testing.T) { }, rebaseCommit) } -func TestUserRebaseConfirmableTransaction(t *testing.T) { +func TestUserRebaseConfirmable_transaction(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -215,7 +207,7 @@ func TestUserRebaseConfirmableTransaction(t *testing.T) { expectPreReceiveHook bool }{ { - desc: "non-transactonal does not vote but executes hook", + desc: "non-transactional does not vote but executes hook", expectedVotes: 0, expectPreReceiveHook: true, }, @@ -249,13 +241,13 @@ func TestUserRebaseConfirmableTransaction(t *testing.T) { ctx = metadata.IncomingToOutgoing(ctx) } - branchSha, err := repo.ResolveRevision(ctx, git.Revision(rebaseBranchName)) + branchCommitID, err := repo.ResolveRevision(ctx, git.Revision(rebaseBranchName)) require.NoError(t, err) rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchSha.String(), repoProto, "master") + headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repoProto, "master") require.NoError(t, rebaseStream.Send(headerRequest)) _, err = rebaseStream.Recv() require.NoError(t, err) @@ -279,7 +271,7 @@ func TestUserRebaseConfirmableTransaction(t *testing.T) { } } -func TestUserRebaseConfirmableStableCommitIDs(t *testing.T) { +func TestUserRebaseConfirmable_stableCommitIDs(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -292,7 +284,7 @@ func TestUserRebaseConfirmableStableCommitIDs(t *testing.T) { require.NoError(t, err) committerDate := ×tamppb.Timestamp{Seconds: 100000000} - parentSha := getBranchSha(t, cfg, repoPath, "master") + parentSha := gittest.ResolveRevision(t, cfg, repoPath, "master") require.NoError(t, rebaseStream.Send(&gitalypb.UserRebaseConfirmableRequest{ UserRebaseConfirmableRequestPayload: &gitalypb.UserRebaseConfirmableRequest_Header_{ @@ -301,7 +293,7 @@ func TestUserRebaseConfirmableStableCommitIDs(t *testing.T) { User: gittest.TestUser, RebaseId: "1", Branch: []byte(rebaseBranchName), - BranchSha: getBranchSha(t, cfg, repoPath, rebaseBranchName), + BranchSha: gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName).String(), RemoteRepository: repoProto, RemoteBranch: []byte("master"), Timestamp: committerDate, @@ -330,7 +322,7 @@ func TestUserRebaseConfirmableStableCommitIDs(t *testing.T) { Body: []byte("Add a directory with many files to allow testing of default 1,000 entry limit\n\nFor performance reasons, GitLab will add a file viewer limit and only show\nthe first 1,000 entries in a directory. Having this directory with many\nempty files in the test project will make the test easy.\n"), BodySize: 283, Id: "c52b98024db0d3af0ccb20ed2a3a93a21cfbba87", - ParentIds: []string{parentSha}, + ParentIds: []string{parentSha.String()}, TreeId: "d0305132f880aa0ab4102e56a09cf1343ba34893", Author: &gitalypb.CommitAuthor{ Name: []byte("Drew Blessing"), @@ -349,15 +341,17 @@ func TestUserRebaseConfirmableStableCommitIDs(t *testing.T) { }, commit) } -func TestFailedRebaseUserRebaseConfirmableRequestDueToInvalidHeader(t *testing.T) { +func TestUserRebaseConfirmable_inputValidation(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) - repoCopy, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repoCopy, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) - branchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + branchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) testCases := []struct { desc string @@ -365,15 +359,15 @@ func TestFailedRebaseUserRebaseConfirmableRequestDueToInvalidHeader(t *testing.T }{ { desc: "empty Repository", - req: buildHeaderRequest(nil, gittest.TestUser, "1", rebaseBranchName, branchSha, repoCopy, "master"), + req: buildHeaderRequest(nil, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repoCopy, "master"), }, { desc: "empty User", - req: buildHeaderRequest(repo, nil, "1", rebaseBranchName, branchSha, repoCopy, "master"), + req: buildHeaderRequest(repo, nil, "1", rebaseBranchName, branchCommitID, repoCopy, "master"), }, { desc: "empty Branch", - req: buildHeaderRequest(repo, gittest.TestUser, "1", "", branchSha, repoCopy, "master"), + req: buildHeaderRequest(repo, gittest.TestUser, "1", "", branchCommitID, repoCopy, "master"), }, { desc: "empty BranchSha", @@ -381,15 +375,15 @@ func TestFailedRebaseUserRebaseConfirmableRequestDueToInvalidHeader(t *testing.T }, { desc: "empty RemoteRepository", - req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchSha, nil, "master"), + req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, nil, "master"), }, { desc: "empty RemoteBranch", - req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchSha, repoCopy, ""), + req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repoCopy, ""), }, { desc: "invalid branch name", - req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchSha, repoCopy, "+dev:master"), + req: buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repoCopy, "+dev:master"), }, } @@ -408,7 +402,7 @@ func TestFailedRebaseUserRebaseConfirmableRequestDueToInvalidHeader(t *testing.T } } -func TestAbortedUserRebaseConfirmable(t *testing.T) { +func TestUserRebaseConfirmable_abortViaClose(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -431,9 +425,9 @@ func TestAbortedUserRebaseConfirmable(t *testing.T) { testRepo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, createRepoOpts) testRepoCopy, _ := gittest.CreateRepository(ctx, t, cfg, createRepoOpts) - branchSha := getBranchSha(t, cfg, testRepoPath, rebaseBranchName) + branchCommitID := gittest.ResolveRevision(t, cfg, testRepoPath, rebaseBranchName) - headerRequest := buildHeaderRequest(testRepo, gittest.TestUser, fmt.Sprintf("%v", i), rebaseBranchName, branchSha, testRepoCopy, "master") + headerRequest := buildHeaderRequest(testRepo, gittest.TestUser, fmt.Sprintf("%v", i), rebaseBranchName, branchCommitID, testRepoCopy, "master") rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) @@ -461,13 +455,13 @@ func TestAbortedUserRebaseConfirmable(t *testing.T) { require.Error(t, err) testhelper.RequireGrpcCode(t, err, tc.code) - newBranchSha := getBranchSha(t, cfg, testRepoPath, rebaseBranchName) - require.Equal(t, newBranchSha, branchSha, "branch should not change when the rebase is aborted") + newBranchCommitID := gittest.ResolveRevision(t, cfg, testRepoPath, rebaseBranchName) + require.Equal(t, newBranchCommitID, branchCommitID, "branch should not change when the rebase is aborted") }) } } -func TestFailedUserRebaseConfirmableDueToApplyBeingFalse(t *testing.T) { +func TestUserRebaseConfirmable_abortViaApply(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -479,12 +473,12 @@ func TestFailedUserRebaseConfirmableDueToApplyBeingFalse(t *testing.T) { Seed: gittest.SeedGitLabTest, }) - branchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + branchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchSha, testRepoCopy, "master") + headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", rebaseBranchName, branchCommitID, testRepoCopy, "master") require.NoError(t, rebaseStream.Send(headerRequest), "send header") firstResponse, err := rebaseStream.Recv() @@ -504,26 +498,22 @@ func TestFailedUserRebaseConfirmableDueToApplyBeingFalse(t *testing.T) { _, err = repo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) require.Equal(t, localrepo.ErrObjectNotFound, err, "commit should have been discarded") - newBranchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) - require.Equal(t, branchSha, newBranchSha, "branch should not change when the rebase is not applied") - require.NotEqual(t, newBranchSha, firstResponse.GetRebaseSha(), "branch should not be the sha returned when the rebase is not applied") + newBranchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) + require.Equal(t, branchCommitID, newBranchCommitID, "branch should not change when the rebase is not applied") + require.NotEqual(t, newBranchCommitID, firstResponse.GetRebaseSha(), "branch should not be the sha returned when the rebase is not applied") } -func TestFailedUserRebaseConfirmableRequestDueToPreReceiveError(t *testing.T) { +func TestUserRebaseConfirmable_preReceiveError(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.UserRebaseConfirmableImprovedErrorHandling). - Run(t, testFailedUserRebaseConfirmableRequestDueToPreReceiveError) -} -func testFailedUserRebaseConfirmableRequestDueToPreReceiveError(t *testing.T, ctx context.Context) { - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) repoCopyProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) - branchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + branchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) hookContent := []byte("#!/bin/sh\necho 'failure'\nexit 1") @@ -534,7 +524,7 @@ func testFailedUserRebaseConfirmableRequestDueToPreReceiveError(t *testing.T, ct rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, fmt.Sprintf("%v", i), rebaseBranchName, branchSha, repoCopyProto, "master") + headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, fmt.Sprintf("%v", i), rebaseBranchName, branchCommitID, repoCopyProto, "master") require.NoError(t, rebaseStream.Send(headerRequest), "send header") firstResponse, err := rebaseStream.Recv() @@ -547,24 +537,18 @@ func testFailedUserRebaseConfirmableRequestDueToPreReceiveError(t *testing.T, ct require.NoError(t, rebaseStream.Send(applyRequest), "apply rebase") secondResponse, err := rebaseStream.Recv() + require.Nil(t, secondResponse) - if featureflag.UserRebaseConfirmableImprovedErrorHandling.IsEnabled(ctx) { - testhelper.RequireGrpcError(t, errWithDetails(t, - helper.ErrPermissionDeniedf(`access check: "failure\n"`), - &gitalypb.UserRebaseConfirmableError{ - Error: &gitalypb.UserRebaseConfirmableError_AccessCheck{ - AccessCheck: &gitalypb.AccessCheckError{ - ErrorMessage: "failure\n", - }, + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf(`access check: "running %s hooks: failure\n"`, hookName), + &gitalypb.UserRebaseConfirmableError{ + Error: &gitalypb.UserRebaseConfirmableError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: "failure\n", }, }, - ), err) - } else { - require.NoError(t, err, "receive second response") - require.Contains(t, secondResponse.PreReceiveError, "failure") - _, err = rebaseStream.Recv() - require.Equal(t, io.EOF, err) - } + }, + ), err) _, err = repo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) if hookName == "pre-receive" { @@ -573,188 +557,197 @@ func testFailedUserRebaseConfirmableRequestDueToPreReceiveError(t *testing.T, ct require.NoError(t, err) } - newBranchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) - require.Equal(t, branchSha, newBranchSha, "branch should not change when the rebase fails due to PreReceiveError") - require.NotEqual(t, newBranchSha, firstResponse.GetRebaseSha(), "branch should not be the sha returned when the rebase fails due to PreReceiveError") + newBranchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) + require.Equal(t, branchCommitID, newBranchCommitID, "branch should not change when the rebase fails due to PreReceiveError") + require.NotEqual(t, newBranchCommitID, firstResponse.GetRebaseSha(), "branch should not be the sha returned when the rebase fails due to PreReceiveError") }) } } func TestUserRebaseConfirmable_gitError(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.UserRebaseConfirmableImprovedErrorHandling). - Run(t, testFailedUserRebaseConfirmableDueToGitError) -} -func testFailedUserRebaseConfirmableDueToGitError(t *testing.T, ctx context.Context) { - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repoCopyProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) - failedBranchName := "rebase-encoding-failure-trigger" - branchSha := getBranchSha(t, cfg, repoPath, failedBranchName) + targetBranch := "rebase-encoding-failure-trigger" + targetBranchCommitID := gittest.ResolveRevision(t, cfg, repoPath, targetBranch) + sourceBranchCommitID := gittest.ResolveRevision(t, cfg, repoPath, "master") rebaseStream, err := client.UserRebaseConfirmable(ctx) require.NoError(t, err) - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", failedBranchName, branchSha, repoCopyProto, "master") + headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", targetBranch, targetBranchCommitID, repoCopyProto, "master") require.NoError(t, rebaseStream.Send(headerRequest), "send header") - firstResponse, err := rebaseStream.Recv() - if featureflag.UserRebaseConfirmableImprovedErrorHandling.IsEnabled(ctx) { - testhelper.RequireGrpcError(t, errWithDetails(t, - helper.ErrFailedPrecondition(errors.New(`rebasing commits: rebase: commit "eb8f5fb9523b868cef583e09d4bf70b99d2dd404": there are conflicting files`)), - &gitalypb.UserRebaseConfirmableError{ - Error: &gitalypb.UserRebaseConfirmableError_RebaseConflict{ - RebaseConflict: &gitalypb.MergeConflictError{ - ConflictingFiles: [][]byte{[]byte("README.md")}, + response, err := rebaseStream.Recv() + require.Nil(t, response) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPrecondition(errors.New(`rebasing commits: rebase: commit "eb8f5fb9523b868cef583e09d4bf70b99d2dd404": there are conflicting files`)), + &gitalypb.UserRebaseConfirmableError{ + Error: &gitalypb.UserRebaseConfirmableError_RebaseConflict{ + RebaseConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: [][]byte{ + []byte("README.md"), + }, + ConflictingCommitIds: []string{ + sourceBranchCommitID.String(), + targetBranchCommitID.String(), }, }, }, - ), err) - } else { - require.NoError(t, err, "receive first response") - require.Contains(t, firstResponse.GitError, "conflict") + }, + ), err) - _, err = rebaseStream.Recv() - require.Equal(t, io.EOF, err) + newBranchCommitID := gittest.ResolveRevision(t, cfg, repoPath, targetBranch) + require.Equal(t, targetBranchCommitID, newBranchCommitID, "branch should not change when the rebase fails due to GitError") +} + +func TestUserRebaseConfirmable_deletedFileInLocalRepo(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + localRepoProto, localRepoPath := gittest.CreateRepository(ctx, t, cfg) + localRepo := localrepo.NewTestRepo(t, cfg, localRepoProto) + + remoteRepoProto, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg) + + // Write the root commit into both repositories as common history. + var rootCommitID git.ObjectID + for _, path := range []string{localRepoPath, remoteRepoPath} { + rootCommitID = gittest.WriteCommit(t, cfg, path, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "change-me", Mode: "100644", Content: "unchanged contents"}, + gittest.TreeEntry{Path: "delete-me", Mode: "100644", Content: "useless stuff"}, + ), + ) } - newBranchSha := getBranchSha(t, cfg, repoPath, failedBranchName) - require.Equal(t, branchSha, newBranchSha, "branch should not change when the rebase fails due to GitError") -} + // Write a commit into the local repository that deletes a single file. + localCommitID := gittest.WriteCommit(t, cfg, localRepoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "change-me", Mode: "100644", Content: "unchanged contents"}, + ), + gittest.WithBranch("local"), + ) -func getBranchSha(t *testing.T, cfg config.Cfg, repoPath string, branchName string) string { - branchSha := string(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", branchName)) - return strings.TrimSpace(branchSha) -} + // And then finally write a commit into the remote repository that changes a different file. + gittest.WriteCommit(t, cfg, remoteRepoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "change-me", Mode: "100644", Content: "modified contents"}, + gittest.TreeEntry{Path: "delete-me", Mode: "100644", Content: "useless stuff"}, + ), + gittest.WithBranch("remote"), + ) -func TestRebaseRequestWithDeletedFile(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - repoCopyProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - - branch := "rebase-delete-test" - - gittest.Exec(t, cfg, "-C", repoPath, "config", "user.name", string(gittest.TestUser.Name)) - gittest.Exec(t, cfg, "-C", repoPath, "config", "user.email", string(gittest.TestUser.Email)) - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "-b", branch, "master~1") - gittest.Exec(t, cfg, "-C", repoPath, "rm", "README") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-a", "-m", "delete file") - - branchSha := getBranchSha(t, cfg, repoPath, branch) - - rebaseStream, err := client.UserRebaseConfirmable(ctx) + // Send the first request to tell the server to perform the rebase. + stream, err := client.UserRebaseConfirmable(ctx) + require.NoError(t, err) + require.NoError(t, stream.Send(buildHeaderRequest( + localRepoProto, gittest.TestUser, "1", "local", localCommitID, remoteRepoProto, "remote", + ))) + firstResponse, err := stream.Recv() require.NoError(t, err) - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", branch, branchSha, repoCopyProto, "master") - require.NoError(t, rebaseStream.Send(headerRequest), "send header") - - firstResponse, err := rebaseStream.Recv() - require.NoError(t, err, "receive first response") - - _, err = repo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) + _, err = localRepo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) require.Equal(t, localrepo.ErrObjectNotFound, err, "commit should not exist in the normal repo given that it is quarantined") - applyRequest := buildApplyRequest(true) - require.NoError(t, rebaseStream.Send(applyRequest), "apply rebase") + // Send the second request to tell the server to apply the rebase. + require.NoError(t, stream.Send(buildApplyRequest(true))) + secondResponse, err := stream.Recv() + require.NoError(t, err) + require.True(t, secondResponse.GetRebaseApplied()) + _, err = stream.Recv() + require.Equal(t, io.EOF, err) + + newBranchCommitID := gittest.ResolveRevision(t, cfg, localRepoPath, "local") + + _, err = localRepo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) + require.NoError(t, err) + require.NotEqual(t, newBranchCommitID, localCommitID) + require.Equal(t, newBranchCommitID.String(), firstResponse.GetRebaseSha()) +} + +func TestUserRebaseConfirmable_deletedFileInRemoteRepo(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + localRepoProto, localRepoPath := gittest.CreateRepository(ctx, t, cfg) + localRepo := localrepo.NewTestRepo(t, cfg, localRepoProto) + + remoteRepoProto, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg) + + // Write the root commit into both repositories as common history. + var rootCommitID git.ObjectID + for _, path := range []string{localRepoPath, remoteRepoPath} { + rootCommitID = gittest.WriteCommit(t, cfg, path, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "unchanged", Mode: "100644", Content: "unchanged contents"}, + gittest.TreeEntry{Path: "delete-me", Mode: "100644", Content: "useless stuff"}, + ), + gittest.WithBranch("local"), + ) + } + + // Write a commit into the remote repository that deletes a file. + remoteCommitID := gittest.WriteCommit(t, cfg, remoteRepoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "unchanged", Mode: "100644", Content: "unchanged contents"}, + ), + gittest.WithBranch("remote"), + ) + + _, err := localRepo.ReadCommit(ctx, remoteCommitID.Revision()) + require.Equal(t, localrepo.ErrObjectNotFound, err, "remote commit should not yet exist in local repository") + + // Send the first request to tell the server to perform the rebase. + rebaseStream, err := client.UserRebaseConfirmable(ctx) + require.NoError(t, err) + require.NoError(t, rebaseStream.Send(buildHeaderRequest( + localRepoProto, gittest.TestUser, "1", "local", rootCommitID, remoteRepoProto, "remote", + ))) + firstResponse, err := rebaseStream.Recv() + require.NoError(t, err) + + _, err = localRepo.ReadCommit(ctx, remoteCommitID.Revision()) + require.Equal(t, localrepo.ErrObjectNotFound, err, "commit should not exist in the normal repo given that it is quarantined") + + // Send the second request to tell the server to apply the rebase. + require.NoError(t, rebaseStream.Send(buildApplyRequest(true))) secondResponse, err := rebaseStream.Recv() - require.NoError(t, err, "receive second response") + require.NoError(t, err) + require.True(t, secondResponse.GetRebaseApplied(), "the second rebase is applied") _, err = rebaseStream.Recv() require.Equal(t, io.EOF, err) - newBranchSha := getBranchSha(t, cfg, repoPath, branch) - - _, err = repo.ReadCommit(ctx, git.Revision(firstResponse.GetRebaseSha())) - require.NoError(t, err, "look up git commit after rebase is applied") - - require.NotEqual(t, newBranchSha, branchSha) - require.Equal(t, newBranchSha, firstResponse.GetRebaseSha()) - - require.True(t, secondResponse.GetRebaseApplied(), "the second rebase is applied") -} - -func TestRebaseOntoRemoteBranch(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - remoteRepo, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - gittest.AddWorktree(t, cfg, remoteRepoPath, "worktree") - remoteRepoPath = filepath.Join(remoteRepoPath, "worktree") - - localBranch := "master" - localBranchHash := getBranchSha(t, cfg, repoPath, localBranch) - - remoteBranch := "remote-branch" - gittest.Exec(t, cfg, "-C", remoteRepoPath, "config", "user.name", string(gittest.TestUser.Name)) - gittest.Exec(t, cfg, "-C", remoteRepoPath, "config", "user.email", string(gittest.TestUser.Email)) - gittest.Exec(t, cfg, "-C", remoteRepoPath, "checkout", "-b", remoteBranch, "master") - gittest.Exec(t, cfg, "-C", remoteRepoPath, "rm", "README") - gittest.Exec(t, cfg, "-C", remoteRepoPath, "commit", "-a", "-m", "remove README") - remoteBranchHash := getBranchSha(t, cfg, remoteRepoPath, remoteBranch) - - rebaseStream, err := client.UserRebaseConfirmable(ctx) + _, err = localRepo.ReadCommit(ctx, remoteCommitID.Revision()) require.NoError(t, err) - _, err = repo.ReadCommit(ctx, git.Revision(remoteBranchHash)) - require.Equal(t, localrepo.ErrObjectNotFound, err, "remote commit does not yet exist in local repository") - - headerRequest := buildHeaderRequest(repoProto, gittest.TestUser, "1", localBranch, localBranchHash, remoteRepo, remoteBranch) - require.NoError(t, rebaseStream.Send(headerRequest), "send header") - - firstResponse, err := rebaseStream.Recv() - require.NoError(t, err, "receive first response") - - _, err = repo.ReadCommit(ctx, git.Revision(remoteBranchHash)) - require.Equal(t, localrepo.ErrObjectNotFound, err, "commit should not exist in the normal repo given that it is quarantined") - - applyRequest := buildApplyRequest(true) - require.NoError(t, rebaseStream.Send(applyRequest), "apply rebase") - - secondResponse, err := rebaseStream.Recv() - require.NoError(t, err, "receive second response") - - _, err = rebaseStream.Recv() - require.Equal(t, io.EOF, err) - - _, err = repo.ReadCommit(ctx, git.Revision(remoteBranchHash)) - require.NoError(t, err) - - rebasedBranchHash := getBranchSha(t, cfg, repoPath, localBranch) - - require.NotEqual(t, rebasedBranchHash, localBranchHash) - require.Equal(t, rebasedBranchHash, firstResponse.GetRebaseSha()) - - require.True(t, secondResponse.GetRebaseApplied(), "the second rebase is applied") + rebasedBranchCommitID := gittest.ResolveRevision(t, cfg, localRepoPath, "local") + require.NotEqual(t, rebasedBranchCommitID, rootCommitID) + require.Equal(t, rebasedBranchCommitID.String(), firstResponse.GetRebaseSha()) } -func TestRebaseFailedWithCode(t *testing.T) { +func TestUserRebaseConfirmable_failedWithCode(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) - branchSha := getBranchSha(t, cfg, repoPath, rebaseBranchName) + branchCommitID := gittest.ResolveRevision(t, cfg, repoPath, rebaseBranchName) testCases := []struct { desc string @@ -767,7 +760,7 @@ func TestRebaseFailedWithCode(t *testing.T) { repo := proto.Clone(repoProto).(*gitalypb.Repository) repo.StorageName = "@this-storage-does-not-exist" - return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchSha, repo, "master") + return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repo, "master") }, expectedCode: codes.InvalidArgument, }, @@ -777,7 +770,7 @@ func TestRebaseFailedWithCode(t *testing.T) { repo := proto.Clone(repoProto).(*gitalypb.Repository) repo.RelativePath = "" - return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchSha, repo, "master") + return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repo, "master") }, expectedCode: codes.InvalidArgument, }, @@ -817,7 +810,7 @@ func rebaseRecvTimeout(bidi gitalypb.OperationService_UserRebaseConfirmableClien } } -func buildHeaderRequest(repo *gitalypb.Repository, user *gitalypb.User, rebaseID string, branchName string, branchSha string, remoteRepo *gitalypb.Repository, remoteBranch string) *gitalypb.UserRebaseConfirmableRequest { +func buildHeaderRequest(repo *gitalypb.Repository, user *gitalypb.User, rebaseID string, branchName string, commitID git.ObjectID, remoteRepo *gitalypb.Repository, remoteBranch string) *gitalypb.UserRebaseConfirmableRequest { return &gitalypb.UserRebaseConfirmableRequest{ UserRebaseConfirmableRequestPayload: &gitalypb.UserRebaseConfirmableRequest_Header_{ Header: &gitalypb.UserRebaseConfirmableRequest_Header{ @@ -825,7 +818,7 @@ func buildHeaderRequest(repo *gitalypb.Repository, user *gitalypb.User, rebaseID User: user, RebaseId: rebaseID, Branch: []byte(branchName), - BranchSha: branchSha, + BranchSha: commitID.String(), RemoteRepository: remoteRepo, RemoteBranch: []byte(remoteBranch), }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert.go index 9b57b63b2d..22c5c4527c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert.go @@ -5,16 +5,16 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserRevert(ctx context.Context, req *gitalypb.UserRevertRequest) (*gitalypb.UserRevertResponse, error) { if err := validateCherryPickOrRevertRequest(req); err != nil { return nil, helper.ErrInvalidArgument(err) @@ -84,7 +84,7 @@ func (s *Server) UserRevert(ctx context.Context, req *gitalypb.UserRevertRequest oldrev, err := quarantineRepo.ResolveRevision(ctx, referenceName.Revision()+"^{commit}") if errors.Is(err, git.ErrReferenceNotFound) { branchCreated = true - oldrev = git.ZeroOID + oldrev = git.ObjectHashSHA1.ZeroOID } else if err != nil { return nil, helper.ErrInvalidArgumentf("resolve ref: %w", err) } @@ -106,10 +106,10 @@ func (s *Server) UserRevert(ctx context.Context, req *gitalypb.UserRevertRequest } if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, newrev, oldrev); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + var customHookErr updateref.CustomHookError + if errors.As(err, &customHookErr) { return &gitalypb.UserRevertResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErr.Error(), }, nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert_test.go index 22e10efa28..d829d9db95 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/revert_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/revert_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -6,12 +8,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -208,7 +210,7 @@ func TestServer_UserRevert_quarantine(t *testing.T) { require.NotEmpty(t, response.PreReceiveError) hookOutput := testhelper.MustReadFile(t, outputPath) - oid, err := git.NewObjectIDFromHex(text.ChompBytes(hookOutput)) + oid, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(hookOutput)) require.NoError(t, err) exists, err := repo.HasRevision(ctx, oid.Revision()+"^{commit}") require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/server.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/server.go index e8bc6d538f..3ff19f7526 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/server.go @@ -3,22 +3,22 @@ package operations import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type Server struct { gitalypb.UnimplementedOperationServiceServer hookManager hook.Manager diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash.go index 9b3adaba96..7f2bc0881c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash.go @@ -1,18 +1,16 @@ package operations import ( - "bytes" "context" "errors" - "fmt" + "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -72,7 +70,7 @@ func validateUserSquashRequest(req *gitalypb.UserSquashRequest) error { } if len(req.GetAuthor().GetEmail()) == 0 { - return errors.New("empty auithor email") + return errors.New("empty author email") } return nil @@ -137,16 +135,28 @@ func (s *Server) userSquash(ctx context.Context, req *gitalypb.UserSquashRequest return "", helper.ErrInvalidArgument(err) } - // We're now rebasing the end commit on top of the start commit. The resulting tree - // is then going to be the tree of the squashed commit. - rebasedCommitID, err := s.git2goExecutor.Rebase(ctx, quarantineRepo, git2go.RebaseCommand{ - Repository: quarantineRepoPath, - Committer: git2go.NewSignature( - string(req.GetUser().Name), string(req.GetUser().Email), commitDate, - ), - CommitID: endCommit, - UpstreamCommitID: startCommit, - SkipEmptyCommits: true, + message := string(req.GetCommitMessage()) + // In previous implementation, we've used git commit-tree to create commit. + // When message wasn't empty and didn't end in a new line, + // git commit-tree would add a trailing new line to the commit message. + // Let's keep that behaviour for compatibility. + if len(message) > 0 && !strings.HasSuffix(message, "\n") { + message += "\n" + } + + // Perform squash merge onto endCommit using git2go merge. + merge, err := s.git2goExecutor.Merge(ctx, quarantineRepo, git2go.MergeCommand{ + Repository: quarantineRepoPath, + AuthorName: string(req.GetAuthor().GetName()), + AuthorMail: string(req.GetAuthor().GetEmail()), + AuthorDate: commitDate, + CommitterName: string(req.GetUser().Name), + CommitterMail: string(req.GetUser().Email), + CommitterDate: commitDate, + Message: message, + Ours: startCommit.String(), + Theirs: endCommit.String(), + Squash: true, }) if err != nil { var conflictErr git2go.ConflictingFilesError @@ -158,11 +168,17 @@ func (s *Server) userSquash(ctx context.Context, req *gitalypb.UserSquashRequest } detailedErr, err := helper.ErrWithDetails( - helper.ErrFailedPreconditionf("rebasing commits: %w", err), + helper.ErrFailedPreconditionf("squashing commits: %w", err), &gitalypb.UserSquashError{ + // Note: this is actually a merge conflict, but we've kept + // the old "rebase" name for compatibility reasons. Error: &gitalypb.UserSquashError_RebaseConflict{ RebaseConflict: &gitalypb.MergeConflictError{ ConflictingFiles: conflictingFiles, + ConflictingCommitIds: []string{ + startCommit.String(), + endCommit.String(), + }, }, }, }, @@ -173,47 +189,9 @@ func (s *Server) userSquash(ctx context.Context, req *gitalypb.UserSquashRequest return "", detailedErr } - - return "", helper.ErrInternalf("rebasing commits: %w", err) } - treeID, err := quarantineRepo.ResolveRevision(ctx, rebasedCommitID.Revision()+"^{tree}") - if err != nil { - return "", fmt.Errorf("cannot resolve rebased tree: %w", err) - } - - commitEnv := []string{ - "GIT_COMMITTER_NAME=" + string(req.GetUser().Name), - "GIT_COMMITTER_EMAIL=" + string(req.GetUser().Email), - fmt.Sprintf("GIT_COMMITTER_DATE=%d %s", commitDate.Unix(), commitDate.Format("-0700")), - "GIT_AUTHOR_NAME=" + string(req.GetAuthor().Name), - "GIT_AUTHOR_EMAIL=" + string(req.GetAuthor().Email), - fmt.Sprintf("GIT_AUTHOR_DATE=%d %s", commitDate.Unix(), commitDate.Format("-0700")), - } - - flags := []git.Option{ - git.ValueFlag{ - Name: "-m", - Value: string(req.GetCommitMessage()), - }, - git.ValueFlag{ - Name: "-p", - Value: startCommit.String(), - }, - } - - var stdout, stderr bytes.Buffer - if err := quarantineRepo.ExecAndWait(ctx, git.SubCmd{ - Name: "commit-tree", - Flags: flags, - Args: []string{ - treeID.String(), - }, - }, git.WithStdout(&stdout), git.WithStderr(&stderr), git.WithEnv(commitEnv...)); err != nil { - return "", helper.ErrInternalf("creating squashed commit: %w", err) - } - - commitID := text.ChompBytes(stdout.Bytes()) + commitID := merge.CommitID // The RPC is badly designed in that it never updates any references, but only creates the // objects and writes them to disk. We still use a quarantine directory to stage the new diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash_test.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash_test.go index 57cb362fe9..3a418a6b0d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/squash_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/squash_test.go @@ -1,27 +1,28 @@ +//go:build !gitaly_test_sha256 + package operations import ( "context" "fmt" "os" - "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -74,8 +75,6 @@ func TestUserSquash_successful(t *testing.T) { response, err := client.UserSquash(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) commit, err := repo.ReadCommit(ctx, git.Revision(response.SquashSha)) require.NoError(t, err) @@ -213,7 +212,6 @@ func TestUserSquash_stableID(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - ctx, cfg, repoProto, _, client := setupOperationsService(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -228,8 +226,6 @@ func TestUserSquash_stableID(t *testing.T) { Timestamp: ×tamppb.Timestamp{Seconds: 1234512345}, }) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) commit, err := repo.ReadCommit(ctx, git.Revision(response.SquashSha)) require.NoError(t, err) @@ -273,7 +269,6 @@ func TestUserSquash_threeWayMerge(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - ctx, cfg, repoProto, _, client := setupOperationsService(t, ctx) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -290,8 +285,6 @@ func TestUserSquash_threeWayMerge(t *testing.T) { response, err := client.UserSquash(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) commit, err := repo.ReadCommit(ctx, git.Revision(response.SquashSha)) require.NoError(t, err) @@ -322,10 +315,8 @@ func TestUserSquash_splitIndex(t *testing.T) { EndSha: endSha, } - response, err := client.UserSquash(ctx, request) + _, err := client.UserSquash(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) require.False(t, ensureSplitIndexExists(t, cfg, repoPath)) } @@ -333,53 +324,59 @@ func TestUserSquash_renames(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) repo := localrepo.NewTestRepo(t, cfg, repoProto) originalFilename := "original-file.txt" renamedFilename := "renamed-file.txt" - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "-b", "squash-rename-test", "master") - require.NoError(t, os.WriteFile(filepath.Join(repoPath, originalFilename), []byte("This is a test"), 0o644)) - gittest.Exec(t, cfg, "-C", repoPath, "add", ".") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-m", "test file") + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: originalFilename, Mode: "100644", Content: "This is a test"}, + ), + ) - startCommitID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")) + startCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: renamedFilename, Mode: "100644", Content: "This is a test"}, + ), + ) - gittest.Exec(t, cfg, "-C", repoPath, "mv", originalFilename, renamedFilename) - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-a", "-m", "renamed test file") + changedCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(rootCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: originalFilename, Mode: "100644", Content: "This is a change"}, + ), + ) - // Modify the original file in another branch - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "-b", "squash-rename-branch", startCommitID) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, originalFilename), []byte("This is a change"), 0o644)) - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-a", "-m", "test") - - require.NoError(t, os.WriteFile(filepath.Join(repoPath, originalFilename), []byte("This is another change"), 0o644)) - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-a", "-m", "test") - - endCommitID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")) + endCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(changedCommitID), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: originalFilename, Mode: "100644", Content: "This is another change"}, + ), + ) request := &gitalypb.UserSquashRequest{ Repository: repoProto, User: gittest.TestUser, Author: author, CommitMessage: commitMessage, - StartSha: startCommitID, - EndSha: endCommitID, + StartSha: startCommitID.String(), + EndSha: endCommitID.String(), } response, err := client.UserSquash(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) commit, err := repo.ReadCommit(ctx, git.Revision(response.SquashSha)) require.NoError(t, err) - require.Equal(t, []string{startCommitID}, commit.ParentIds) + require.Equal(t, []string{startCommitID.String()}, commit.ParentIds) require.Equal(t, author.Name, commit.Author.Name) require.Equal(t, author.Email, commit.Author.Email) require.Equal(t, gittest.TestUser.Name, commit.Committer.Name) @@ -387,6 +384,10 @@ func TestUserSquash_renames(t *testing.T) { require.Equal(t, gittest.TimezoneOffset, string(commit.Committer.Timezone)) require.Equal(t, gittest.TimezoneOffset, string(commit.Author.Timezone)) require.Equal(t, commitMessage, commit.Subject) + + gittest.RequireTree(t, cfg, repoPath, response.SquashSha, []gittest.TreeEntry{ + {Path: renamedFilename, Mode: "100644", Content: "This is another change", OID: "1b2ae89cca65f0d514f677981f012d708df651fc"}, + }) } func TestUserSquash_missingFileOnTargetBranch(t *testing.T) { @@ -406,10 +407,8 @@ func TestUserSquash_missingFileOnTargetBranch(t *testing.T) { EndSha: endSha, } - response, err := client.UserSquash(ctx, request) + _, err := client.UserSquash(ctx, request) require.NoError(t, err) - //nolint:staticcheck - require.Empty(t, response.GetGitError()) } func TestUserSquash_emptyCommit(t *testing.T) { @@ -420,9 +419,9 @@ func TestUserSquash_emptyCommit(t *testing.T) { repo := localrepo.NewTestRepo(t, cfg, repoProto) // Set up history with two diverging lines of branches, where both sides have implemented - // the same changes. During rebase, the diff will thus become empty. + // the same changes. During merge, the diff will thus become empty. base := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithParents(), gittest.WithTreeEntries( + gittest.WithTreeEntries( gittest.TreeEntry{Path: "a", Content: "base", Mode: "100644"}, ), ) @@ -642,13 +641,19 @@ func TestUserSquash_conflicts(t *testing.T) { }) testhelper.RequireGrpcError(t, errWithDetails(t, - helper.ErrFailedPreconditionf("rebasing commits: rebase: commit %q: there are conflicting files", ours), + helper.ErrFailedPreconditionf( + "squashing commits: merge: there are conflicting files", + ), &gitalypb.UserSquashError{ Error: &gitalypb.UserSquashError_RebaseConflict{ RebaseConflict: &gitalypb.MergeConflictError{ ConflictingFiles: [][]byte{ []byte("b"), }, + ConflictingCommitIds: []string{ + theirs.String(), + ours.String(), + }, }, }, }, @@ -664,7 +669,7 @@ func TestUserSquash_ancestry(t *testing.T) { // We create an empty parent commit and two commits which both branch off from it. As a // result, they are not direct ancestors of each other. - parent := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("p"), gittest.WithTreeEntries(), gittest.WithParents()) + parent := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("p"), gittest.WithTreeEntries()) commit1 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("1"), gittest.WithTreeEntries(gittest.TreeEntry{Path: "a", Mode: "100644", Content: "a-content"}), gittest.WithParents(parent), @@ -768,6 +773,18 @@ func TestUserSquash_gitError(t *testing.T) { }, expectedErr: helper.ErrInvalidArgumentf("UserSquash: empty author name"), }, + { + desc: "author has no email set", + request: &gitalypb.UserSquashRequest{ + Repository: repo, + User: gittest.TestUser, + Author: &gitalypb.User{Name: gittest.TestUser.Name}, + CommitMessage: commitMessage, + StartSha: startSha, + EndSha: endSha, + }, + expectedErr: helper.ErrInvalidArgumentf("UserSquash: empty author email"), + }, } for _, tc := range testCases { @@ -778,3 +795,81 @@ func TestUserSquash_gitError(t *testing.T) { }) } } + +func TestUserSquash_squashingMerge(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("base"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "a", Mode: "100644", Content: "base-content"}), + ) + ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("ours"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "a", Mode: "100644", Content: "ours-content"}), + gittest.WithParents(base), + ) + theirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("theirs"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "a", Mode: "100644", Content: "theirs-content"}), + gittest.WithParents(base), + ) + oursMergedIntoTheirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("merge ours into theirs"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "a", Mode: "100644", Content: "ours-content\ntheirs-content"}), + gittest.WithParents(theirs, ours), + ) + ours2 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("ours 2"), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "a", Mode: "100644", Content: "ours-content"}, + gittest.TreeEntry{Path: "ours-file", Mode: "100644", Content: "new-content"}, + ), + gittest.WithParents(ours), + ) + + // We had conflicting commit on "ours" and on "theirs", + // then we have manually merged "ours into "theirs" resolving the conflict, + // and then we created one non-conflicting commit on branch "ours". + // + // o-------o ours + // / \ + // base o X + // \ \ + // o---o theirs + // + // We're now squashing both commits from "theirs" onto "ours". + response, err := client.UserSquash(ctx, &gitalypb.UserSquashRequest{ + Repository: repo, + User: gittest.TestUser, + Author: gittest.TestUser, + CommitMessage: commitMessage, + StartSha: ours2.String(), + EndSha: oursMergedIntoTheirs.String(), + Timestamp: ×tamppb.Timestamp{Seconds: 1234512345}, + }) + + // With squashing using merge, we should successfully merge without any issues. + // The new detached commit history will look like this: + // + // HEAD o---o---o---o + // + // We have one commit from "base", two from "ours" + // and one squash commit that contains squashed changes from branch "theirs". + require.Nil(t, err) + testhelper.ProtoEqual(t, &gitalypb.UserSquashResponse{ + SquashSha: "69d8db2439502c18b9c17c2d1bddb122a82bd448", + }, response) + gittest.RequireTree(t, cfg, repoPath, "69d8db2439502c18b9c17c2d1bddb122a82bd448", []gittest.TreeEntry{ + { + // It should use the version from commit "oursMergedIntoTheirs", + // as it resolves the pre-existing conflict. + Content: "ours-content\ntheirs-content", + Mode: "100644", + Path: "a", + }, + { + // This is the file that only existed on branch "ours". + Content: "new-content", + Mode: "100644", + Path: "ours-file", + }, + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules.go index 68375c2262..dd8e3ee70d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules.go @@ -8,18 +8,18 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const userUpdateSubmoduleName = "UserUpdateSubmodule" -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserUpdateSubmodule(ctx context.Context, req *gitalypb.UserUpdateSubmoduleRequest) (*gitalypb.UserUpdateSubmoduleResponse, error) { if err := validateUserUpdateSubmoduleRequest(req); err != nil { return nil, status.Errorf(codes.InvalidArgument, userUpdateSubmoduleName+": %v", err) @@ -138,7 +138,7 @@ func (s *Server) userUpdateSubmodule(ctx context.Context, req *gitalypb.UserUpda return nil, fmt.Errorf("%s: submodule subcommand: %w", userUpdateSubmoduleName, err) } - commitID, err := git.NewObjectIDFromHex(result.CommitID) + commitID, err := git.ObjectHashSHA1.FromHex(result.CommitID) if err != nil { return nil, helper.ErrInvalidArgumentf("cannot parse commit ID: %w", err) } @@ -152,10 +152,10 @@ func (s *Server) userUpdateSubmodule(ctx context.Context, req *gitalypb.UserUpda commitID, branchOID, ); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + var customHookErr updateref.CustomHookError + if errors.As(err, &customHookErr) { return &gitalypb.UserUpdateSubmoduleResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErr.Error(), }, nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules_test.go index 6c6107b6c8..43ab9856bd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/submodules_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/submodules_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -7,13 +9,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/lstree" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -30,14 +32,14 @@ func TestSuccessfulUserUpdateSubmoduleRequest(t *testing.T) { // a branch which has a name starting with "refs/heads/". currentOID, err := repo.ResolveRevision(ctx, "refs/heads/master") require.NoError(t, err) - require.NoError(t, repo.UpdateRef(ctx, "refs/heads/refs/heads/master", currentOID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/heads/refs/heads/master", currentOID, git.ObjectHashSHA1.ZeroOID)) // If something uses the branch name as an unqualified reference, then // git would return the tag instead of the branch. We thus create a tag // with a different OID than the current master branch. prevOID, err := repo.ResolveRevision(ctx, "refs/heads/master~") require.NoError(t, err) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/master", prevOID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/master", prevOID, git.ObjectHashSHA1.ZeroOID)) commitMessage := []byte("Update Submodule message") @@ -91,7 +93,7 @@ func TestSuccessfulUserUpdateSubmoduleRequest(t *testing.T) { require.Equal(t, commitMessage, commit.Subject) entry := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-z", fmt.Sprintf("%s^{tree}:", response.BranchUpdate.CommitId), testCase.submodule) - parser := lstree.NewParser(bytes.NewReader(entry)) + parser := lstree.NewParser(bytes.NewReader(entry), git.ObjectHashSHA1) parsedEntry, err := parser.NextEntry() require.NoError(t, err) require.Equal(t, testCase.submodule, parsedEntry.Path) @@ -177,7 +179,7 @@ func TestUserUpdateSubmoduleQuarantine(t *testing.T) { require.NotEmpty(t, response.GetPreReceiveError()) hookOutput := testhelper.MustReadFile(t, outputPath) - oid, err := git.NewObjectIDFromHex(text.ChompBytes(hookOutput)) + oid, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(hookOutput)) require.NoError(t, err) exists, err := repo.HasRevision(ctx, oid.Revision()+"^{commit}") require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags.go similarity index 57% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags.go index 68acb036aa..71909dfb17 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/tags.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags.go @@ -8,17 +8,19 @@ import ( "regexp" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserDeleteTag(ctx context.Context, req *gitalypb.UserDeleteTagRequest) (*gitalypb.UserDeleteTagResponse, error) { if len(req.TagName) == 0 { return nil, status.Errorf(codes.InvalidArgument, "empty tag name") @@ -34,11 +36,11 @@ func (s *Server) UserDeleteTag(ctx context.Context, req *gitalypb.UserDeleteTagR return nil, status.Errorf(codes.FailedPrecondition, "tag not found: %s", req.TagName) } - if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, nil, referenceName, git.ZeroOID, revision); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, nil, referenceName, git.ObjectHashSHA1.ZeroOID, revision); err != nil { + var customHookErr updateref.CustomHookError + if errors.As(err, &customHookErr) { return &gitalypb.UserDeleteTagResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErr.Error(), }, nil } @@ -54,45 +56,41 @@ func (s *Server) UserDeleteTag(ctx context.Context, req *gitalypb.UserDeleteTagR } func validateUserCreateTag(req *gitalypb.UserCreateTagRequest) error { - // Emulate validations done by Ruby. A lot of these (e.g. the - // upper-case error messages) can be simplified once we're not - // doing bug-for-bug Ruby emulation anymore) if len(req.TagName) == 0 { - return status.Errorf(codes.InvalidArgument, "empty tag name") + return fmt.Errorf("empty tag name") } - if bytes.Contains(req.TagName, []byte(" ")) { - return status.Errorf(codes.Unknown, "Gitlab::Git::CommitError: Could not update refs/tags/%s. Please refresh and try again.", req.TagName) + if err := git.ValidateRevision(req.TagName); err != nil { + return fmt.Errorf("invalid tag name: %w", err) } if req.User == nil { - return status.Errorf(codes.InvalidArgument, "empty user") + return fmt.Errorf("empty user") } if len(req.TargetRevision) == 0 { - return status.Error(codes.InvalidArgument, "empty target revision") + return fmt.Errorf("empty target revision") } if bytes.Contains(req.Message, []byte("\000")) { - return status.Errorf(codes.Unknown, "ArgumentError: string contains null byte") + return fmt.Errorf("tag message contains NUL byte") } - // Our own Go-specific validation if req.GetRepository() == nil { - return status.Errorf(codes.Internal, "empty repository") + return fmt.Errorf("empty repository") } return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) UserCreateTag(ctx context.Context, req *gitalypb.UserCreateTagRequest) (*gitalypb.UserCreateTagResponse, error) { - // Validate the request if err := validateUserCreateTag(req); err != nil { - return nil, err + return nil, helper.ErrInvalidArgumentf("validating request: %w", err) } targetRevision := git.Revision(req.TargetRevision) + referenceName := git.ReferenceName(fmt.Sprintf("refs/tags/%s", req.TagName)) committerTime, err := dateFromProto(req) if err != nil { @@ -109,12 +107,112 @@ func (s *Server) UserCreateTag(ctx context.Context, req *gitalypb.UserCreateTagR return nil, err } - referenceName := git.ReferenceName(fmt.Sprintf("refs/tags/%s", req.TagName)) - if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, quarantineDir, referenceName, tagID, git.ZeroOID); err != nil { - var hookError updateref.HookError - if errors.As(err, &hookError) { + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + // We check whether the reference exists up-front so that we can return a proper + // detailed error to the caller in case the tag cannot be created. While this is + // racy given that the tag can be created afterwards by a concurrent caller, we'd + // detect that raciness in `updateReferenceWithHooks()` anyway. + if oid, err := quarantineRepo.ResolveRevision(ctx, referenceName.Revision()); err != nil { + // If the reference wasn't found we're on the happy path, otherwise + // something has gone wrong. + if !errors.Is(err, git.ErrReferenceNotFound) { + return nil, helper.ErrInternalf("resolving target reference: %w", err) + } + } else { + // When resolving the revision succeeds the tag reference exists already. + // Because we don't want to overwrite preexisting references in this RPC we + // thus return an error and alert the caller of this condition. + detailedErr, err := helper.ErrWithDetails( + helper.ErrAlreadyExistsf("tag reference exists already"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_ReferenceExists{ + ReferenceExists: &gitalypb.ReferenceExistsError{ + ReferenceName: []byte(referenceName.String()), + Oid: oid.String(), + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("creating detailed error: %w", err) + } + + return nil, detailedErr + } + } + + if err := s.updateReferenceWithHooks(ctx, req.Repository, req.User, quarantineDir, referenceName, tagID, git.ObjectHashSHA1.ZeroOID); err != nil { + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + var notAllowedError hook.NotAllowedError + var customHookErr updateref.CustomHookError + var updateRefError updateref.Error + + if errors.As(err, ¬AllowedError) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrPermissionDeniedf("reference update denied by access checks: %w", err), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: notAllowedError.Message, + UserId: notAllowedError.UserID, + Protocol: notAllowedError.Protocol, + Changes: notAllowedError.Changes, + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } else if errors.As(err, &customHookErr) { + detailedErr, err := helper.ErrWithDetails( + // We explicitly don't include the custom hook error itself + // in the returned error because that would also contain the + // standard output or standard error in the error message. + // It's thus needlessly verbose and duplicates information + // we have available in the structured error anyway. + helper.ErrPermissionDeniedf("reference update denied by custom hooks"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_CustomHook{ + CustomHook: customHookErr.Proto(), + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } else if errors.As(err, &updateRefError) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("reference update failed: %w", err), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_ReferenceUpdate{ + ReferenceUpdate: &gitalypb.ReferenceUpdateError{ + ReferenceName: []byte(updateRefError.Reference.String()), + OldOid: updateRefError.OldOID.String(), + NewOid: updateRefError.NewOID.String(), + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } + + return nil, helper.ErrInternalf("updating reference: %w", err) + } + + var customHookErrr updateref.CustomHookError + if errors.As(err, &customHookErrr) { + // TODO: this case should return a CustomHookError. return &gitalypb.UserCreateTagResponse{ - PreReceiveError: hookError.Error(), + PreReceiveError: customHookErrr.Error(), }, nil } @@ -136,6 +234,8 @@ func (s *Server) UserCreateTag(ctx context.Context, req *gitalypb.UserCreateTagR // does is what the Ruby code used to // do, so let's follow it off that // cliff. + // + // TODO: this case should return a ReferenceExistsError. return &gitalypb.UserCreateTagResponse{ Tag: nil, Exists: true, @@ -146,6 +246,8 @@ func (s *Server) UserCreateTag(ctx context.Context, req *gitalypb.UserCreateTagR // tell the user to retry with an // invalid ref name, but ditto on the // Ruby bug-for-bug emulation. + // + // TODO: this case should return a ReferenceUpdateError. return &gitalypb.UserCreateTagResponse{ Tag: nil, Exists: true, @@ -158,6 +260,9 @@ func (s *Server) UserCreateTag(ctx context.Context, req *gitalypb.UserCreateTagR // we've got an unknown error (it should all be // updateRefError above) let's relay it to the // caller. This should not happen. + // + // TODO: this case should either return an AccessCheckError in case Rails refused + // the update, or alternatively an Internal error. return &gitalypb.UserCreateTagResponse{ Tag: nil, Exists: true, @@ -178,15 +283,17 @@ func (s *Server) createTag( committer *gitalypb.User, committerTime time.Time, ) (*gitalypb.Tag, git.ObjectID, error) { - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return nil, "", status.Error(codes.Internal, err.Error()) } + defer cancel() - objectInfoReader, err := s.catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(ctx, repo) if err != nil { return nil, "", status.Error(codes.Internal, err.Error()) } + defer cancel() // We allow all ways to name a revision that cat-file // supports, not just OID. Resolve it. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags_test.go new file mode 100644 index 0000000000..37fa8af950 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/tags_test.go @@ -0,0 +1,1469 @@ +//go:build !gitaly_test_sha256 + +package operations + +import ( + "context" + "fmt" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestUserDeleteTag_successful(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + tagNameInput := "to-be-deleted-soon-tag" + + gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) + + request := &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte(tagNameInput), + User: gittest.TestUser, + } + + response, err := client.UserDeleteTag(ctx, request) + require.NoError(t, err) + require.Empty(t, response.PreReceiveError) + + tags := gittest.Exec(t, cfg, "-C", repoPath, "tag") + require.NotContains(t, string(tags), tagNameInput, "tag name still exists in tags list") +} + +func TestUserDeleteTag_hooks(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + tagNameInput := "to-be-déleted-soon-tag" + + request := &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte(tagNameInput), + User: gittest.TestUser, + } + + for _, hookName := range GitlabHooks { + t.Run(hookName, func(t *testing.T) { + gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) + + hookOutputTempPath := gittest.WriteEnvToCustomHook(t, repoPath, hookName) + + _, err := client.UserDeleteTag(ctx, request) + require.NoError(t, err) + + output := testhelper.MustReadFile(t, hookOutputTempPath) + require.Contains(t, string(output), "GL_USERNAME="+gittest.TestUser.GlUsername) + }) + } +} + +func writeAssertObjectTypePreReceiveHook(t *testing.T, repoPath, expectedObjectType string) { + t.Helper() + + gittest.WriteCustomHook(t, repoPath, "pre-receive", []byte(fmt.Sprintf(`#!/bin/bash + i=0 + while read oldvalue newvalue reference + do + i=$((i+1)) + + if [[ "${reference}" =~ skip-type-check- ]] + then + continue + fi + + type="$(git cat-file -t "${newvalue}")" + if test "%[1]s" != "${type}" + then + echo "expected %[1]s, got ${type}" >&2 + exit 1 + fi + done + + if test "$i" -ne 1 + then + echo "expected exactly one reference update, got ${i}" >&2 + exit 1 + fi + `, expectedObjectType))) +} + +func writeAssertObjectTypeUpdateHook(t *testing.T, repoPath, expectedObjectType string) { + t.Helper() + + gittest.WriteCustomHook(t, repoPath, "update", []byte(fmt.Sprintf(`#!/bin/bash + if [[ "$1" =~ skip-type-check- ]] + then + exit 0 + fi + + type="$(git cat-file -t "$3")" + if test "%[1]s" != "${type}" + then + echo "expected %[1]s, got ${type}" >&2 + exit 1 + fi + `, expectedObjectType))) +} + +func TestUserCreateTag_successful(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagSuccessful) +} + +func testUserCreateTagSuccessful(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + + targetRevisionCommit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + inputTagName := "to-be-créated-soon" + + for _, tc := range []struct { + desc string + tagName string + message string + targetRevision git.Revision + expectedObjectType string + expectedResponse *gitalypb.UserCreateTagResponse + }{ + { + desc: "lightweight tag to commit", + tagName: inputTagName, + targetRevision: commitID.Revision(), + expectedResponse: &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte(inputTagName), + Id: commitID.String(), + TargetCommit: targetRevisionCommit, + }, + }, + expectedObjectType: "commit", + }, + { + desc: "annotated tag to commit", + tagName: inputTagName, + targetRevision: commitID.Revision(), + message: "This is an annotated tag", + expectedResponse: &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte(inputTagName), + Id: "6c6134431f05e3d22726a3876cc1fecea7df18b5", + TargetCommit: targetRevisionCommit, + Message: []byte("This is an annotated tag"), + MessageSize: 24, + }, + }, + expectedObjectType: "tag", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + writeAssertObjectTypePreReceiveHook(t, repoPath, tc.expectedObjectType) + writeAssertObjectTypeUpdateHook(t, repoPath, tc.expectedObjectType) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte(tc.tagName), + TargetRevision: []byte(tc.targetRevision), + User: gittest.TestUser, + Message: []byte(tc.message), + Timestamp: timestamppb.New(time.Unix(1600000000, 0)), + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, tc.expectedResponse, response) + + defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", inputTagName) + + tag := gittest.Exec(t, cfg, "-C", repoPath, "tag") + require.Contains(t, string(tag), inputTagName) + }) + } +} + +func TestUserCreateTag_transactional(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagTransactional) +} + +func testUserCreateTagTransactional(t *testing.T, ctx context.Context) { + t.Parallel() + + cfg := testcfg.Build(t) + cfg.SocketPath = runOperationServiceServer(t, cfg, testserver.WithDisablePraefect()) + + transactionServer := &testTransactionServer{} + + // We're using internal gitaly socket to connect to the server. + // This is kind of a hack when running tests with Praefect: + // if we directly connect to the server created above, then our call + // would be intercepted by Praefect, which would in turn replace the + // transaction information we inject further down below. So we instead + // use internal socket so we can circumvent Praefect and just talk + // to Gitaly directly. + client := newMuxedOperationClient(t, ctx, "unix://"+cfg.InternalSocketPath(), cfg.Auth.Token, + backchannel.NewClientHandshaker( + testhelper.NewDiscardingLogEntry(t), + func() backchannel.Server { + srv := grpc.NewServer() + gitalypb.RegisterRefTransactionServer(srv, transactionServer) + return srv + }, + ), + ) + + for _, tc := range []struct { + desc string + primary bool + message string + }{ + { + desc: "primary creates a lightweight tag", + primary: true, + }, + { + desc: "secondary creates a lightweight tag", + primary: false, + }, + { + desc: "primary creates an annotated tag", + primary: true, + message: "foobar", + }, + { + desc: "secondary creates an annotated tag", + primary: false, + message: "foobar", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + *transactionServer = testTransactionServer{} + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + hooksOutputDir := testhelper.TempDir(t) + hooksOutputPath := filepath.Join(hooksOutputDir, "output") + + // We're creating a set of custom hooks which simply + // write to a file. The intention is that we want to + // check that the hooks only run on the primary node. + hooks := []string{"pre-receive", "update", "post-receive"} + for _, hook := range hooks { + gittest.WriteCustomHook(t, repoPath, hook, + []byte(fmt.Sprintf("#!/bin/sh\necho %s >>%s\n", hook, hooksOutputPath)), + ) + } + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + targetCommit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + // We need to convert to an incoming context first in + // order to preserve the feature flag. + ctx := metadata.OutgoingToIncoming(ctx) + ctx, err = txinfo.InjectTransaction(ctx, 1, "node", tc.primary) + require.NoError(t, err) + ctx = metadata.IncomingToOutgoing(ctx) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("v1.0.0"), + Message: []byte(tc.message), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte("v1.0.0"), + Message: []byte(tc.message), + MessageSize: int64(len(tc.message)), + Id: text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/tags/v1.0.0")), + TargetCommit: targetCommit, + }, + }, response) + + peeledTagID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/tags/v1.0.0^{commit}")) + require.Equal(t, commitID.String(), peeledTagID) + + // Only the primary node should've executed hooks. + if tc.primary { + contents := testhelper.MustReadFile(t, hooksOutputPath) + require.Equal(t, "pre-receive\nupdate\npost-receive\n", string(contents)) + } else { + require.NoFileExists(t, hooksOutputPath) + } + + require.Equal(t, 2, transactionServer.called) + transactionServer.called = 0 + }) + } +} + +func TestUserCreateTag_quarantine(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagQuarantine) +} + +func testUserCreateTagQuarantine(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + + tagIDOutputPath := filepath.Join(testhelper.TempDir(t), "tag-id") + + // We set up a custom "pre-receive" hook which simply prints the new tag to stdout and then + // exits with an error. Like this, we can both assert that the hook can see the quarantined + // tag, and it allows us to fail the RPC before we migrate quarantined objects. Furthermore, + // we also try whether we can print the tag's tagged object to assert that we can see + // objects which are not part of the object quarantine. + gittest.WriteCustomHook(t, repoPath, "pre-receive", []byte(fmt.Sprintf( + `#!/bin/sh + read oldval newval ref && + git cat-file -p $newval^{commit} >/dev/null && + echo "$newval" >%q && + git cat-file -p $newval^{tag} && + exit 1 + `, tagIDOutputPath))) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("quarantined-tag"), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + Timestamp: timestamppb.New(time.Unix(1600000000, 0)), + Message: []byte("message"), + }) + + expectedObject := fmt.Sprintf(`object %s +type commit +tag quarantined-tag +tagger Jane Doe 1600000000 +0800 + +message`, commitID) + + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("reference update denied by custom hooks"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + Stdout: []byte(expectedObject), + }, + }, + }, + ), err) + require.Nil(t, response) + } else { + require.NoError(t, err) + // Conveniently, the pre-receive error will now contain output from our custom hook and thus + // the tag's contents. + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + PreReceiveError: expectedObject, + }, response) + } + + tagID := text.ChompBytes(testhelper.MustReadFile(t, tagIDOutputPath)) + + // In case we use an object quarantine directory, the tag should not exist in the target + // repository because the RPC failed to update the revision. + tagExists, err := repo.HasRevision(ctx, git.Revision(tagID+"^{tag}")) + require.NoError(t, err) + require.False(t, tagExists, "tag should not have been migrated") +} + +func TestUserCreateTag_message(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagMessage) +} + +func testUserCreateTagMessage(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + for _, tc := range []struct { + desc string + message string + expectedObjectType string + expectedErr error + expectedMessage string + }{ + { + desc: "error: contains null byte", + message: "\000", + expectedErr: helper.ErrInvalidArgumentf("validating request: tag message contains NUL byte"), + }, + { + desc: "annotated: some control characters", + message: "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008", + expectedObjectType: "tag", + expectedMessage: "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008", + }, + { + desc: "lightweight: empty message", + message: "", + expectedObjectType: "commit", + }, + { + desc: "lightweight: simple whitespace", + message: " \t\t", + expectedObjectType: "commit", + }, + { + desc: "lightweight: whitespace with newlines", + message: "\t\n\f\r ", + expectedObjectType: "commit", + }, + { + desc: "annotated: simple Unicode whitespace", + message: "\u00a0", + expectedObjectType: "tag", + expectedMessage: "\u00a0", + }, + { + desc: "lightweight: lots of Unicode whitespace", + message: "\u0020\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\ufeff", + expectedObjectType: "tag", + expectedMessage: "\u0020\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\ufeff", + }, + { + desc: "annotated: dot", + message: ".", + expectedObjectType: "tag", + expectedMessage: ".", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + writeAssertObjectTypePreReceiveHook(t, repoPath, tc.expectedObjectType) + writeAssertObjectTypeUpdateHook(t, repoPath, tc.expectedObjectType) + + request := &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("what-will-it-be"), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + Message: []byte(tc.message), + } + + response, err := client.UserCreateTag(ctx, request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + if tc.expectedErr == nil { + response.Tag.Id = "" + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte("what-will-it-be"), + Message: []byte(tc.expectedMessage), + MessageSize: int64(len(tc.expectedMessage)), + TargetCommit: commit, + }, + }, response) + } else { + require.Nil(t, response) + } + }) + } +} + +func TestUserCreateTag_targetRevision(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagTargetRevision) +} + +func testUserCreateTagTargetRevision(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + for _, tc := range []struct { + desc string + targetRevision string + expectedRevision string + }{ + { + desc: "unqualified tag", + targetRevision: "v1.0.0", + expectedRevision: "refs/tags/v1.0.0", + }, + { + desc: "parent of unqualified tag", + targetRevision: "v1.0.0~", + expectedRevision: "refs/tags/v1.0.0~", + }, + { + desc: "parent of semi-qualified tag", + targetRevision: "tags/v1.0.0~", + expectedRevision: "refs/tags/v1.0.0~", + }, + { + desc: "parent of fully-qualified tag", + targetRevision: "refs/tags/v1.0.0~", + expectedRevision: "refs/tags/v1.0.0~", + }, + { + desc: "unqualified branch", + targetRevision: "main", + expectedRevision: "refs/heads/main", + }, + { + desc: "fully-qualified branch", + targetRevision: "refs/heads/main", + expectedRevision: "refs/heads/main", + }, + { + desc: "ambiguous branch starting with heads", + targetRevision: "heads/main", + expectedRevision: "refs/heads/main", + }, + { + desc: "ambiguated branch", + targetRevision: "heads/heads/main", + expectedRevision: "refs/heads/heads/main", + }, + { + desc: "deep ambiguous branch", + targetRevision: "heads/refs/heads/main", + expectedRevision: "refs/heads/refs/heads/main", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + baseCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithMessage("1")) + + // We create an ambiguous branching structure that has "refs/heads/main", + // "refs/heads/heads/main" and "refs/heads/refs/heads/main" to exercise how + // we resolve the tag's target revision. + gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(baseCommit), gittest.WithBranch("main"), gittest.WithMessage("2")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(baseCommit), gittest.WithBranch("heads/main"), gittest.WithMessage("3")) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(baseCommit), gittest.WithBranch("refs/heads/main"), gittest.WithMessage("4")) + + taggedCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(baseCommit), gittest.WithMessage("5")) + gittest.WriteTag(t, cfg, repoPath, "v1.0.0", taggedCommit.Revision()) + + expectedCommit, err := repo.ReadCommit(ctx, git.Revision(tc.expectedRevision)) + require.NoError(t, err) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("tag"), + TargetRevision: []byte(tc.targetRevision), + User: gittest.TestUser, + }) + require.NoError(t, err) + + testhelper.ProtoEqual(t, response, &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Id: expectedCommit.Id, + Name: []byte("tag"), + TargetCommit: expectedCommit, + }, + }) + + // Perform another sanity check to verify that the tag really does point to + // the commit we expect it to. + parsedID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "tag") + require.Equal(t, response.Tag.TargetCommit.Id, text.ChompBytes(parsedID)) + }) + } +} + +func TestUserCreateTag_nonCommitTarget(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagNonCommitTarget) +} + +func testUserCreateTagNonCommitTarget(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("content")) + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "file", Mode: "100644", Content: "something"}, + }) + + for _, tc := range []struct { + desc string + tagName string + message string + targetRevision git.Revision + expectedTag *gitalypb.Tag + expectedObjectType string + }{ + { + desc: "lightweight tag to tree", + tagName: "lightweight-to-tree", + targetRevision: treeID.Revision(), + expectedTag: &gitalypb.Tag{ + Name: []byte("lightweight-to-tree"), + Id: treeID.String(), + }, + expectedObjectType: "tree", + }, + { + desc: "lightweight tag to blob", + tagName: "lightweight-to-blob", + targetRevision: blobID.Revision(), + expectedTag: &gitalypb.Tag{ + Name: []byte("lightweight-to-blob"), + Id: blobID.String(), + }, + expectedObjectType: "blob", + }, + { + desc: "annotated tag to tree", + tagName: "annotated-to-tree", + targetRevision: treeID.Revision(), + message: "This is an annotated tag", + expectedTag: &gitalypb.Tag{ + Name: []byte("annotated-to-tree"), + Message: []byte("This is an annotated tag"), + MessageSize: 24, + }, + expectedObjectType: "tag", + }, + { + desc: "annotated tag to blob", + tagName: "annotated-to-blob", + targetRevision: blobID.Revision(), + message: "This is an annotated tag", + expectedTag: &gitalypb.Tag{ + Name: []byte("annotated-to-blob"), + Message: []byte("This is an annotated tag"), + MessageSize: 24, + }, + expectedObjectType: "tag", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + writeAssertObjectTypePreReceiveHook(t, repoPath, tc.expectedObjectType) + writeAssertObjectTypeUpdateHook(t, repoPath, tc.expectedObjectType) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repo, + TagName: []byte(tc.tagName), + TargetRevision: []byte(tc.targetRevision), + User: gittest.TestUser, + Message: []byte(tc.message), + }) + require.NoError(t, err) + + // We cannot know the object ID of the annotated tags beforehand, so we just + // fill in this detail now. + if len(tc.expectedTag.Id) == 0 { + tc.expectedTag.Id = text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tc.tagName)) + } + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: tc.expectedTag, + }, response) + + peeledID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tc.tagName+"^{}") + require.Equal(t, tc.targetRevision.String(), text.ChompBytes(peeledID)) + }) + } +} + +func TestUserCreateTag_nestedTags(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagNestedTags) +} + +func testUserCreateTagNestedTags(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + for _, tc := range []struct { + desc string + targetObject string + targetObjectType string + expectedTag *gitalypb.Tag + }{ + { + desc: "nested tags to commit", + targetObject: "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + targetObjectType: "commit", + }, + { + desc: "nested tags to tree", + targetObjectType: "tree", + targetObject: "612036fac47c5d31c212b17268e2f3ba807bce1e", + }, + { + desc: "nested tags to blob", + targetObject: "dfaa3f97ca337e20154a98ac9d0be76ddd1fcc82", + targetObjectType: "blob", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + // We resolve down to commit/tree/blob, but we'll only ever push a "tag" + // here. + writeAssertObjectTypePreReceiveHook(t, repoPath, "tag") + writeAssertObjectTypeUpdateHook(t, repoPath, "tag") + + targetObject := tc.targetObject + nestLevel := 2 + for i := 0; i <= nestLevel; i++ { + tagName := fmt.Sprintf("nested-tag-%v", i) + tagMessage := fmt.Sprintf("This is level %v of a nested annotated tag to %v", i, tc.targetObject) + request := &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte(tagName), + TargetRevision: []byte(targetObject), + User: gittest.TestUser, + Message: []byte(tagMessage), + } + response, err := client.UserCreateTag(ctx, request) + require.NoError(t, err) + require.Empty(t, response.PreReceiveError) + defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagName) + + createdID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagName) + createdIDStr := text.ChompBytes(createdID) + responseOk := &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: request.TagName, + Id: createdIDStr, + // TargetCommit: is dynamically determined, filled in below + Message: request.Message, + MessageSize: int64(len(request.Message)), + }, + } + // Fake it up for all levels, except for ^{} == "commit" + responseOk.Tag.TargetCommit = response.Tag.TargetCommit + if tc.targetObjectType == "commit" { + responseOk.Tag.TargetCommit, err = repo.ReadCommit(ctx, git.Revision(tc.targetObject)) + require.NoError(t, err) + } + testhelper.ProtoEqual(t, responseOk, response) + + peeledID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagName+"^{}") + peeledIDStr := text.ChompBytes(peeledID) + require.Equal(t, tc.targetObject, peeledIDStr) + + // Set up the next level of nesting... + targetObject = response.Tag.Id + + // Create a *lightweight* tag pointing + // to our N-level + // tag->[commit|tree|blob]. The "tag" + // field name will not match the tag + // name. + tagNameLight := fmt.Sprintf("skip-type-check-light-%s", tagName) + request = &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte(tagNameLight), + TargetRevision: []byte(createdIDStr), + User: gittest.TestUser, + } + response, err = client.UserCreateTag(ctx, request) + defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameLight) + require.NoError(t, err) + require.Empty(t, response.PreReceiveError) + + responseOk = &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: request.TagName, + Id: tc.targetObject, + TargetCommit: responseOk.Tag.TargetCommit, + Message: nil, + MessageSize: 0, + }, + } + testhelper.ProtoEqual(t, responseOk, response) + + createdIDLight := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", tagNameLight) + createdIDLightStr := text.ChompBytes(createdIDLight) + require.Equal(t, tc.targetObject, createdIDLightStr) + } + }) + } +} + +func TestUserCreateTag_stableTagIDs(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagStableTagIDs) +} + +func testUserCreateTagStableTagIDs(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("happy-tag"), + TargetRevision: []byte(commitID), + Message: []byte("my message"), + User: gittest.TestUser, + Timestamp: ×tamppb.Timestamp{Seconds: 12345}, + }) + require.NoError(t, err) + + require.Equal(t, &gitalypb.Tag{ + Id: "d877784c740f492d74e6073de649a6b046ab3656", + Name: []byte("happy-tag"), + Message: []byte("my message"), + MessageSize: 10, + TargetCommit: commit, + }, response.Tag) +} + +func TestUserDeleteTag_prefixedTag(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + testCases := []struct { + desc string + tagNameInput string + tagCommit string + user *gitalypb.User + response *gitalypb.UserDeleteTagResponse + err error + }{ + { + desc: "possible to delete a tag called refs/tags/something", + tagNameInput: "refs/tags/can-find-this", + tagCommit: "c642fe9b8b9f28f9225d7ea953fe14e74748d53b", + user: gittest.TestUser, + response: &gitalypb.UserDeleteTagResponse{}, + err: nil, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + gittest.Exec(t, cfg, "-C", repoPath, "tag", testCase.tagNameInput, testCase.tagCommit) + + request := &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte(testCase.tagNameInput), + User: testCase.user, + } + + response, err := client.UserDeleteTag(ctx, request) + testhelper.RequireGrpcError(t, testCase.err, err) + testhelper.ProtoEqual(t, testCase.response, response) + + refs := gittest.Exec(t, cfg, "-C", repoPath, "for-each-ref", "--", "refs/tags/"+testCase.tagNameInput) + require.NotContains(t, string(refs), testCase.tagCommit, "tag kept because we stripped off refs/tags/*") + }) + } +} + +func TestUserCreateTag_prefixedTag(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagPrefixedTag) +} + +func testUserCreateTagPrefixedTag(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + // We try to create a tag that has a nested name of "refs/tags/refs/tags/". + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("refs/tags/can-create-this"), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte("refs/tags/can-create-this"), + Id: commitID.String(), + TargetCommit: commit, + }, + }, response) + + // Verify that the tag indeed has the awkward but expected name. + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/tags/refs/tags/can-create-this")), + commitID.String(), + ) +} + +func TestUserCreateTag_gitHooks(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagGitHooks) +} + +func testUserCreateTagGitHooks(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + for _, hookName := range GitlabHooks { + t.Run(hookName, func(t *testing.T) { + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commit, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(t, err) + + hookOutputTempPath := gittest.WriteEnvToCustomHook(t, repoPath, hookName) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repoProto, + TagName: []byte("v1.0.0"), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: &gitalypb.Tag{ + Name: []byte("v1.0.0"), + Id: commitID.String(), + TargetCommit: commit, + }, + }, response) + + output := string(testhelper.MustReadFile(t, hookOutputTempPath)) + require.Contains(t, output, "GL_USERNAME="+gittest.TestUser.GlUsername) + require.Contains(t, output, "GL_PROJECT_PATH=gitlab-org/gitlab-test") + }) + } +} + +func TestUserDeleteTag_invalidArgument(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, _, repo, _, client := setupOperationsService(t, ctx) + + testCases := []struct { + desc string + request *gitalypb.UserDeleteTagRequest + response *gitalypb.UserDeleteTagResponse + err error + }{ + { + desc: "empty user", + request: &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte("does-matter-the-name-if-user-is-empty"), + }, + response: nil, + err: status.Error(codes.InvalidArgument, "empty user"), + }, + { + desc: "empty tag name", + request: &gitalypb.UserDeleteTagRequest{ + Repository: repo, + User: gittest.TestUser, + }, + response: nil, + err: status.Error(codes.InvalidArgument, "empty tag name"), + }, + { + desc: "non-existent tag name", + request: &gitalypb.UserDeleteTagRequest{ + Repository: repo, + User: gittest.TestUser, + TagName: []byte("i-do-not-exist"), + }, + response: nil, + err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "i-do-not-exist"), + }, + { + desc: "space in tag name", + request: &gitalypb.UserDeleteTagRequest{ + Repository: repo, + User: gittest.TestUser, + TagName: []byte("a tag"), + }, + response: nil, + err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a tag"), + }, + { + desc: "newline in tag name", + request: &gitalypb.UserDeleteTagRequest{ + Repository: repo, + User: gittest.TestUser, + TagName: []byte("a\ntag"), + }, + response: nil, + err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a\ntag"), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + response, err := client.UserDeleteTag(ctx, testCase.request) + testhelper.RequireGrpcError(t, testCase.err, err) + testhelper.ProtoEqual(t, testCase.response, response) + }) + } +} + +func TestUserDeleteTag_hookFailure(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + tagNameInput := "to-be-deleted-soon-tag" + gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) + defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameInput) + + request := &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte(tagNameInput), + User: gittest.TestUser, + } + + hookContent := []byte("#!/bin/sh\necho GL_ID=$GL_ID\nexit 1") + + for _, hookName := range gitlabPreHooks { + t.Run(hookName, func(t *testing.T) { + gittest.WriteCustomHook(t, repoPath, hookName, hookContent) + + response, err := client.UserDeleteTag(ctx, request) + require.NoError(t, err) + require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) + + tags := gittest.Exec(t, cfg, "-C", repoPath, "tag") + require.Contains(t, string(tags), tagNameInput, "tag name does not exist in tags list") + }) + } +} + +func TestUserCreateTag_hookFailure(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagHookFailure) +} + +func testUserCreateTagHookFailure(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + for _, tc := range []struct { + hook string + hookType gitalypb.CustomHookError_HookType + }{ + { + hook: "pre-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + }, + { + hook: "update", + hookType: gitalypb.CustomHookError_HOOK_TYPE_UPDATE, + }, + } { + t.Run(tc.hook, func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + + gittest.WriteCustomHook(t, repoPath, tc.hook, []byte( + "#!/bin/sh\necho GL_ID=$GL_ID\nexit 1"), + ) + + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repo, + TagName: []byte("new-tag"), + TargetRevision: []byte(commitID), + User: gittest.TestUser, + }) + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("reference update denied by custom hooks"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: tc.hookType, + Stdout: []byte( + "GL_ID=" + gittest.TestUser.GlId + "\n", + ), + }, + }, + }, + ), err) + require.Nil(t, response) + } else { + require.NoError(t, err) + require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) + } + }) + } +} + +func TestUserCreateTag_preexisting(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagPreexisting) +} + +func testUserCreateTagPreexisting(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + gittest.WriteTag(t, cfg, repoPath, "v1.1.0", commitID.Revision()) + + for _, tc := range []struct { + desc string + tagName string + targetRevision string + user *gitalypb.User + expectedResponse *gitalypb.UserCreateTagResponse + expectedErr error + }{ + { + desc: "simple existing tag", + tagName: "v1.1.0", + targetRevision: commitID.String(), + user: gittest.TestUser, + expectedErr: func() error { + if featureflag.UserCreateTagStructuredErrors.IsDisabled(ctx) { + return nil + } + + return errWithDetails(t, + helper.ErrAlreadyExistsf("tag reference exists already"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_ReferenceExists{ + ReferenceExists: &gitalypb.ReferenceExistsError{ + ReferenceName: []byte("refs/tags/v1.1.0"), + Oid: commitID.String(), + }, + }, + }, + ) + }(), + expectedResponse: func() *gitalypb.UserCreateTagResponse { + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + return nil + } + + return &gitalypb.UserCreateTagResponse{ + Exists: true, + } + }(), + }, + { + desc: "existing tag nonexisting target revision", + tagName: "v1.1.0", + targetRevision: "does-not-exist", + user: gittest.TestUser, + expectedErr: helper.ErrFailedPreconditionf("revspec 'does-not-exist' not found"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + response, err := client.UserCreateTag(ctx, &gitalypb.UserCreateTagRequest{ + Repository: repo, + TagName: []byte(tc.tagName), + TargetRevision: []byte(tc.targetRevision), + User: tc.user, + }) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + testhelper.ProtoEqual(t, tc.expectedResponse, response) + }) + } +} + +func TestUserCreateTag_invalidArgument(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testUserCreateTagInvalidArgument) +} + +func testUserCreateTagInvalidArgument(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, client := setupOperationsServiceWithoutRepo(t, ctx) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) + + injectedTag := "inject-tag\ntagger . <> 0 +0000\n\nInjected subject\n\n" + + for _, tc := range []struct { + desc string + tagName string + targetRevision string + message string + user *gitalypb.User + expectedErr error + }{ + { + desc: "empty target revision", + tagName: "shiny-new-tag", + targetRevision: "", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: empty target revision"), + }, + { + desc: "empty user", + tagName: "shiny-new-tag", + targetRevision: "main", + user: nil, + expectedErr: helper.ErrInvalidArgumentf("validating request: empty user"), + }, + { + desc: "empty starting point", + tagName: "new-tag", + targetRevision: "", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: empty target revision"), + }, + { + desc: "non-existing starting point", + tagName: "new-tag", + targetRevision: "i-dont-exist", + user: gittest.TestUser, + expectedErr: helper.ErrFailedPreconditionf("revspec '%s' not found", "i-dont-exist"), + }, + { + desc: "space in lightweight tag name", + tagName: "a tag", + targetRevision: "main", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + { + desc: "space in annotated tag name", + tagName: "a tag", + targetRevision: "main", + message: "a message", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + { + desc: "newline in lightweight tag name", + tagName: "a\ntag", + targetRevision: "main", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + { + desc: "newline in annotated tag name", + tagName: "a\ntag", + targetRevision: "main", + message: "a message", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + { + desc: "injection in lightweight tag name", + tagName: injectedTag, + targetRevision: "main", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + { + desc: "injection in annotated tag name", + tagName: injectedTag, + targetRevision: "main", + message: "a message", + user: gittest.TestUser, + expectedErr: helper.ErrInvalidArgumentf("validating request: invalid tag name: revision can't contain whitespace"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + request := &gitalypb.UserCreateTagRequest{ + Repository: repo, + TagName: []byte(tc.tagName), + TargetRevision: []byte(tc.targetRevision), + User: tc.user, + Message: []byte(tc.message), + } + + response, err := client.UserCreateTag(ctx, request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + require.Nil(t, response) + }) + } +} + +func TestTagHookOutput(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UserCreateTagStructuredErrors).Run(t, testTagHookOutput) +} + +func testTagHookOutput(t *testing.T, ctx context.Context) { + t.Parallel() + + ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx) + + for _, tc := range []struct { + desc string + hookContent string + expectedStdout string + expectedStderr string + expectedErr func(hookPath string) string + }{ + { + desc: "empty stdout and empty stderr", + hookContent: "#!/bin/sh\nexit 1", + expectedErr: func(hookPath string) string { + return fmt.Sprintf("executing custom hooks: error executing %q: exit status 1", hookPath) + }, + }, + { + desc: "empty stdout and some stderr", + hookContent: "#!/bin/sh\necho stderr >&2\nexit 1", + expectedStderr: "stderr\n", + expectedErr: func(string) string { return "stderr\n" }, + }, + { + desc: "some stdout and empty stderr", + hookContent: "#!/bin/sh\necho stdout\nexit 1", + expectedStdout: "stdout\n", + expectedErr: func(string) string { return "stdout\n" }, + }, + { + desc: "some stdout and some stderr", + hookContent: "#!/bin/sh\necho stdout\necho stderr >&2\nexit 1", + expectedStdout: "stdout\n", + expectedStderr: "stderr\n", + expectedErr: func(string) string { return "stderr\n" }, + }, + { + desc: "whitespace stdout and some stderr", + hookContent: "#!/bin/sh\necho ' '\necho stderr >&2\nexit 1", + expectedStdout: " \n", + expectedStderr: "stderr\n", + expectedErr: func(string) string { return "stderr\n" }, + }, + { + desc: "some stdout and whitespace stderr", + hookContent: "#!/bin/sh\necho stdout\necho ' ' >&2\nexit 1", + expectedStdout: "stdout\n", + expectedStderr: " \n", + expectedErr: func(string) string { return "stdout\n" }, + }, + } { + for _, hookTC := range []struct { + hook string + hookType gitalypb.CustomHookError_HookType + }{ + { + hook: "pre-receive", + hookType: gitalypb.CustomHookError_HOOK_TYPE_PRERECEIVE, + }, + { + hook: "update", + hookType: gitalypb.CustomHookError_HOOK_TYPE_UPDATE, + }, + } { + t.Run(hookTC.hook+"/"+tc.desc, func(t *testing.T) { + tagNameInput := "some-tag" + createRequest := &gitalypb.UserCreateTagRequest{ + Repository: repo, + TagName: []byte(tagNameInput), + TargetRevision: []byte("master"), + User: gittest.TestUser, + } + deleteRequest := &gitalypb.UserDeleteTagRequest{ + Repository: repo, + TagName: []byte(tagNameInput), + User: gittest.TestUser, + } + + hookFilename := gittest.WriteCustomHook(t, repoPath, hookTC.hook, []byte(tc.hookContent)) + + createResponse, err := client.UserCreateTag(ctx, createRequest) + if featureflag.UserCreateTagStructuredErrors.IsEnabled(ctx) { + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrPermissionDeniedf("reference update denied by custom hooks"), + &gitalypb.UserCreateTagError{ + Error: &gitalypb.UserCreateTagError_CustomHook{ + CustomHook: &gitalypb.CustomHookError{ + HookType: hookTC.hookType, + Stdout: []byte(tc.expectedStdout), + Stderr: []byte(tc.expectedStderr), + }, + }, + }, + ), err) + require.Nil(t, createResponse) + } else { + require.NoError(t, err) + + testhelper.ProtoEqual(t, &gitalypb.UserCreateTagResponse{ + Tag: createResponse.Tag, + Exists: false, + PreReceiveError: tc.expectedErr(hookFilename), + }, createResponse) + } + + defer gittest.Exec(t, cfg, "-C", repoPath, "tag", "-d", tagNameInput) + gittest.Exec(t, cfg, "-C", repoPath, "tag", tagNameInput) + + deleteResponse, err := client.UserDeleteTag(ctx, deleteRequest) + require.NoError(t, err) + deleteResponseOk := &gitalypb.UserDeleteTagResponse{ + PreReceiveError: tc.expectedErr(hookFilename), + } + testhelper.ProtoEqual(t, deleteResponseOk, deleteResponse) + }) + } + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testdata/0001-A-commit-from-a-patch.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testdata/0001-A-commit-from-a-patch.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testdata/0001-A-commit-from-a-patch.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testdata/0001-A-commit-from-a-patch.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testdata/0001-This-does-not-apply-to-the-feature-branch.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testdata/0001-This-does-not-apply-to-the-feature-branch.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testdata/0001-This-does-not-apply-to-the-feature-branch.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testdata/0001-This-does-not-apply-to-the-feature-branch.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testhelper_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testhelper_test.go index 0e7f3e4f6c..09908e8095 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -5,22 +7,23 @@ import ( "testing" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - internalclient "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) var ( @@ -35,29 +38,29 @@ func TestMain(m *testing.M) { testhelper.Run(m) } -func setupOperationsService(t testing.TB, ctx context.Context, options ...testserver.GitalyServerOpt) (context.Context, config.Cfg, *gitalypb.Repository, string, gitalypb.OperationServiceClient) { - cfg := testcfg.Build(t) - ctx, cfg, repo, repoPath, client := setupOperationsServiceWithCfg(t, ctx, cfg, options...) +func setupOperationsService(tb testing.TB, ctx context.Context, options ...testserver.GitalyServerOpt) (context.Context, config.Cfg, *gitalypb.Repository, string, gitalypb.OperationServiceClient) { + cfg := testcfg.Build(tb) + ctx, cfg, repo, repoPath, client := setupOperationsServiceWithCfg(tb, ctx, cfg, options...) return ctx, cfg, repo, repoPath, client } func setupOperationsServiceWithCfg( - t testing.TB, ctx context.Context, cfg config.Cfg, options ...testserver.GitalyServerOpt, + tb testing.TB, ctx context.Context, cfg config.Cfg, options ...testserver.GitalyServerOpt, ) (context.Context, config.Cfg, *gitalypb.Repository, string, gitalypb.OperationServiceClient) { - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyGit2Go(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(tb, cfg) + testcfg.BuildGitalyGit2Go(tb, cfg) + testcfg.BuildGitalyHooks(tb, cfg) - serverSocketPath := runOperationServiceServer(t, cfg, options...) + serverSocketPath := runOperationServiceServer(tb, cfg, options...) cfg.SocketPath = serverSocketPath - client, conn := newOperationClient(t, serverSocketPath) - t.Cleanup(func() { conn.Close() }) + client, conn := newOperationClient(tb, serverSocketPath) + tb.Cleanup(func() { conn.Close() }) - md := testcfg.GitalyServersMetadataFromCfg(t, cfg) + md := testcfg.GitalyServersMetadataFromCfg(tb, cfg) ctx = testhelper.MergeOutgoingMetadata(ctx, md) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -65,30 +68,30 @@ func setupOperationsServiceWithCfg( } func setupOperationsServiceWithoutRepo( - t testing.TB, ctx context.Context, options ...testserver.GitalyServerOpt, + tb testing.TB, ctx context.Context, options ...testserver.GitalyServerOpt, ) (context.Context, config.Cfg, gitalypb.OperationServiceClient) { - cfg := testcfg.Build(t) + cfg := testcfg.Build(tb) - testcfg.BuildGitalySSH(t, cfg) - testcfg.BuildGitalyGit2Go(t, cfg) - testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(tb, cfg) + testcfg.BuildGitalyGit2Go(tb, cfg) + testcfg.BuildGitalyHooks(tb, cfg) - serverSocketPath := runOperationServiceServer(t, cfg, options...) + serverSocketPath := runOperationServiceServer(tb, cfg, options...) cfg.SocketPath = serverSocketPath - client, conn := newOperationClient(t, serverSocketPath) - t.Cleanup(func() { conn.Close() }) + client, conn := newOperationClient(tb, serverSocketPath) + tb.Cleanup(func() { conn.Close() }) - md := testcfg.GitalyServersMetadataFromCfg(t, cfg) + md := testcfg.GitalyServersMetadataFromCfg(tb, cfg) ctx = testhelper.MergeOutgoingMetadata(ctx, md) return ctx, cfg, client } -func runOperationServiceServer(t testing.TB, cfg config.Cfg, options ...testserver.GitalyServerOpt) string { - t.Helper() +func runOperationServiceServer(tb testing.TB, cfg config.Cfg, options ...testserver.GitalyServerOpt) string { + tb.Helper() - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + return testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { operationServer := NewServer( deps.GetHookManager(), deps.GetTxManager(), @@ -101,7 +104,7 @@ func runOperationServiceServer(t testing.TB, cfg config.Cfg, options ...testserv ) gitalypb.RegisterOperationServiceServer(srv, operationServer) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( deps.GetCfg(), nil, @@ -133,13 +136,13 @@ func runOperationServiceServer(t testing.TB, cfg config.Cfg, options ...testserv }, options...) } -func newOperationClient(t testing.TB, serverSocketPath string) (gitalypb.OperationServiceClient, *grpc.ClientConn) { +func newOperationClient(tb testing.TB, serverSocketPath string) (gitalypb.OperationServiceClient, *grpc.ClientConn) { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) if err != nil { - t.Fatal(err) + tb.Fatal(err) } return gitalypb.NewOperationServiceClient(conn), conn @@ -152,8 +155,8 @@ func newMuxedOperationClient(t *testing.T, ctx context.Context, serverSocketPath return gitalypb.NewOperationServiceClient(conn) } -func setupAndStartGitlabServer(t testing.TB, glID, glRepository string, cfg config.Cfg, gitPushOptions ...string) string { - url, cleanup := gitlab.SetupAndStartGitlabServer(t, cfg.GitlabShell.Dir, &gitlab.TestServerOptions{ +func setupAndStartGitlabServer(tb testing.TB, glID, glRepository string, cfg config.Cfg, gitPushOptions ...string) string { + url, cleanup := gitlab.SetupAndStartGitlabServer(tb, cfg.GitlabShell.Dir, &gitlab.TestServerOptions{ SecretToken: "secretToken", GLID: glID, GLRepository: glRepository, @@ -162,7 +165,7 @@ func setupAndStartGitlabServer(t testing.TB, glID, glRepository string, cfg conf GitPushOptions: gitPushOptions, }) - t.Cleanup(cleanup) + tb.Cleanup(cleanup) return url } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_branches_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_branches_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_branches_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_branches_test.go index 1ea5701fa7..3cffdd11a5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_branches_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_branches_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -50,7 +52,7 @@ func TestSuccessfulUserUpdateBranchRequest(t *testing.T) { { desc: "short name branch creation", updateBranchName: "a-new-branch", - oldRev: []byte(git.ZeroOID.String()), + oldRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), newRev: []byte("845009f4d7bdc9e0d8f26b1c6fb6e108aaff9314"), }, // We create refs/heads/heads/BRANCH and @@ -60,13 +62,13 @@ func TestSuccessfulUserUpdateBranchRequest(t *testing.T) { { desc: "heads/* branch creation", updateBranchName: "heads/a-new-branch", - oldRev: []byte(git.ZeroOID.String()), + oldRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), newRev: []byte("845009f4d7bdc9e0d8f26b1c6fb6e108aaff9314"), }, { desc: "refs/heads/* branch creation", updateBranchName: "refs/heads/a-new-branch", - oldRev: []byte(git.ZeroOID.String()), + oldRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), newRev: []byte("845009f4d7bdc9e0d8f26b1c6fb6e108aaff9314"), }, } @@ -116,7 +118,7 @@ func TestSuccessfulUserUpdateBranchRequestToDelete(t *testing.T) { desc: "short name branch deletion", updateBranchName: "csv", oldRev: []byte("3dd08961455abf80ef9115f4afdc1c6f968b503c"), - newRev: []byte(git.ZeroOID.String()), + newRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), err: status.Error(codes.InvalidArgument, "object not found"), }, // We test for the failed heads/* and refs/heads/* cases below in TestFailedUserUpdateBranchRequest @@ -125,7 +127,7 @@ func TestSuccessfulUserUpdateBranchRequestToDelete(t *testing.T) { updateBranchName: "heads/my-test-branch", createBranch: true, oldRev: []byte("689600b91aabec706e657e38ea706ece1ee8268f"), - newRev: []byte(git.ZeroOID.String()), + newRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), err: status.Error(codes.InvalidArgument, "object not found"), }, { @@ -133,7 +135,7 @@ func TestSuccessfulUserUpdateBranchRequestToDelete(t *testing.T) { updateBranchName: "refs/heads/my-other-test-branch", createBranch: true, oldRev: []byte("db46a1c5a5e474aa169b6cdb7a522d891bc4c5f9"), - newRev: []byte(git.ZeroOID.String()), + newRev: []byte(git.ObjectHashSHA1.ZeroOID.String()), err: status.Error(codes.InvalidArgument, "object not found"), }, } @@ -296,7 +298,7 @@ func TestFailedUserUpdateBranchRequest(t *testing.T) { { desc: "existing branch failed deletion attempt", branchName: "csv", - newrev: []byte(git.ZeroOID.String()), + newrev: []byte(git.ObjectHashSHA1.ZeroOID.String()), oldrev: oldrev, gotrev: []byte("3dd08961455abf80ef9115f4afdc1c6f968b503c"), user: gittest.TestUser, @@ -330,7 +332,7 @@ func TestFailedUserUpdateBranchRequest(t *testing.T) { { desc: "delete existing branch, but unsupported refs/heads/* name", branchName: "refs/heads/crlf-diff", - newrev: []byte(git.ZeroOID.String()), + newrev: []byte(git.ObjectHashSHA1.ZeroOID.String()), oldrev: []byte("593890758a6f845c600f38ffa05be2749211caee"), user: gittest.TestUser, err: status.Errorf(codes.FailedPrecondition, "Could not update %v. Please refresh and try again.", "refs/heads/crlf-diff"), @@ -339,7 +341,7 @@ func TestFailedUserUpdateBranchRequest(t *testing.T) { desc: "short name branch deletion", branchName: "csv", oldrev: []byte("3dd08961455abf80ef9115f4afdc1c6f968b503c"), - newrev: []byte(git.ZeroOID.String()), + newrev: []byte(git.ObjectHashSHA1.ZeroOID.String()), expectNotFoundError: true, user: gittest.TestUser, err: nil, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_with_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_with_hooks.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_with_hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_with_hooks.go index 10aa7f6d02..4d94909363 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/update_with_hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/update_with_hooks.go @@ -3,9 +3,9 @@ package operations import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *Server) updateReferenceWithHooks( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils.go index 9953fe4dbc..2052c9b3d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils_test.go index 2745ccabfb..4889814284 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations/utils_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations/utils_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package operations import ( @@ -6,7 +8,7 @@ import ( "time" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches.go index 0f12bcdbba..71daec916b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches_test.go index 3e7088fda9..f96fea503d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/branches_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/branches_test.go @@ -1,13 +1,15 @@ +//go:build !gitaly_test_sha256 + package ref import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs.go index 1d3a121f72..f8d7a7f03a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs.go @@ -6,13 +6,14 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -38,8 +39,41 @@ func (s *server) DeleteRefs(ctx context.Context, in *gitalypb.DeleteRefsRequest) } voteHash := voting.NewVoteHash() + + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) { + var invalidRefnames [][]byte + + for _, ref := range refnames { + if err := git.ValidateRevision([]byte(ref)); err != nil { + invalidRefnames = append(invalidRefnames, []byte(ref)) + } + } + + if len(invalidRefnames) > 0 { + detailedErr, err := helper.ErrWithDetails( + helper.ErrInvalidArgumentf("invalid references"), + &gitalypb.DeleteRefsError{ + Error: &gitalypb.DeleteRefsError_InvalidFormat{ + InvalidFormat: &gitalypb.InvalidRefFormatError{ + Refs: invalidRefnames, + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } + } + for _, ref := range refnames { if err := updater.Delete(ref); err != nil { + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) { + return nil, helper.ErrInternalf("unable to delete refs: %w", err) + } + return &gitalypb.DeleteRefsResponse{GitError: err.Error()}, nil } @@ -49,6 +83,26 @@ func (s *server) DeleteRefs(ctx context.Context, in *gitalypb.DeleteRefsRequest) } if err := updater.Prepare(); err != nil { + var errAlreadyLocked *updateref.ErrAlreadyLocked + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) && + errors.As(err, &errAlreadyLocked) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("cannot lock references"), + &gitalypb.DeleteRefsError{ + Error: &gitalypb.DeleteRefsError_ReferencesLocked{ + ReferencesLocked: &gitalypb.ReferencesLockedError{ + Refs: [][]byte{[]byte(errAlreadyLocked.Ref)}, + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr + } + return &gitalypb.DeleteRefsResponse{ GitError: fmt.Sprintf("unable to delete refs: %s", err.Error()), }, nil @@ -68,10 +122,10 @@ func (s *server) DeleteRefs(ctx context.Context, in *gitalypb.DeleteRefsRequest) } if err := updater.Commit(); err != nil { - // TODO: We should be able to easily drop this error here and return a real error as - // soon as we always use proper locking semantics in git-update-ref(1). All locking - // issues would be catched when `Prepare()`ing the changes already, so a fail - // afterwards would hint at a real unexpected error. + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) { + return nil, helper.ErrInternalf("unable to commit: %w", err) + } + return &gitalypb.DeleteRefsResponse{GitError: fmt.Sprintf("unable to delete refs: %s", err.Error())}, nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs_test.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs_test.go index b07c760092..a821999f70 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/delete_refs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/delete_refs_test.go @@ -1,30 +1,43 @@ +//go:build !gitaly_test_sha256 + package ref import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) func TestDeleteRefs_successful(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + testhelper.NewFeatureSets(featureflag.DeleteRefsStructuredErrors).Run( + t, + testDeleteRefSuccessful, + ) +} + +func testDeleteRefSuccessful(t *testing.T, ctx context.Context) { cfg, client := setupRefServiceWithoutRepo(t) testCases := []struct { @@ -80,8 +93,14 @@ func TestDeleteRefs_successful(t *testing.T) { func TestDeleteRefs_transaction(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + testhelper.NewFeatureSets(featureflag.DeleteRefsStructuredErrors).Run( + t, + testDeleteRefsTransaction, + ) +} + +func testDeleteRefsTransaction(t *testing.T, ctx context.Context) { cfg := testcfg.Build(t) testcfg.BuildGitalyHooks(t, cfg) @@ -106,7 +125,7 @@ func TestDeleteRefs_transaction(t *testing.T) { deps.GetGit2goExecutor(), deps.GetHousekeepingManager(), )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) }, testserver.WithTransactionManager(txManager)) cfg.SocketPath = addr @@ -156,19 +175,95 @@ func TestDeleteRefs_transaction(t *testing.T) { func TestDeleteRefs_invalidRefFormat(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + testhelper.NewFeatureSets(featureflag.DeleteRefsStructuredErrors).Run( + t, + testDeleteRefsInvalidRefFormat, + ) +} + +func testDeleteRefsInvalidRefFormat(t *testing.T, ctx context.Context) { _, repo, _, client := setupRefService(ctx, t) request := &gitalypb.DeleteRefsRequest{ Repository: repo, - Refs: [][]byte{[]byte(`refs\tails\invalid-ref-format`)}, + Refs: [][]byte{[]byte(`refs invalid-ref-format`)}, } response, err := client.DeleteRefs(ctx, request) + + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) { + require.Nil(t, response) + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrInvalidArgumentf("invalid references"), + &gitalypb.DeleteRefsError{ + Error: &gitalypb.DeleteRefsError_InvalidFormat{ + InvalidFormat: &gitalypb.InvalidRefFormatError{ + Refs: request.Refs, + }, + }, + }) + require.NoError(t, errGeneratingDetailedErr) + testhelper.RequireGrpcError(t, detailedErr, err) + } else { + require.NoError(t, err) + assert.Contains(t, response.GitError, "invalid ref format") + } +} + +func TestDeleteRefs_refLocked(t *testing.T) { + t.Parallel() + + testhelper.NewFeatureSets(featureflag.DeleteRefsStructuredErrors).Run( + t, + testDeleteRefsRefLocked, + ) +} + +func testDeleteRefsRefLocked(t *testing.T, ctx context.Context) { + cfg, repoProto, _, client := setupRefService(ctx, t) + + if !gittest.GitSupportsStatusFlushing(t, ctx, cfg) { + t.Skip("git does not support flushing yet, which is known to be flaky") + } + + request := &gitalypb.DeleteRefsRequest{ + Repository: repoProto, + Refs: [][]byte{[]byte("refs/heads/master")}, + } + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + oldValue, err := repo.ResolveRevision(ctx, git.Revision("refs/heads/master")) require.NoError(t, err) - assert.Contains(t, response.GitError, "unable to delete refs") + updater, err := updateref.New(ctx, repo) + require.NoError(t, err) + require.NoError(t, updater.Update( + git.ReferenceName("refs/heads/master"), + "0b4bc9a49b562e85de7cc9e834518ea6828729b9", + oldValue, + )) + require.NoError(t, updater.Prepare()) + + response, err := client.DeleteRefs(ctx, request) + + if featureflag.DeleteRefsStructuredErrors.IsEnabled(ctx) { + require.Nil(t, response) + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("cannot lock references"), + &gitalypb.DeleteRefsError{ + Error: &gitalypb.DeleteRefsError_ReferencesLocked{ + ReferencesLocked: &gitalypb.ReferencesLockedError{ + Refs: [][]byte{[]byte("refs/heads/master")}, + }, + }, + }) + require.NoError(t, errGeneratingDetailedErr) + testhelper.RequireGrpcError(t, detailedErr, err) + } else { + require.NoError(t, err) + assert.Contains(t, response.GetGitError(), "reference is already locked") + } } func TestDeleteRefs_validation(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags.go index 4bfb2d0e9c..551083b308 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags.go @@ -7,12 +7,12 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -40,10 +40,11 @@ func (s *server) FindAllTags(in *gitalypb.FindAllTagsRequest, stream gitalypb.Re } func (s *server) findAllTags(ctx context.Context, repo *localrepo.Repo, sortField string, stream gitalypb.RefService_FindAllTagsServer, opts *paginationOpts) error { - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return fmt.Errorf("error creating object reader: %v", err) } + defer cancel() forEachRefIter := gitpipe.ForEachRef( ctx, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags_test.go index 487790b7d0..d025afefe5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_all_tags_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_all_tags_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -9,18 +11,16 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" @@ -96,12 +96,7 @@ func TestFindAllTags_successful(t *testing.T) { TargetCommit: gitCommit, Message: []byte("commit tag with a commit sha as the name"), MessageSize: 40, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Tagger: gittest.DefaultCommitAuthor, }, { Name: []byte("tag-of-tag"), @@ -109,12 +104,7 @@ func TestFindAllTags_successful(t *testing.T) { TargetCommit: gitCommit, Message: []byte("tag of a tag"), MessageSize: 12, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Tagger: gittest.DefaultCommitAuthor, }, { Name: []byte("v1.0.0"), @@ -163,8 +153,8 @@ func TestFindAllTags_successful(t *testing.T) { Message: truncatedPGPTagMsg[146:10386], // first 10240 bytes of tag message MessageSize: 11148, Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), + Name: []byte(gittest.DefaultCommitterName), + Email: []byte(gittest.DefaultCommitterMail), Date: ×tamppb.Timestamp{Seconds: 1393491261}, Timezone: []byte("+0100"), }, @@ -175,12 +165,7 @@ func TestFindAllTags_successful(t *testing.T) { Id: annotatedTagID.String(), Message: []byte("Blob tag"), MessageSize: 8, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Tagger: gittest.DefaultCommitAuthor, }, { Name: []byte("v1.3.0"), @@ -207,12 +192,7 @@ func TestFindAllTags_successful(t *testing.T) { Message: []byte(bigMessage[:helper.MaxCommitOrTagMessageSize]), MessageSize: int64(len(bigMessage)), TargetCommit: gitCommit, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Tagger: gittest.DefaultCommitAuthor, }, } @@ -226,9 +206,7 @@ func TestFindAllTags_simpleNestedTags(t *testing.T) { repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) - commitID := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithParents(), - ) + commitID := gittest.WriteCommit(t, cfg, repoPath) tagID := gittest.WriteTag(t, cfg, repoPath, "my/nested/tag", commitID.Revision()) @@ -243,23 +221,13 @@ func TestFindAllTags_simpleNestedTags(t *testing.T) { Name: []byte("my/nested/tag"), Id: tagID.String(), TargetCommit: &gitalypb.GitCommit{ - Id: commitID.String(), - Body: []byte("message"), - BodySize: 7, - Subject: []byte("message"), - TreeId: git.EmptyTreeOID.String(), - Author: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Id: commitID.String(), + Body: []byte("message"), + BodySize: 7, + Subject: []byte("message"), + TreeId: git.ObjectHashSHA1.EmptyTreeOID.String(), + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, }, }, }, @@ -278,7 +246,7 @@ func TestFindAllTags_duplicateAnnotatedTags(t *testing.T) { repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) repo := localrepo.NewTestRepo(t, cfg, repoProto) - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, repoPath) date := time.Unix(12345, 0) dateOffset := date.Format("-0700") @@ -286,10 +254,10 @@ func TestFindAllTags_duplicateAnnotatedTags(t *testing.T) { gittest.TestUser, date) require.NoError(t, err) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated", tagID, git.ZeroOID)) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated-dup", tagID, git.ZeroOID)) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/lightweight-1", commitID, git.ZeroOID)) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/lightweight-2", commitID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated", tagID, git.ObjectHashSHA1.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated-dup", tagID, git.ObjectHashSHA1.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/lightweight-1", commitID, git.ObjectHashSHA1.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/lightweight-2", commitID, git.ObjectHashSHA1.ZeroOID)) c, err := client.FindAllTags(ctx, &gitalypb.FindAllTagsRequest{Repository: repoProto}) require.NoError(t, err) @@ -304,20 +272,14 @@ func TestFindAllTags_duplicateAnnotatedTags(t *testing.T) { receivedTags = append(receivedTags, r.GetTags()...) } - commitAuthor := &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - } commit := &gitalypb.GitCommit{ Id: commitID.String(), TreeId: "4b825dc642cb6eb9a060e54bf8d69288fbee4904", Body: []byte("message"), BodySize: 7, Subject: []byte("message"), - Author: commitAuthor, - Committer: commitAuthor, + Author: gittest.DefaultCommitAuthor, + Committer: gittest.DefaultCommitAuthor, } testhelper.ProtoEqual(t, []*gitalypb.Tag{ @@ -403,11 +365,13 @@ func TestFindAllTags_nestedTags(t *testing.T) { catfileCache := catfile.NewCache(cfg) defer catfileCache.Stop() - objectReader, err := catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) require.NoError(t, err) + defer cancel() - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) require.NoError(t, err) + defer cancel() info, err := objectInfoReader.Info(ctx, git.Revision(tc.originalOid)) require.NoError(t, err) @@ -425,12 +389,7 @@ func TestFindAllTags_nestedTags(t *testing.T) { Id: tagID.String(), Message: []byte(tagMessage), MessageSize: int64(len([]byte(tagMessage))), - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, + Tagger: gittest.DefaultCommitAuthor, } if info.Type == "commit" { @@ -459,7 +418,7 @@ func TestFindAllTags_nestedTags(t *testing.T) { require.Len(t, receivedTags, len(expectedTags)) for _, receivedTag := range receivedTags { - assert.Equal(t, expectedTags[string(receivedTag.Name)], receivedTag) + testhelper.ProtoEqual(t, expectedTags[string(receivedTag.Name)], receivedTag) } }) } @@ -504,10 +463,7 @@ func TestFindAllTags_invalidRequest(t *testing.T) { } func TestFindAllTags_pagination(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindAllTagsPagination) -} - -func testFindAllTagsPagination(t *testing.T, ctx context.Context) { + ctx := testhelper.Context(t) cfg, repoProto, repoPath, client := setupRefService(ctx, t) catfileCache := catfile.NewCache(cfg) @@ -561,15 +517,7 @@ func testFindAllTagsPagination(t *testing.T, ctx context.Context) { paginationParams: &gitalypb.PaginationParameter{Limit: 3, PageToken: "refs/tags/v1.0.0"}, sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_REFNAME, Direction: gitalypb.SortDirection_DESCENDING}, expected: func(context.Context) ([]string, error) { - if featureflag.ExactPaginationTokenMatch.IsEnabled(ctx) { - return []string{ - annotatedTagID.String(), - }, nil - } - return []string{ - "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", annotatedTagID.String(), }, nil }, @@ -585,14 +533,7 @@ func testFindAllTagsPagination(t *testing.T, ctx context.Context) { desc: "with invalid page token", paginationParams: &gitalypb.PaginationParameter{Limit: 3, PageToken: "refs/tags/invalid"}, expected: func(ctx context.Context) ([]string, error) { - if featureflag.ExactPaginationTokenMatch.IsEnabled(ctx) { - return nil, helper.ErrInvalidArgumentf("could not find page token") - } - - return []string{ - "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - "8f03acbcd11c53d9c9468078f32a2622005a4841", - }, nil + return nil, helper.ErrInvalidArgumentf("could not find page token") }, }, } { @@ -638,49 +579,81 @@ func TestFindAllTags_sorted(t *testing.T) { require.NoError(t, err) annotatedTagID, err := repo.WriteTag(ctx, git.ObjectID(headCommit.Id), "commit", []byte("annotated"), []byte("message"), gittest.TestUser, time.Now()) require.NoError(t, err) - require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated", annotatedTagID, git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, "refs/tags/annotated", annotatedTagID, git.ObjectHashSHA1.ZeroOID)) require.NoError(t, repo.ExecAndWait(ctx, git.SubCmd{ Name: "tag", - Args: []string{"not-annotated", headCommit.Id}, + Args: []string{"v1.2.0", headCommit.Id}, + }, git.WithDisabledHooks())) + + require.NoError(t, repo.ExecAndWait(ctx, git.SubCmd{ + Name: "tag", + Args: []string{"v1.10.0", headCommit.Id}, }, git.WithDisabledHooks())) for _, tc := range []struct { desc string sortBy *gitalypb.FindAllTagsRequest_SortBy - exp []string + exp map[string]string }{ { desc: "by name", sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_REFNAME}, - exp: []string{ - annotatedTagID.String(), - headCommit.Id, - "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", - "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - "8f03acbcd11c53d9c9468078f32a2622005a4841", + exp: map[string]string{ + "annotated": annotatedTagID.String(), + "v1.0.0": "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + "v1.1.0": "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + "v1.1.1": "8f03acbcd11c53d9c9468078f32a2622005a4841", + "v1.10.0": headCommit.Id, + "v1.2.0": headCommit.Id, + }, + }, + { + desc: "by semantic name in ascending order", + sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_VERSION_REFNAME, Direction: gitalypb.SortDirection_ASCENDING}, + exp: map[string]string{ + "annotated": annotatedTagID.String(), + "v1.0.0": "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + "v1.1.0": "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + "v1.1.1": "8f03acbcd11c53d9c9468078f32a2622005a4841", + "v1.2.0": headCommit.Id, + "v1.10.0": headCommit.Id, + }, + }, + { + desc: "by semantic name in descending order", + sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_VERSION_REFNAME, Direction: gitalypb.SortDirection_DESCENDING}, + exp: map[string]string{ + "v1.10.0": headCommit.Id, + "v1.2.0": headCommit.Id, + "v1.1.1": "8f03acbcd11c53d9c9468078f32a2622005a4841", + "v1.1.0": "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + "v1.0.0": "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + "annotated": annotatedTagID.String(), }, }, { desc: "by updated in ascending order", sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_CREATORDATE, Direction: gitalypb.SortDirection_ASCENDING}, - exp: []string{ - "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", - "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - headCommit.Id, - "8f03acbcd11c53d9c9468078f32a2622005a4841", - annotatedTagID.String(), + exp: map[string]string{ + "v1.0.0": "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + "v1.1.0": "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + "v1.10.0": headCommit.Id, + "v1.2.0": headCommit.Id, + "v1.1.1": "8f03acbcd11c53d9c9468078f32a2622005a4841", + "annotated": annotatedTagID.String(), }, }, { desc: "by updated in descending order", sortBy: &gitalypb.FindAllTagsRequest_SortBy{Key: gitalypb.FindAllTagsRequest_SortBy_CREATORDATE, Direction: gitalypb.SortDirection_DESCENDING}, - exp: []string{ - annotatedTagID.String(), - "8f03acbcd11c53d9c9468078f32a2622005a4841", - headCommit.Id, - "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + exp: map[string]string{ + "annotated": annotatedTagID.String(), + "v1.1.0": "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + "v1.10.0": headCommit.Id, + "v1.2.0": headCommit.Id, + "v1.1.1": "8f03acbcd11c53d9c9468078f32a2622005a4841", + "v1.0.0": "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", }, }, } { @@ -691,7 +664,7 @@ func TestFindAllTags_sorted(t *testing.T) { }) require.NoError(t, err) - var tags []string + tags := make(map[string]string) for { r, err := c.Recv() if err == io.EOF { @@ -699,7 +672,7 @@ func TestFindAllTags_sorted(t *testing.T) { } require.NoError(t, err) for _, tag := range r.GetTags() { - tags = append(tags, tag.Id) + tags[string(tag.Name)] = tag.Id } } @@ -749,7 +722,9 @@ func BenchmarkFindAllTags(b *testing.B) { cfg, client := setupRefServiceWithoutRepo(b) - repoProto, repoPath := gittest.CloneRepo(b, cfg, cfg.Storages[0]) + repoProto, repoPath := gittest.CreateRepository(ctx, b, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) for i := 0; i < 1000; i++ { gittest.WriteTag(b, cfg, repoPath, fmt.Sprintf("%d", i), "HEAD", gittest.WriteTagConfig{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid.go index 13443dffc0..520acb3fa9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid.go @@ -5,9 +5,9 @@ import ( "errors" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FindRefsByOID(ctx context.Context, in *gitalypb.FindRefsByOIDRequest) (*gitalypb.FindRefsByOIDResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid_test.go index 8d657ce978..cf50884a6e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/find_refs_by_oid_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_refs_by_oid_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -7,10 +9,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag.go new file mode 100644 index 0000000000..b23b50b3e1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag.go @@ -0,0 +1,139 @@ +package ref + +import ( + "bufio" + "context" + "errors" + "fmt" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func (s *server) FindTag(ctx context.Context, in *gitalypb.FindTagRequest) (*gitalypb.FindTagResponse, error) { + if err := s.validateFindTagRequest(in); err != nil { + return nil, helper.ErrInvalidArgument(err) + } + + repo := s.localrepo(in.GetRepository()) + + tag, err := s.findTag(ctx, repo, in.GetTagName()) + if err != nil { + return nil, helper.ErrInternal(err) + } + + return &gitalypb.FindTagResponse{Tag: tag}, nil +} + +// parseTagLine parses a line of text with the output format %(objectname) %(objecttype) %(refname:lstrip=2) +func parseTagLine(ctx context.Context, objectReader catfile.ObjectReader, tagLine string) (*gitalypb.Tag, error) { + fields := strings.SplitN(tagLine, " ", 3) + if len(fields) != 3 { + return nil, fmt.Errorf("invalid output from for-each-ref command: %v", tagLine) + } + + tagID, refType, refName := fields[0], fields[1], fields[2] + + tag := &gitalypb.Tag{ + Id: tagID, + Name: []byte(refName), + } + + switch refType { + // annotated tag + case "tag": + tag, err := catfile.GetTag(ctx, objectReader, git.Revision(tagID), refName) + if err != nil { + return nil, fmt.Errorf("getting annotated tag: %v", err) + } + catfile.TrimTagMessage(tag) + + return tag, nil + case "commit": + commit, err := catfile.GetCommit(ctx, objectReader, git.Revision(tagID)) + if err != nil { + return nil, fmt.Errorf("getting commit catfile: %v", err) + } + tag.TargetCommit = commit + return tag, nil + default: + return tag, nil + } +} + +func (s *server) findTag(ctx context.Context, repo git.RepositoryExecutor, tagName []byte) (*gitalypb.Tag, error) { + tagCmd, err := repo.Exec(ctx, + git.SubCmd{ + Name: "tag", + Flags: []git.Option{ + git.Flag{Name: "-l"}, git.ValueFlag{Name: "--format", Value: tagFormat}, + }, + Args: []string{string(tagName)}, + }, + git.WithRefTxHook(repo), + ) + if err != nil { + return nil, fmt.Errorf("for-each-ref error: %v", err) + } + + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) + if err != nil { + return nil, err + } + defer cancel() + + var tag *gitalypb.Tag + + scanner := bufio.NewScanner(tagCmd) + if scanner.Scan() { + tag, err = parseTagLine(ctx, objectReader, scanner.Text()) + if err != nil { + return nil, err + } + } else { + if featureflag.FindTagStructuredError.IsEnabled(ctx) { + detailedErr, err := helper.ErrWithDetails( + helper.ErrNotFoundf("tag does not exist"), + &gitalypb.FindTagError{ + Error: &gitalypb.FindTagError_TagNotFound{ + TagNotFound: &gitalypb.ReferenceNotFoundError{ + ReferenceName: []byte(fmt.Sprintf("refs/tags/%s", tagName)), + }, + }, + }, + ) + if err != nil { + return nil, helper.ErrInternalf("generating detailed error: %w", err) + } + + return nil, detailedErr + } + + return nil, errors.New("no tag found") + } + + if err = tagCmd.Wait(); err != nil { + return nil, err + } + + return tag, nil +} + +func (s *server) validateFindTagRequest(in *gitalypb.FindTagRequest) error { + if in.GetRepository() == nil { + return errors.New("repository is empty") + } + + if _, err := s.locator.GetRepoPath(in.GetRepository()); err != nil { + return fmt.Errorf("invalid git directory: %v", err) + } + + if in.GetTagName() == nil { + return errors.New("tag name is empty") + } + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag_test.go new file mode 100644 index 0000000000..aeeaf9c564 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/find_tag_test.go @@ -0,0 +1,336 @@ +//go:build !gitaly_test_sha256 + +package ref + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestFindTag_successful(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, repoProto, repoPath, client := setupRefService(ctx, t) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") + commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") + + gitCommit := testhelper.GitLabTestCommit(commitID.String()) + + bigCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch("local-big-commits"), + gittest.WithMessage("An empty commit with REALLY BIG message\n\n"+strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1)), + gittest.WithParents("60ecb67744cb56576c30214ff52294f8ce2def98"), + ) + bigCommit, err := repo.ReadCommit(ctx, git.Revision(bigCommitID)) + require.NoError(t, err) + + annotatedTagID := gittest.WriteTag(t, cfg, repoPath, "v1.2.0", blobID.Revision(), gittest.WriteTagConfig{Message: "Blob tag"}) + + gittest.WriteTag(t, cfg, repoPath, "v1.3.0", commitID.Revision()) + gittest.WriteTag(t, cfg, repoPath, "v1.4.0", blobID.Revision()) + + // To test recursive resolving to a commit + gittest.WriteTag(t, cfg, repoPath, "v1.5.0", "v1.3.0") + + // A tag to commit with a big message + gittest.WriteTag(t, cfg, repoPath, "v1.6.0", bigCommitID.Revision()) + + // A tag with a big message + bigMessage := strings.Repeat("a", 11*1024) + bigMessageTag1ID := gittest.WriteTag(t, cfg, repoPath, "v1.7.0", commitID.Revision(), gittest.WriteTagConfig{Message: bigMessage}) + + // A tag with a commit id as its name + commitTagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision(), gittest.WriteTagConfig{Message: "commit tag with a commit sha as the name"}) + + // a tag of a tag + tagOfTagID := gittest.WriteTag(t, cfg, repoPath, "tag-of-tag", commitTagID.Revision(), gittest.WriteTagConfig{Message: "tag of a tag"}) + + expectedTags := []*gitalypb.Tag{ + { + Name: []byte(commitID), + Id: commitTagID.String(), + TargetCommit: gitCommit, + Message: []byte("commit tag with a commit sha as the name"), + MessageSize: 40, + Tagger: gittest.DefaultCommitAuthor, + }, + { + Name: []byte("tag-of-tag"), + Id: tagOfTagID.String(), + TargetCommit: gitCommit, + Message: []byte("tag of a tag"), + MessageSize: 12, + Tagger: gittest.DefaultCommitAuthor, + }, + { + Name: []byte("v1.0.0"), + Id: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", + TargetCommit: gitCommit, + Message: []byte("Release"), + MessageSize: 7, + Tagger: &gitalypb.CommitAuthor{ + Name: []byte("Dmitriy Zaporozhets"), + Email: []byte("dmitriy.zaporozhets@gmail.com"), + Date: ×tamppb.Timestamp{Seconds: 1393491299}, + Timezone: []byte("+0200"), + }, + SignatureType: gitalypb.SignatureType_NONE, + }, + { + Name: []byte("v1.1.0"), + Id: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", + TargetCommit: testhelper.GitLabTestCommit("5937ac0a7beb003549fc5fd26fc247adbce4a52e"), + Message: []byte("Version 1.1.0"), + MessageSize: 13, + Tagger: &gitalypb.CommitAuthor{ + Name: []byte("Dmitriy Zaporozhets"), + Email: []byte("dmitriy.zaporozhets@gmail.com"), + Date: ×tamppb.Timestamp{Seconds: 1393505709}, + Timezone: []byte("+0200"), + }, + }, + { + Name: []byte("v1.1.1"), + Id: "8f03acbcd11c53d9c9468078f32a2622005a4841", + TargetCommit: testhelper.GitLabTestCommit("189a6c924013fc3fe40d6f1ec1dc20214183bc97"), + Message: []byte("x509 signed tag\n-----BEGIN SIGNED MESSAGE-----\nMIISfwYJKoZIhvcNAQcCoIIScDCCEmwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI\nhvcNAQcBoIIP8zCCB3QwggVcoAMCAQICBBXXLOIwDQYJKoZIhvcNAQELBQAwgbYx\nCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVu\nMRAwDgYDVQQKDAdTaWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwU\nU2llbWVucyBUcnVzdCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBD\nQSBNZWRpdW0gU3RyZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjAeFw0xNzAyMDMw\nNjU4MzNaFw0yMDAyMDMwNjU4MzNaMFsxETAPBgNVBAUTCFowMDBOV0RIMQ4wDAYD\nVQQqDAVSb2dlcjEOMAwGA1UEBAwFTWVpZXIxEDAOBgNVBAoMB1NpZW1lbnMxFDAS\nBgNVBAMMC01laWVyIFJvZ2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAuBNea/68ZCnHYQjpm/k3ZBG0wBpEKSwG6lk9CEQlSxsqVLQHAoAKBIlJm1in\nYVLcK/Sq1yhYJ/qWcY/M53DhK2rpPuhtrWJUdOUy8EBWO20F4bd4Fw9pO7jt8bme\nu33TSrK772vKjuppzB6SeG13Cs08H+BIeD106G27h7ufsO00pvsxoSDL+uc4slnr\npBL+2TAL7nSFnB9QHWmRIK27SPqJE+lESdb0pse11x1wjvqKy2Q7EjL9fpqJdHzX\nNLKHXd2r024TOORTa05DFTNR+kQEKKV96XfpYdtSBomXNQ44cisiPBJjFtYvfnFE\nwgrHa8fogn/b0C+A+HAoICN12wIDAQABo4IC4jCCAt4wHQYDVR0OBBYEFCF+gkUp\nXQ6xGc0kRWXuDFxzA14zMEMGA1UdEQQ8MDqgIwYKKwYBBAGCNxQCA6AVDBNyLm1l\naWVyQHNpZW1lbnMuY29tgRNyLm1laWVyQHNpZW1lbnMuY29tMA4GA1UdDwEB/wQE\nAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwgcoGA1UdHwSBwjCB\nvzCBvKCBuaCBtoYmaHR0cDovL2NoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBNi5j\ncmyGQWxkYXA6Ly9jbC5zaWVtZW5zLm5ldC9DTj1aWlpaWlpBNixMPVBLST9jZXJ0\naWZpY2F0ZVJldm9jYXRpb25MaXN0hklsZGFwOi8vY2wuc2llbWVucy5jb20vQ049\nWlpaWlpaQTYsbz1UcnVzdGNlbnRlcj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0\nMEUGA1UdIAQ+MDwwOgYNKwYBBAGhaQcCAgMBAzApMCcGCCsGAQUFBwIBFhtodHRw\nOi8vd3d3LnNpZW1lbnMuY29tL3BraS8wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW\ngBT4FV1HDGx3e3LEAheRaKK292oJRDCCAQQGCCsGAQUFBwEBBIH3MIH0MDIGCCsG\nAQUFBzAChiZodHRwOi8vYWguc2llbWVucy5jb20vcGtpP1paWlpaWkE2LmNydDBB\nBggrBgEFBQcwAoY1bGRhcDovL2FsLnNpZW1lbnMubmV0L0NOPVpaWlpaWkE2LEw9\nUEtJP2NBQ2VydGlmaWNhdGUwSQYIKwYBBQUHMAKGPWxkYXA6Ly9hbC5zaWVtZW5z\nLmNvbS9DTj1aWlpaWlpBNixvPVRydXN0Y2VudGVyP2NBQ2VydGlmaWNhdGUwMAYI\nKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLnBraS1zZXJ2aWNlcy5zaWVtZW5zLmNvbTAN\nBgkqhkiG9w0BAQsFAAOCAgEAXPVcX6vaEcszJqg5IemF9aFTlwTrX5ITNIpzcqG+\nkD5haOf2mZYLjl+MKtLC1XfmIsGCUZNb8bjP6QHQEI+2d6x/ZOqPq7Kd7PwVu6x6\nxZrkDjUyhUbUntT5+RBy++l3Wf6Cq6Kx+K8ambHBP/bu90/p2U8KfFAG3Kr2gI2q\nfZrnNMOxmJfZ3/sXxssgLkhbZ7hRa+MpLfQ6uFsSiat3vlawBBvTyHnoZ/7oRc8y\nqi6QzWcd76CPpMElYWibl+hJzKbBZUWvc71AzHR6i1QeZ6wubYz7vr+FF5Y7tnxB\nVz6omPC9XAg0F+Dla6Zlz3Awj5imCzVXa+9SjtnsidmJdLcKzTAKyDewewoxYOOJ\nj3cJU7VSjJPl+2fVmDBaQwcNcUcu/TPAKApkegqO7tRF9IPhjhW8QkRnkqMetO3D\nOXmAFVIsEI0Hvb2cdb7B6jSpjGUuhaFm9TCKhQtCk2p8JCDTuaENLm1x34rrJKbT\n2vzyYN0CZtSkUdgD4yQxK9VWXGEzexRisWb4AnZjD2NAquLPpXmw8N0UwFD7MSpC\ndpaX7FktdvZmMXsnGiAdtLSbBgLVWOD1gmJFDjrhNbI8NOaOaNk4jrfGqNh5lhGU\n4DnBT2U6Cie1anLmFH/oZooAEXR2o3Nu+1mNDJChnJp0ovs08aa3zZvBdcloOvfU\nqdowggh3MIIGX6ADAgECAgQtyi/nMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYDVQQG\nEwJERTEPMA0GA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UE\nCgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaQTExHTAbBgNVBAsMFFNpZW1lbnMg\nVHJ1c3QgQ2VudGVyMSIwIAYDVQQDDBlTaWVtZW5zIFJvb3QgQ0EgVjMuMCAyMDE2\nMB4XDTE2MDcyMDEzNDYxMFoXDTIyMDcyMDEzNDYxMFowgbYxCzAJBgNVBAYTAkRF\nMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVuMRAwDgYDVQQKDAdT\naWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwUU2llbWVucyBUcnVz\ndCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBDQSBNZWRpdW0gU3Ry\nZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAL9UfK+JAZEqVMVvECdYF9IK4KSw34AqyNl3rYP5x03dtmKaNu+2\n0fQqNESA1NGzw3s6LmrKLh1cR991nB2cvKOXu7AvEGpSuxzIcOROd4NpvRx+Ej1p\nJIPeqf+ScmVK7lMSO8QL/QzjHOpGV3is9sG+ZIxOW9U1ESooy4Hal6ZNs4DNItsz\npiCKqm6G3et4r2WqCy2RRuSqvnmMza7Y8BZsLy0ZVo5teObQ37E/FxqSrbDI8nxn\nB7nVUve5ZjrqoIGSkEOtyo11003dVO1vmWB9A0WQGDqE/q3w178hGhKfxzRaqzyi\nSoADUYS2sD/CglGTUxVq6u0pGLLsCFjItcCWqW+T9fPYfJ2CEd5b3hvqdCn+pXjZ\n/gdX1XAcdUF5lRnGWifaYpT9n4s4adzX8q6oHSJxTppuAwLRKH6eXALbGQ1I9lGQ\nDSOipD/09xkEsPw6HOepmf2U3YxZK1VU2sHqugFJboeLcHMzp6E1n2ctlNG1GKE9\nFDHmdyFzDi0Nnxtf/GgVjnHF68hByEE1MYdJ4nJLuxoT9hyjYdRW9MpeNNxxZnmz\nW3zh7QxIqP0ZfIz6XVhzrI9uZiqwwojDiM5tEOUkQ7XyW6grNXe75yt6mTj89LlB\nH5fOW2RNmCy/jzBXDjgyskgK7kuCvUYTuRv8ITXbBY5axFA+CpxZqokpAgMBAAGj\nggKmMIICojCCAQUGCCsGAQUFBwEBBIH4MIH1MEEGCCsGAQUFBzAChjVsZGFwOi8v\nYWwuc2llbWVucy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/Y0FDZXJ0aWZpY2F0ZTAy\nBggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBMS5j\ncnQwSgYIKwYBBQUHMAKGPmxkYXA6Ly9hbC5zaWVtZW5zLmNvbS91aWQ9WlpaWlpa\nQTEsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUFBzABhiRodHRw\nOi8vb2NzcC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wHwYDVR0jBBgwFoAUcG2g\nUOyp0CxnnRkV/v0EczXD4tQwEgYDVR0TAQH/BAgwBgEB/wIBADBABgNVHSAEOTA3\nMDUGCCsGAQQBoWkHMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuc2llbWVucy5j\nb20vcGtpLzCBxwYDVR0fBIG/MIG8MIG5oIG2oIGzhj9sZGFwOi8vY2wuc2llbWVu\ncy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3SG\nJmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTEuY3JshkhsZGFwOi8v\nY2wuc2llbWVucy5jb20vdWlkPVpaWlpaWkExLG89VHJ1c3RjZW50ZXI/YXV0aG9y\naXR5UmV2b2NhdGlvbkxpc3QwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsGAQUFBwME\nBggrBgEFBQcDCTAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPgVXUcMbHd7csQC\nF5Foorb3aglEMA0GCSqGSIb3DQEBCwUAA4ICAQBw+sqMp3SS7DVKcILEmXbdRAg3\nlLO1r457KY+YgCT9uX4VG5EdRKcGfWXK6VHGCi4Dos5eXFV34Mq/p8nu1sqMuoGP\nYjHn604eWDprhGy6GrTYdxzcE/GGHkpkuE3Ir/45UcmZlOU41SJ9SNjuIVrSHMOf\nccSY42BCspR/Q1Z/ykmIqQecdT3/Kkx02GzzSN2+HlW6cEO4GBW5RMqsvd2n0h2d\nfe2zcqOgkLtx7u2JCR/U77zfyxG3qXtcymoz0wgSHcsKIl+GUjITLkHfS9Op8V7C\nGr/dX437sIg5pVHmEAWadjkIzqdHux+EF94Z6kaHywohc1xG0KvPYPX7iSNjkvhz\n4NY53DHmxl4YEMLffZnaS/dqyhe1GTpcpyN8WiR4KuPfxrkVDOsuzWFtMSvNdlOV\ngdI0MXcLMP+EOeANZWX6lGgJ3vWyemo58nzgshKd24MY3w3i6masUkxJH2KvI7UH\n/1Db3SC8oOUjInvSRej6M3ZhYWgugm6gbpUgFoDw/o9Cg6Qm71hY0JtcaPC13rzm\nN8a2Br0+Fa5e2VhwLmAxyfe1JKzqPwuHT0S5u05SQghL5VdzqfA8FCL/j4XC9yI6\ncsZTAQi73xFQYVjZt3+aoSz84lOlTmVo/jgvGMY/JzH9I4mETGgAJRNj34Z/0meh\nM+pKWCojNH/dgyJSwDGCAlIwggJOAgEBMIG/MIG2MQswCQYDVQQGEwJERTEPMA0G\nA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UECgwHU2llbWVu\nczERMA8GA1UEBRMIWlpaWlpaQTYxHTAbBgNVBAsMFFNpZW1lbnMgVHJ1c3QgQ2Vu\ndGVyMT8wPQYDVQQDDDZTaWVtZW5zIElzc3VpbmcgQ0EgTWVkaXVtIFN0cmVuZ3Ro\nIEF1dGhlbnRpY2F0aW9uIDIwMTYCBBXXLOIwCwYJYIZIAWUDBAIBoGkwHAYJKoZI\nhvcNAQkFMQ8XDTE5MTEyMDE0NTYyMFowLwYJKoZIhvcNAQkEMSIEIJDnZUpcVLzC\nOdtpkH8gtxwLPIDE0NmAmFC9uM8q2z+OMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B\nBwEwCwYJKoZIhvcNAQEBBIIBAH/Pqv2xp3a0jSPkwU1K3eGA/1lfoNJMUny4d/PS\nLVWlkgrmedXdLmuBzAGEaaZOJS0lEpNd01pR/reHs7xxZ+RZ0olTs2ufM0CijQSx\nOL9HDl2O3OoD77NWx4tl3Wy1yJCeV3XH/cEI7AkKHCmKY9QMoMYWh16ORBtr+YcS\nYK+gONOjpjgcgTJgZ3HSFgQ50xiD4WT1kFBHsuYsLqaOSbTfTN6Ayyg4edjrPQqa\nVcVf1OQcIrfWA3yMQrnEZfOYfN/D4EPjTfxBV+VCi/F2bdZmMbJ7jNk1FbewSwWO\nSDH1i0K32NyFbnh0BSos7njq7ELqKlYBsoB/sZfaH2vKy5U=\n-----END SIGNED MESSAGE-----"), + MessageSize: 6494, + Tagger: &gitalypb.CommitAuthor{ + Name: []byte("Roger Meier"), + Email: []byte("r.meier@siemens.com"), + Date: ×tamppb.Timestamp{Seconds: 1574261780}, + Timezone: []byte("+0100"), + }, + SignatureType: gitalypb.SignatureType_X509, + }, + { + Name: []byte("v1.2.0"), + Id: annotatedTagID.String(), + Message: []byte("Blob tag"), + MessageSize: 8, + Tagger: gittest.DefaultCommitAuthor, + }, + { + Name: []byte("v1.3.0"), + Id: commitID.String(), + TargetCommit: gitCommit, + }, + { + Name: []byte("v1.4.0"), + Id: blobID.String(), + }, + { + Name: []byte("v1.5.0"), + Id: commitID.String(), + TargetCommit: gitCommit, + }, + { + Name: []byte("v1.6.0"), + Id: bigCommitID.String(), + TargetCommit: bigCommit, + }, + { + Name: []byte("v1.7.0"), + Id: bigMessageTag1ID.String(), + Message: []byte(bigMessage[:helper.MaxCommitOrTagMessageSize]), + MessageSize: int64(len(bigMessage)), + TargetCommit: gitCommit, + Tagger: gittest.DefaultCommitAuthor, + }, + } + + for _, expectedTag := range expectedTags { + rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: expectedTag.Name} + + resp, err := client.FindTag(ctx, rpcRequest) + require.NoError(t, err) + + testhelper.ProtoEqual(t, expectedTag, resp.GetTag()) + } +} + +func TestFindTag_nestedTag(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, repoProto, repoPath, client := setupRefService(ctx, t) + + repo := localrepo.NewTestRepo(t, cfg, repoProto) + + blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") + commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") + + testCases := []struct { + description string + depth int + originalOid git.ObjectID + }{ + { + description: "nested 1 deep, points to a commit", + depth: 1, + originalOid: commitID, + }, + { + description: "nested 4 deep, points to a commit", + depth: 4, + originalOid: commitID, + }, + { + description: "nested 3 deep, points to a blob", + depth: 3, + originalOid: blobID, + }, + { + description: "nested 20 deep, points to a commit", + depth: 20, + originalOid: commitID, + }, + } + + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + tags, err := repo.GetReferences(ctx, "refs/tags/") + require.NoError(t, err) + + updater, err := updateref.New(ctx, repo) + require.NoError(t, err) + for _, tag := range tags { + require.NoError(t, updater.Delete(tag.Name)) + } + require.NoError(t, updater.Commit()) + + catfileCache := catfile.NewCache(cfg) + defer catfileCache.Stop() + + objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) + require.NoError(t, err) + defer cancel() + + info, err := objectInfoReader.Info(ctx, git.Revision(tc.originalOid)) + require.NoError(t, err) + + tagID := tc.originalOid + var tagName, tagMessage string + + for depth := 0; depth < tc.depth; depth++ { + tagName = fmt.Sprintf("tag-depth-%d", depth) + tagMessage = fmt.Sprintf("a commit %d deep", depth) + tagID = gittest.WriteTag(t, cfg, repoPath, tagName, tagID.Revision(), gittest.WriteTagConfig{Message: tagMessage}) + } + expectedTag := &gitalypb.Tag{ + Name: []byte(tagName), + Id: tagID.String(), + Message: []byte(tagMessage), + MessageSize: int64(len([]byte(tagMessage))), + Tagger: gittest.DefaultCommitAuthor, + } + if info.Type == "commit" { + commit, err := catfile.GetCommit(ctx, objectReader, git.Revision(tc.originalOid)) + require.NoError(t, err) + expectedTag.TargetCommit = commit + } + rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: []byte(tagName)} + + resp, err := client.FindTag(ctx, rpcRequest) + require.NoError(t, err) + testhelper.ProtoEqual(t, expectedTag, resp.GetTag()) + }) + } +} + +func TestFindTag_notFound(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.FindTagStructuredError).Run(t, testFindTagNotFound) +} + +func testFindTagNotFound(t *testing.T, ctx context.Context) { + t.Parallel() + + cfg, client := setupRefServiceWithoutRepo(t) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) + + response, err := client.FindTag(ctx, &gitalypb.FindTagRequest{ + Repository: repoProto, + TagName: []byte("does-not-exist"), + }) + require.Nil(t, response) + if featureflag.FindTagStructuredError.IsEnabled(ctx) { + expectedErr, errGeneratingDetails := helper.ErrWithDetails( + helper.ErrNotFoundf("tag does not exist"), + &gitalypb.FindTagError{ + Error: &gitalypb.FindTagError_TagNotFound{ + TagNotFound: &gitalypb.ReferenceNotFoundError{ + ReferenceName: []byte("refs/tags/does-not-exist"), + }, + }, + }, + ) + require.NoError(t, errGeneratingDetails) + + testhelper.RequireGrpcError(t, expectedErr, err) + } else { + testhelper.RequireGrpcError(t, helper.ErrInternalf("no tag found"), err) + } +} + +func TestFindTag_invalidRequest(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupRefService(ctx, t) + + testCases := []struct { + desc string + request *gitalypb.FindTagRequest + }{ + { + desc: "empty request", + request: &gitalypb.FindTagRequest{}, + }, + { + desc: "invalid repo", + request: &gitalypb.FindTagRequest{ + Repository: &gitalypb.Repository{ + StorageName: "fake", + RelativePath: "repo", + }, + }, + }, + { + desc: "empty tag name", + request: &gitalypb.FindTagRequest{ + Repository: repo, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := client.FindTag(ctx, tc.request) + testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs.go index 0ad61e508b..7b11f5a919 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs.go @@ -5,10 +5,10 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) ListRefs(in *gitalypb.ListRefsRequest, stream gitalypb.RefService_ListRefsServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs_test.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs_test.go index 31eae96a25..dd89caaf0e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/list_refs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/list_refs_test.go @@ -1,16 +1,17 @@ +//go:build !gitaly_test_sha256 + package ref import ( "io" - "path/filepath" "testing" + "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -19,28 +20,21 @@ func TestServer_ListRefs(t *testing.T) { cfg, _, _, client := setupRefService(ctx, t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg) - // Checking out a worktree in an empty repository is not possible, so we must first write an empty commit. - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(git.DefaultBranch), gittest.WithParents()) - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") - // The worktree is detached, checkout the main so the branch pointer advances - // as we commit. - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "main") - oldCommit := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/main")) - - gittest.Exec(t, cfg, "-C", repoPath, "commit", "--allow-empty", "-m", "commit message") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "--amend", "--date", "Wed Feb 16 14:01 2011 +0100", "--allow-empty", "--no-edit") - commit := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/main")) + oldCommitID := gittest.WriteCommit(t, cfg, repoPath) + newCommitID := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommitID), + gittest.WithAuthorDate(time.Date(2011, 2, 16, 14, 1, 0, 0, time.FixedZone("UTC+1", +1*60*60))), + ) for _, cmd := range [][]string{ - {"update-ref", "refs/heads/main", commit}, - {"tag", "lightweight-tag", commit}, + {"update-ref", "refs/heads/main", newCommitID.String()}, + {"tag", "lightweight-tag", newCommitID.String()}, {"tag", "-m", "tag message", "annotated-tag", "refs/heads/main"}, {"symbolic-ref", "refs/heads/symbolic", "refs/heads/main"}, - {"update-ref", "refs/remote/remote-name/remote-branch", commit}, + {"update-ref", "refs/remote/remote-name/remote-branch", newCommitID.String()}, {"symbolic-ref", "HEAD", "refs/heads/main"}, - {"update-ref", "refs/heads/old", oldCommit}, + {"update-ref", "refs/heads/old", oldCommitID.String()}, } { gittest.Exec(t, cfg, append([]string{"-C", repoPath}, cmd...)...) } @@ -111,7 +105,7 @@ func TestServer_ListRefs(t *testing.T) { }, }, expected: []*gitalypb.ListRefsResponse_Reference{ - {Name: []byte("refs/heads/main"), Target: commit}, + {Name: []byte("refs/heads/main"), Target: newCommitID.String()}, }, }, { @@ -121,12 +115,12 @@ func TestServer_ListRefs(t *testing.T) { Patterns: [][]byte{[]byte("refs/")}, }, expected: []*gitalypb.ListRefsResponse_Reference{ - {Name: []byte("refs/heads/main"), Target: commit}, - {Name: []byte("refs/heads/old"), Target: oldCommit}, - {Name: []byte("refs/heads/symbolic"), Target: commit}, - {Name: []byte("refs/remote/remote-name/remote-branch"), Target: commit}, + {Name: []byte("refs/heads/main"), Target: newCommitID.String()}, + {Name: []byte("refs/heads/old"), Target: oldCommitID.String()}, + {Name: []byte("refs/heads/symbolic"), Target: newCommitID.String()}, + {Name: []byte("refs/remote/remote-name/remote-branch"), Target: newCommitID.String()}, {Name: []byte("refs/tags/annotated-tag"), Target: annotatedTagOID}, - {Name: []byte("refs/tags/lightweight-tag"), Target: commit}, + {Name: []byte("refs/tags/lightweight-tag"), Target: newCommitID.String()}, }, }, { @@ -140,9 +134,9 @@ func TestServer_ListRefs(t *testing.T) { }, }, expected: []*gitalypb.ListRefsResponse_Reference{ - {Name: []byte("refs/heads/old"), Target: oldCommit}, - {Name: []byte("refs/heads/main"), Target: commit}, - {Name: []byte("refs/heads/symbolic"), Target: commit}, + {Name: []byte("refs/heads/old"), Target: oldCommitID.String()}, + {Name: []byte("refs/heads/main"), Target: newCommitID.String()}, + {Name: []byte("refs/heads/symbolic"), Target: newCommitID.String()}, }, }, { @@ -152,11 +146,11 @@ func TestServer_ListRefs(t *testing.T) { Patterns: [][]byte{[]byte("refs/heads/*"), []byte("refs/tags/*")}, }, expected: []*gitalypb.ListRefsResponse_Reference{ - {Name: []byte("refs/heads/main"), Target: commit}, - {Name: []byte("refs/heads/old"), Target: oldCommit}, - {Name: []byte("refs/heads/symbolic"), Target: commit}, + {Name: []byte("refs/heads/main"), Target: newCommitID.String()}, + {Name: []byte("refs/heads/old"), Target: oldCommitID.String()}, + {Name: []byte("refs/heads/symbolic"), Target: newCommitID.String()}, {Name: []byte("refs/tags/annotated-tag"), Target: annotatedTagOID}, - {Name: []byte("refs/tags/lightweight-tag"), Target: commit}, + {Name: []byte("refs/tags/lightweight-tag"), Target: newCommitID.String()}, }, }, { @@ -167,12 +161,12 @@ func TestServer_ListRefs(t *testing.T) { Patterns: [][]byte{[]byte("refs/heads/*"), []byte("refs/tags/*")}, }, expected: []*gitalypb.ListRefsResponse_Reference{ - {Name: []byte("HEAD"), Target: commit}, - {Name: []byte("refs/heads/main"), Target: commit}, - {Name: []byte("refs/heads/old"), Target: oldCommit}, - {Name: []byte("refs/heads/symbolic"), Target: commit}, + {Name: []byte("HEAD"), Target: newCommitID.String()}, + {Name: []byte("refs/heads/main"), Target: newCommitID.String()}, + {Name: []byte("refs/heads/old"), Target: oldCommitID.String()}, + {Name: []byte("refs/heads/symbolic"), Target: newCommitID.String()}, {Name: []byte("refs/tags/annotated-tag"), Target: annotatedTagOID}, - {Name: []byte("refs/tags/lightweight-tag"), Target: commit}, + {Name: []byte("refs/tags/lightweight-tag"), Target: newCommitID.String()}, }, }, } { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs.go index 0b9ae588c4..6fee884e36 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs.go @@ -3,11 +3,11 @@ package ref import ( "context" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) PackRefs(ctx context.Context, in *gitalypb.PackRefsRequest) (*gitalypb.PackRefsResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs_test.go index c91db2de5a..cdaa080c0a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/pack_refs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/pack_refs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -10,11 +12,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -32,7 +34,7 @@ func TestPackRefsSuccessfulRequest(t *testing.T) { // creates some new heads newBranches := 10 for i := 0; i < newBranches; i++ { - require.NoError(t, repo.UpdateRef(ctx, git.ReferenceName(fmt.Sprintf("refs/heads/new-ref-%d", i)), "refs/heads/master", git.ZeroOID)) + require.NoError(t, repo.UpdateRef(ctx, git.ReferenceName(fmt.Sprintf("refs/heads/new-ref-%d", i)), "refs/heads/master", git.ObjectHashSHA1.ZeroOID)) } // pack all refs diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists.go index 2256d8dcac..b081fbee29 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists.go @@ -5,10 +5,10 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // RefExists returns true if the given reference exists. The ref must start with the string `ref/` diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists_test.go index 4e87c19ec9..c30e2e8147 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refexists_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refexists_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package ref import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames.go index 087bdc317a..491b31d144 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames.go @@ -4,9 +4,9 @@ import ( "bufio" "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames_containing.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames_containing.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames_containing.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames_containing.go index 851a5a5fcd..420dbda83d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refnames_containing.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refnames_containing.go @@ -4,10 +4,10 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -15,7 +15,7 @@ import ( // ListBranchNamesContainingCommit returns a maximum of in.GetLimit() Branch names // which contain the SHA1 passed as argument func (s *server) ListBranchNamesContainingCommit(in *gitalypb.ListBranchNamesContainingCommitRequest, stream gitalypb.RefService_ListBranchNamesContainingCommitServer) error { - if err := git.ValidateObjectID(in.GetCommitId()); err != nil { + if err := git.ObjectHashSHA1.ValidateHex(in.GetCommitId()); err != nil { return helper.ErrInvalidArgument(err) } @@ -58,7 +58,7 @@ func (bs *branchNamesContainingCommitSender) Send() error { // ListTagNamesContainingCommit returns a maximum of in.GetLimit() Tag names // which contain the SHA1 passed as argument func (s *server) ListTagNamesContainingCommit(in *gitalypb.ListTagNamesContainingCommitRequest, stream gitalypb.RefService_ListTagNamesContainingCommitServer) error { - if err := git.ValidateObjectID(in.GetCommitId()); err != nil { + if err := git.ObjectHashSHA1.ValidateHex(in.GetCommitId()); err != nil { return helper.ErrInvalidArgument(err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs.go index 63df4f6651..ca67ce8ed3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs.go @@ -1,20 +1,16 @@ package ref import ( - "bufio" "bytes" "context" - "errors" "fmt" "math" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -109,10 +105,11 @@ func (s *server) findLocalBranches(in *gitalypb.FindLocalBranchesRequest, stream ctx := stream.Context() repo := s.localrepo(in.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() writer := newFindLocalBranchesWriter(stream, objectReader) opts := buildFindRefsOpts(ctx, in.GetPaginationParams()) @@ -161,10 +158,11 @@ func (s *server) findAllBranches(in *gitalypb.FindAllBranchesRequest, stream git } ctx := stream.Context() - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() opts := buildFindRefsOpts(ctx, nil) opts.cmdArgs = args @@ -174,111 +172,6 @@ func (s *server) findAllBranches(in *gitalypb.FindAllBranchesRequest, stream git return s.findRefs(ctx, writer, repo, patterns, opts) } -func (s *server) FindTag(ctx context.Context, in *gitalypb.FindTagRequest) (*gitalypb.FindTagResponse, error) { - if err := s.validateFindTagRequest(in); err != nil { - return nil, helper.ErrInvalidArgument(err) - } - - repo := s.localrepo(in.GetRepository()) - - tag, err := s.findTag(ctx, repo, in.GetTagName()) - if err != nil { - return nil, helper.ErrInternal(err) - } - - return &gitalypb.FindTagResponse{Tag: tag}, nil -} - -// parseTagLine parses a line of text with the output format %(objectname) %(objecttype) %(refname:lstrip=2) -func parseTagLine(ctx context.Context, objectReader catfile.ObjectReader, tagLine string) (*gitalypb.Tag, error) { - fields := strings.SplitN(tagLine, " ", 3) - if len(fields) != 3 { - return nil, fmt.Errorf("invalid output from for-each-ref command: %v", tagLine) - } - - tagID, refType, refName := fields[0], fields[1], fields[2] - - tag := &gitalypb.Tag{ - Id: tagID, - Name: []byte(refName), - } - - switch refType { - // annotated tag - case "tag": - tag, err := catfile.GetTag(ctx, objectReader, git.Revision(tagID), refName) - if err != nil { - return nil, fmt.Errorf("getting annotated tag: %v", err) - } - catfile.TrimTagMessage(tag) - - return tag, nil - case "commit": - commit, err := catfile.GetCommit(ctx, objectReader, git.Revision(tagID)) - if err != nil { - return nil, fmt.Errorf("getting commit catfile: %v", err) - } - tag.TargetCommit = commit - return tag, nil - default: - return tag, nil - } -} - -func (s *server) findTag(ctx context.Context, repo git.RepositoryExecutor, tagName []byte) (*gitalypb.Tag, error) { - tagCmd, err := repo.Exec(ctx, - git.SubCmd{ - Name: "tag", - Flags: []git.Option{ - git.Flag{Name: "-l"}, git.ValueFlag{Name: "--format", Value: tagFormat}, - }, - Args: []string{string(tagName)}, - }, - git.WithRefTxHook(repo), - ) - if err != nil { - return nil, fmt.Errorf("for-each-ref error: %v", err) - } - - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) - if err != nil { - return nil, err - } - - var tag *gitalypb.Tag - - scanner := bufio.NewScanner(tagCmd) - if scanner.Scan() { - tag, err = parseTagLine(ctx, objectReader, scanner.Text()) - if err != nil { - return nil, err - } - } else { - return nil, errors.New("no tag found") - } - - if err = tagCmd.Wait(); err != nil { - return nil, err - } - - return tag, nil -} - -func (s *server) validateFindTagRequest(in *gitalypb.FindTagRequest) error { - if in.GetRepository() == nil { - return errors.New("repository is empty") - } - - if _, err := s.locator.GetRepoPath(in.GetRepository()); err != nil { - return fmt.Errorf("invalid git directory: %v", err) - } - - if in.GetTagName() == nil { - return errors.New("tag name is empty") - } - return nil -} - func buildPaginationOpts(ctx context.Context, p *gitalypb.PaginationParameter) *paginationOpts { opts := &paginationOpts{} opts.IsPageToken = func(_ []byte) bool { return true } @@ -293,19 +186,15 @@ func buildPaginationOpts(ctx context.Context, p *gitalypb.PaginationParameter) * } if p.GetPageToken() != "" { - if featureflag.ExactPaginationTokenMatch.IsEnabled(ctx) { - opts.IsPageToken = func(line []byte) bool { - // Only use the first part of the line before \x00 separator - if nullByteIndex := bytes.IndexByte(line, 0); nullByteIndex != -1 { - line = line[:nullByteIndex] - } - - return bytes.Equal(line, []byte(p.GetPageToken())) + opts.IsPageToken = func(line []byte) bool { + // Only use the first part of the line before \x00 separator + if nullByteIndex := bytes.IndexByte(line, 0); nullByteIndex != -1 { + line = line[:nullByteIndex] } - opts.PageTokenError = true - } else { - opts.IsPageToken = func(l []byte) bool { return bytes.Compare(l, []byte(p.GetPageToken())) >= 0 } + + return bytes.Equal(line, []byte(p.GetPageToken())) } + opts.PageTokenError = true } return opts @@ -345,6 +234,8 @@ func getTagSortField(sortBy *gitalypb.FindAllTagsRequest_SortBy) (string, error) key = "refname" case gitalypb.FindAllTagsRequest_SortBy_CREATORDATE: key = "creatordate" + case gitalypb.FindAllTagsRequest_SortBy_VERSION_REFNAME: + key = "version:refname" default: return "", fmt.Errorf("unsupported sorting key: %s", sortBy.Key) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs_test.go index 7278f77674..1a09d9fa2e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/refs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/refs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -10,15 +12,14 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -253,47 +254,74 @@ func TestInvalidRepoFindDefaultBranchNameRequest(t *testing.T) { } func TestSuccessfulFindLocalBranches(t *testing.T) { - ctx := testhelper.Context(t) + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testSuccessfulFindLocalBranches) +} + +func testSuccessfulFindLocalBranches(t *testing.T, ctx context.Context) { _, repo, _, client := setupRefService(ctx, t) rpcRequest := &gitalypb.FindLocalBranchesRequest{Repository: repo} c, err := client.FindLocalBranches(ctx, rpcRequest) require.NoError(t, err) - var branches []*gitalypb.FindLocalBranchResponse - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - branches = append(branches, r.GetBranches()...) - } - - for name, target := range localBranches { - localBranch := &gitalypb.FindLocalBranchResponse{ - Name: []byte(name), - CommitId: target.Id, - CommitSubject: target.Subject, - CommitAuthor: &gitalypb.FindLocalBranchCommitAuthor{ - Name: target.Author.Name, - Email: target.Author.Email, - Date: target.Author.Date, - }, - CommitCommitter: &gitalypb.FindLocalBranchCommitAuthor{ - Name: target.Committer.Name, - Email: target.Committer.Email, - Date: target.Committer.Date, - }, - Commit: target, + if featureflag.SimplifyFindLocalBranchesResponse.IsEnabled(ctx) { + var branches []*gitalypb.Branch + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + branches = append(branches, r.GetLocalBranches()...) } - assertContainsLocalBranch(t, branches, localBranch) + for name, target := range localBranches { + localBranch := &gitalypb.Branch{ + Name: []byte(name), + TargetCommit: target, + } + + assertContainsBranch(t, branches, localBranch) + } + + } else { + var branches []*gitalypb.FindLocalBranchResponse + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + branches = append(branches, r.GetBranches()...) + } + + for name, target := range localBranches { + localBranch := &gitalypb.FindLocalBranchResponse{ + Name: []byte(name), + CommitId: target.Id, + CommitSubject: target.Subject, + CommitAuthor: &gitalypb.FindLocalBranchCommitAuthor{ + Name: target.Author.Name, + Email: target.Author.Email, + Date: target.Author.Date, + }, + CommitCommitter: &gitalypb.FindLocalBranchCommitAuthor{ + Name: target.Committer.Name, + Email: target.Committer.Email, + Date: target.Committer.Date, + }, + Commit: target, + } + + assertContainsLocalBranch(t, branches, localBranch) + } } } -func TestFindLocalBranches_huge_committer(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindLocalBranchesHugeCommitter) +func TestFindLocalBranchesHugeCommitter(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testFindLocalBranchesHugeCommitter) } func testFindLocalBranchesHugeCommitter(t *testing.T, ctx context.Context) { @@ -319,7 +347,8 @@ func testFindLocalBranchesHugeCommitter(t *testing.T, ctx context.Context) { } func TestFindLocalBranchesPagination(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindLocalBranchesPagination) + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testFindLocalBranchesPagination) } func testFindLocalBranchesPagination(t *testing.T, ctx context.Context) { @@ -336,42 +365,63 @@ func testFindLocalBranchesPagination(t *testing.T, ctx context.Context) { c, err := client.FindLocalBranches(ctx, rpcRequest) require.NoError(t, err) - var branches []*gitalypb.FindLocalBranchResponse - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - branches = append(branches, r.GetBranches()...) - } - - require.Len(t, branches, limit) - expectedBranch := "refs/heads/improve/awesome" target := localBranches[expectedBranch] - branch := &gitalypb.FindLocalBranchResponse{ - Name: []byte(expectedBranch), - CommitId: target.Id, - CommitSubject: target.Subject, - CommitAuthor: &gitalypb.FindLocalBranchCommitAuthor{ - Name: target.Author.Name, - Email: target.Author.Email, - Date: target.Author.Date, - }, - CommitCommitter: &gitalypb.FindLocalBranchCommitAuthor{ - Name: target.Committer.Name, - Email: target.Committer.Email, - Date: target.Committer.Date, - }, - Commit: target, + if featureflag.SimplifyFindLocalBranchesResponse.IsEnabled(ctx) { + var branches []*gitalypb.Branch + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + branches = append(branches, r.GetLocalBranches()...) + } + + require.Len(t, branches, limit) + + branch := &gitalypb.Branch{ + Name: []byte(expectedBranch), + TargetCommit: target, + } + assertContainsBranch(t, branches, branch) + } else { + var branches []*gitalypb.FindLocalBranchResponse + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + branches = append(branches, r.GetBranches()...) + } + + require.Len(t, branches, limit) + + branch := &gitalypb.FindLocalBranchResponse{ + Name: []byte(expectedBranch), + CommitId: target.Id, + CommitSubject: target.Subject, + CommitAuthor: &gitalypb.FindLocalBranchCommitAuthor{ + Name: target.Author.Name, + Email: target.Author.Email, + Date: target.Author.Date, + }, + CommitCommitter: &gitalypb.FindLocalBranchCommitAuthor{ + Name: target.Committer.Name, + Email: target.Committer.Email, + Date: target.Committer.Date, + }, + Commit: target, + } + assertContainsLocalBranch(t, branches, branch) } - assertContainsLocalBranch(t, branches, branch) } func TestFindLocalBranchesPaginationSequence(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindLocalBranchesPaginationSequence) + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testFindLocalBranchesPaginationSequence) } func testFindLocalBranchesPaginationSequence(t *testing.T, ctx context.Context) { @@ -387,44 +437,82 @@ func testFindLocalBranchesPaginationSequence(t *testing.T, ctx context.Context) c, err := client.FindLocalBranches(ctx, firstRPCRequest) require.NoError(t, err) - var firstResponseBranches []*gitalypb.FindLocalBranchResponse - for { - r, err := c.Recv() - if err == io.EOF { - break + if featureflag.SimplifyFindLocalBranchesResponse.IsEnabled(ctx) { + var firstResponseBranches []*gitalypb.Branch + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + firstResponseBranches = append(firstResponseBranches, r.GetLocalBranches()...) } - require.NoError(t, err) - firstResponseBranches = append(firstResponseBranches, r.GetBranches()...) - } - require.Len(t, firstResponseBranches, limit) + require.Len(t, firstResponseBranches, limit) - secondRPCRequest := &gitalypb.FindLocalBranchesRequest{ - Repository: repo, - PaginationParams: &gitalypb.PaginationParameter{ - Limit: 1, - PageToken: string(firstResponseBranches[0].Name), - }, - } - c, err = client.FindLocalBranches(ctx, secondRPCRequest) - require.NoError(t, err) - - var secondResponseBranches []*gitalypb.FindLocalBranchResponse - for { - r, err := c.Recv() - if err == io.EOF { - break + secondRPCRequest := &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + PaginationParams: &gitalypb.PaginationParameter{ + Limit: 1, + PageToken: string(firstResponseBranches[0].Name), + }, } + c, err = client.FindLocalBranches(ctx, secondRPCRequest) require.NoError(t, err) - secondResponseBranches = append(secondResponseBranches, r.GetBranches()...) - } - require.Len(t, secondResponseBranches, 1) - require.Equal(t, firstResponseBranches[1], secondResponseBranches[0]) + var secondResponseBranches []*gitalypb.Branch + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + secondResponseBranches = append(secondResponseBranches, r.GetLocalBranches()...) + } + + require.Len(t, secondResponseBranches, 1) + require.Equal(t, firstResponseBranches[1], secondResponseBranches[0]) + } else { + var firstResponseBranches []*gitalypb.FindLocalBranchResponse + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + firstResponseBranches = append(firstResponseBranches, r.GetBranches()...) + } + + require.Len(t, firstResponseBranches, limit) + + secondRPCRequest := &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + PaginationParams: &gitalypb.PaginationParameter{ + Limit: 1, + PageToken: string(firstResponseBranches[0].Name), + }, + } + c, err = client.FindLocalBranches(ctx, secondRPCRequest) + require.NoError(t, err) + + var secondResponseBranches []*gitalypb.FindLocalBranchResponse + for { + r, err := c.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + secondResponseBranches = append(secondResponseBranches, r.GetBranches()...) + } + + require.Len(t, secondResponseBranches, 1) + require.Equal(t, firstResponseBranches[1], secondResponseBranches[0]) + } } func TestFindLocalBranchesPaginationWithIncorrectToken(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindLocalBranchesPaginationWithIncorrectToken) + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testFindLocalBranchesPaginationWithIncorrectToken) } func testFindLocalBranchesPaginationWithIncorrectToken(t *testing.T, ctx context.Context) { @@ -441,44 +529,9 @@ func testFindLocalBranchesPaginationWithIncorrectToken(t *testing.T, ctx context c, err := client.FindLocalBranches(ctx, rpcRequest) require.NoError(t, err) - if featureflag.ExactPaginationTokenMatch.IsEnabled(ctx) { - _, err = c.Recv() - require.NotEqual(t, err, io.EOF) - testhelper.RequireGrpcError(t, helper.ErrInternalf("could not find page token"), err) - } else { - require.NoError(t, err) - - var branches []*gitalypb.FindLocalBranchResponse - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - branches = append(branches, r.GetBranches()...) - } - - testhelper.ProtoEqual(t, []*gitalypb.FindLocalBranchResponse{ - { - Name: []byte("refs/heads/rebase-encoding-failure-trigger"), - Commit: gittest.CommitsByID["ca47bfd5e930148c42ed74c3b561a8783e381f7f"], - CommitId: "ca47bfd5e930148c42ed74c3b561a8783e381f7f", - CommitSubject: []byte("Add Modula-2 source file for language detection"), - CommitAuthor: &gitalypb.FindLocalBranchCommitAuthor{ - Name: []byte("Jacob Vosmaer"), - Email: []byte("jacob@gitlab.com"), - Date: ×tamppb.Timestamp{Seconds: 1501503403}, - Timezone: []byte("+0200"), - }, - CommitCommitter: &gitalypb.FindLocalBranchCommitAuthor{ - Name: []byte("Ahmad Sherif"), - Email: []byte("me@ahmadsherif.com"), - Date: ×tamppb.Timestamp{Seconds: 1521033060}, - Timezone: []byte("+0100"), - }, - }, - }, branches) - } + _, err = c.Recv() + require.NotEqual(t, err, io.EOF) + testhelper.RequireGrpcError(t, helper.ErrInternalf("could not find page token"), err) } // Test that `s` contains the elements in `relativeOrder` in that order @@ -500,7 +553,8 @@ func isOrderedSubset(subset, set []string) bool { } func TestFindLocalBranchesSort(t *testing.T) { - testhelper.NewFeatureSets(featureflag.ExactPaginationTokenMatch).Run(t, testFindLocalBranchesSort) + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testFindLocalBranchesSort) } func testFindLocalBranchesSort(t *testing.T, ctx context.Context) { @@ -543,9 +597,16 @@ func testFindLocalBranchesSort(t *testing.T, ctx context.Context) { } require.NoError(t, err) - for _, branch := range r.GetBranches() { - branches = append(branches, string(branch.Name)) + if featureflag.SimplifyFindLocalBranchesResponse.IsEnabled(ctx) { + for _, branch := range r.GetLocalBranches() { + branches = append(branches, string(branch.Name)) + } + } else { + for _, branch := range r.GetBranches() { + branches = append(branches, string(branch.Name)) + } } + } if !isOrderedSubset(testCase.relativeOrder, branches) { @@ -556,10 +617,14 @@ func testFindLocalBranchesSort(t *testing.T, ctx context.Context) { } func TestEmptyFindLocalBranchesRequest(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.SimplifyFindLocalBranchesResponse).Run(t, testEmptyFindLocalBranchesRequest) +} + +func testEmptyFindLocalBranchesRequest(t *testing.T, ctx context.Context) { _, client := setupRefServiceWithoutRepo(t) rpcRequest := &gitalypb.FindLocalBranchesRequest{} - ctx := testhelper.Context(t) c, err := client.FindLocalBranches(ctx, rpcRequest) require.NoError(t, err) @@ -568,9 +633,13 @@ func TestEmptyFindLocalBranchesRequest(t *testing.T) { _, recvError = c.Recv() } - if helper.GrpcCode(recvError) != codes.InvalidArgument { - t.Fatal(recvError) - } + testhelper.RequireGrpcError(t, + helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), + recvError, + ) } func TestSuccessfulFindAllBranchesRequest(t *testing.T) { @@ -616,11 +685,11 @@ func TestSuccessfulFindAllBranchesRequest(t *testing.T) { Name: []byte(name), Target: target, } - assertContainsBranch(t, branches, branch) + assertContainsAllBranchesResponseBranch(t, branches, branch) } // It contains our fake remote branch - assertContainsBranch(t, branches, remoteBranch) + assertContainsAllBranchesResponseBranch(t, branches, remoteBranch) } func TestSuccessfulFindAllBranchesRequestWithMergedBranches(t *testing.T) { @@ -703,7 +772,7 @@ func TestSuccessfulFindAllBranchesRequestWithMergedBranches(t *testing.T) { continue } - assertContainsBranch(t, testCase.expectedBranches, branch) + assertContainsAllBranchesResponseBranch(t, testCase.expectedBranches, branch) } }) } @@ -712,13 +781,18 @@ func TestSuccessfulFindAllBranchesRequestWithMergedBranches(t *testing.T) { func TestInvalidFindAllBranchesRequest(t *testing.T) { _, client := setupRefServiceWithoutRepo(t) - testCases := []struct { + for _, tc := range []struct { description string request *gitalypb.FindAllBranchesRequest + expectedErr error }{ { description: "Empty request", request: &gitalypb.FindAllBranchesRequest{}, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), }, { description: "Invalid repo", @@ -728,10 +802,12 @@ func TestInvalidFindAllBranchesRequest(t *testing.T) { RelativePath: "repo", }, }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"fake\"", + "repo scoped: invalid Repository", + )), }, - } - - for _, tc := range testCases { + } { t.Run(tc.description, func(t *testing.T) { ctx := testhelper.Context(t) c, err := client.FindAllBranches(ctx, tc.request) @@ -742,7 +818,7 @@ func TestInvalidFindAllBranchesRequest(t *testing.T) { _, recvError = c.Recv() } - testhelper.RequireGrpcCode(t, recvError, codes.InvalidArgument) + testhelper.RequireGrpcError(t, tc.expectedErr, recvError) }) } } @@ -853,7 +929,7 @@ func TestListBranchNamesContainingCommit(t *testing.T) { }, { // gitlab-test contains a branch refs/heads/1942eed5cc108b19c7405106e81fa96125d0be22 - // which is in conflift with a commit with the same ID + // which is in conflict with a commit with the same ID description: "branch name is also commit id", commitID: "1942eed5cc108b19c7405106e81fa96125d0be22", code: codes.OK, @@ -913,298 +989,3 @@ func TestListBranchNamesContainingCommit(t *testing.T) { }) } } - -func TestSuccessfulFindTagRequest(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupRefService(ctx, t) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") - commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") - - gitCommit := testhelper.GitLabTestCommit(commitID.String()) - - bigCommitID := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithBranch("local-big-commits"), - gittest.WithMessage("An empty commit with REALLY BIG message\n\n"+strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1)), - gittest.WithParents("60ecb67744cb56576c30214ff52294f8ce2def98"), - ) - bigCommit, err := repo.ReadCommit(ctx, git.Revision(bigCommitID)) - require.NoError(t, err) - - annotatedTagID := gittest.WriteTag(t, cfg, repoPath, "v1.2.0", blobID.Revision(), gittest.WriteTagConfig{Message: "Blob tag"}) - - gittest.WriteTag(t, cfg, repoPath, "v1.3.0", commitID.Revision()) - gittest.WriteTag(t, cfg, repoPath, "v1.4.0", blobID.Revision()) - - // To test recursive resolving to a commit - gittest.WriteTag(t, cfg, repoPath, "v1.5.0", "v1.3.0") - - // A tag to commit with a big message - gittest.WriteTag(t, cfg, repoPath, "v1.6.0", bigCommitID.Revision()) - - // A tag with a big message - bigMessage := strings.Repeat("a", 11*1024) - bigMessageTag1ID := gittest.WriteTag(t, cfg, repoPath, "v1.7.0", commitID.Revision(), gittest.WriteTagConfig{Message: bigMessage}) - - // A tag with a commit id as its name - commitTagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision(), gittest.WriteTagConfig{Message: "commit tag with a commit sha as the name"}) - - // a tag of a tag - tagOfTagID := gittest.WriteTag(t, cfg, repoPath, "tag-of-tag", commitTagID.Revision(), gittest.WriteTagConfig{Message: "tag of a tag"}) - - expectedTags := []*gitalypb.Tag{ - { - Name: []byte(commitID), - Id: commitTagID.String(), - TargetCommit: gitCommit, - Message: []byte("commit tag with a commit sha as the name"), - MessageSize: 40, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - }, - { - Name: []byte("tag-of-tag"), - Id: tagOfTagID.String(), - TargetCommit: gitCommit, - Message: []byte("tag of a tag"), - MessageSize: 12, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - }, - { - Name: []byte("v1.0.0"), - Id: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", - TargetCommit: gitCommit, - Message: []byte("Release"), - MessageSize: 7, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393491299}, - Timezone: []byte("+0200"), - }, - SignatureType: gitalypb.SignatureType_NONE, - }, - { - Name: []byte("v1.1.0"), - Id: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - TargetCommit: testhelper.GitLabTestCommit("5937ac0a7beb003549fc5fd26fc247adbce4a52e"), - Message: []byte("Version 1.1.0"), - MessageSize: 13, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393505709}, - Timezone: []byte("+0200"), - }, - }, - { - Name: []byte("v1.1.1"), - Id: "8f03acbcd11c53d9c9468078f32a2622005a4841", - TargetCommit: testhelper.GitLabTestCommit("189a6c924013fc3fe40d6f1ec1dc20214183bc97"), - Message: []byte("x509 signed tag\n-----BEGIN SIGNED MESSAGE-----\nMIISfwYJKoZIhvcNAQcCoIIScDCCEmwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI\nhvcNAQcBoIIP8zCCB3QwggVcoAMCAQICBBXXLOIwDQYJKoZIhvcNAQELBQAwgbYx\nCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVu\nMRAwDgYDVQQKDAdTaWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwU\nU2llbWVucyBUcnVzdCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBD\nQSBNZWRpdW0gU3RyZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjAeFw0xNzAyMDMw\nNjU4MzNaFw0yMDAyMDMwNjU4MzNaMFsxETAPBgNVBAUTCFowMDBOV0RIMQ4wDAYD\nVQQqDAVSb2dlcjEOMAwGA1UEBAwFTWVpZXIxEDAOBgNVBAoMB1NpZW1lbnMxFDAS\nBgNVBAMMC01laWVyIFJvZ2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAuBNea/68ZCnHYQjpm/k3ZBG0wBpEKSwG6lk9CEQlSxsqVLQHAoAKBIlJm1in\nYVLcK/Sq1yhYJ/qWcY/M53DhK2rpPuhtrWJUdOUy8EBWO20F4bd4Fw9pO7jt8bme\nu33TSrK772vKjuppzB6SeG13Cs08H+BIeD106G27h7ufsO00pvsxoSDL+uc4slnr\npBL+2TAL7nSFnB9QHWmRIK27SPqJE+lESdb0pse11x1wjvqKy2Q7EjL9fpqJdHzX\nNLKHXd2r024TOORTa05DFTNR+kQEKKV96XfpYdtSBomXNQ44cisiPBJjFtYvfnFE\nwgrHa8fogn/b0C+A+HAoICN12wIDAQABo4IC4jCCAt4wHQYDVR0OBBYEFCF+gkUp\nXQ6xGc0kRWXuDFxzA14zMEMGA1UdEQQ8MDqgIwYKKwYBBAGCNxQCA6AVDBNyLm1l\naWVyQHNpZW1lbnMuY29tgRNyLm1laWVyQHNpZW1lbnMuY29tMA4GA1UdDwEB/wQE\nAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwgcoGA1UdHwSBwjCB\nvzCBvKCBuaCBtoYmaHR0cDovL2NoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBNi5j\ncmyGQWxkYXA6Ly9jbC5zaWVtZW5zLm5ldC9DTj1aWlpaWlpBNixMPVBLST9jZXJ0\naWZpY2F0ZVJldm9jYXRpb25MaXN0hklsZGFwOi8vY2wuc2llbWVucy5jb20vQ049\nWlpaWlpaQTYsbz1UcnVzdGNlbnRlcj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0\nMEUGA1UdIAQ+MDwwOgYNKwYBBAGhaQcCAgMBAzApMCcGCCsGAQUFBwIBFhtodHRw\nOi8vd3d3LnNpZW1lbnMuY29tL3BraS8wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW\ngBT4FV1HDGx3e3LEAheRaKK292oJRDCCAQQGCCsGAQUFBwEBBIH3MIH0MDIGCCsG\nAQUFBzAChiZodHRwOi8vYWguc2llbWVucy5jb20vcGtpP1paWlpaWkE2LmNydDBB\nBggrBgEFBQcwAoY1bGRhcDovL2FsLnNpZW1lbnMubmV0L0NOPVpaWlpaWkE2LEw9\nUEtJP2NBQ2VydGlmaWNhdGUwSQYIKwYBBQUHMAKGPWxkYXA6Ly9hbC5zaWVtZW5z\nLmNvbS9DTj1aWlpaWlpBNixvPVRydXN0Y2VudGVyP2NBQ2VydGlmaWNhdGUwMAYI\nKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLnBraS1zZXJ2aWNlcy5zaWVtZW5zLmNvbTAN\nBgkqhkiG9w0BAQsFAAOCAgEAXPVcX6vaEcszJqg5IemF9aFTlwTrX5ITNIpzcqG+\nkD5haOf2mZYLjl+MKtLC1XfmIsGCUZNb8bjP6QHQEI+2d6x/ZOqPq7Kd7PwVu6x6\nxZrkDjUyhUbUntT5+RBy++l3Wf6Cq6Kx+K8ambHBP/bu90/p2U8KfFAG3Kr2gI2q\nfZrnNMOxmJfZ3/sXxssgLkhbZ7hRa+MpLfQ6uFsSiat3vlawBBvTyHnoZ/7oRc8y\nqi6QzWcd76CPpMElYWibl+hJzKbBZUWvc71AzHR6i1QeZ6wubYz7vr+FF5Y7tnxB\nVz6omPC9XAg0F+Dla6Zlz3Awj5imCzVXa+9SjtnsidmJdLcKzTAKyDewewoxYOOJ\nj3cJU7VSjJPl+2fVmDBaQwcNcUcu/TPAKApkegqO7tRF9IPhjhW8QkRnkqMetO3D\nOXmAFVIsEI0Hvb2cdb7B6jSpjGUuhaFm9TCKhQtCk2p8JCDTuaENLm1x34rrJKbT\n2vzyYN0CZtSkUdgD4yQxK9VWXGEzexRisWb4AnZjD2NAquLPpXmw8N0UwFD7MSpC\ndpaX7FktdvZmMXsnGiAdtLSbBgLVWOD1gmJFDjrhNbI8NOaOaNk4jrfGqNh5lhGU\n4DnBT2U6Cie1anLmFH/oZooAEXR2o3Nu+1mNDJChnJp0ovs08aa3zZvBdcloOvfU\nqdowggh3MIIGX6ADAgECAgQtyi/nMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYDVQQG\nEwJERTEPMA0GA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UE\nCgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaQTExHTAbBgNVBAsMFFNpZW1lbnMg\nVHJ1c3QgQ2VudGVyMSIwIAYDVQQDDBlTaWVtZW5zIFJvb3QgQ0EgVjMuMCAyMDE2\nMB4XDTE2MDcyMDEzNDYxMFoXDTIyMDcyMDEzNDYxMFowgbYxCzAJBgNVBAYTAkRF\nMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVuMRAwDgYDVQQKDAdT\naWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwUU2llbWVucyBUcnVz\ndCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBDQSBNZWRpdW0gU3Ry\nZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAL9UfK+JAZEqVMVvECdYF9IK4KSw34AqyNl3rYP5x03dtmKaNu+2\n0fQqNESA1NGzw3s6LmrKLh1cR991nB2cvKOXu7AvEGpSuxzIcOROd4NpvRx+Ej1p\nJIPeqf+ScmVK7lMSO8QL/QzjHOpGV3is9sG+ZIxOW9U1ESooy4Hal6ZNs4DNItsz\npiCKqm6G3et4r2WqCy2RRuSqvnmMza7Y8BZsLy0ZVo5teObQ37E/FxqSrbDI8nxn\nB7nVUve5ZjrqoIGSkEOtyo11003dVO1vmWB9A0WQGDqE/q3w178hGhKfxzRaqzyi\nSoADUYS2sD/CglGTUxVq6u0pGLLsCFjItcCWqW+T9fPYfJ2CEd5b3hvqdCn+pXjZ\n/gdX1XAcdUF5lRnGWifaYpT9n4s4adzX8q6oHSJxTppuAwLRKH6eXALbGQ1I9lGQ\nDSOipD/09xkEsPw6HOepmf2U3YxZK1VU2sHqugFJboeLcHMzp6E1n2ctlNG1GKE9\nFDHmdyFzDi0Nnxtf/GgVjnHF68hByEE1MYdJ4nJLuxoT9hyjYdRW9MpeNNxxZnmz\nW3zh7QxIqP0ZfIz6XVhzrI9uZiqwwojDiM5tEOUkQ7XyW6grNXe75yt6mTj89LlB\nH5fOW2RNmCy/jzBXDjgyskgK7kuCvUYTuRv8ITXbBY5axFA+CpxZqokpAgMBAAGj\nggKmMIICojCCAQUGCCsGAQUFBwEBBIH4MIH1MEEGCCsGAQUFBzAChjVsZGFwOi8v\nYWwuc2llbWVucy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/Y0FDZXJ0aWZpY2F0ZTAy\nBggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBMS5j\ncnQwSgYIKwYBBQUHMAKGPmxkYXA6Ly9hbC5zaWVtZW5zLmNvbS91aWQ9WlpaWlpa\nQTEsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUFBzABhiRodHRw\nOi8vb2NzcC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wHwYDVR0jBBgwFoAUcG2g\nUOyp0CxnnRkV/v0EczXD4tQwEgYDVR0TAQH/BAgwBgEB/wIBADBABgNVHSAEOTA3\nMDUGCCsGAQQBoWkHMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuc2llbWVucy5j\nb20vcGtpLzCBxwYDVR0fBIG/MIG8MIG5oIG2oIGzhj9sZGFwOi8vY2wuc2llbWVu\ncy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3SG\nJmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTEuY3JshkhsZGFwOi8v\nY2wuc2llbWVucy5jb20vdWlkPVpaWlpaWkExLG89VHJ1c3RjZW50ZXI/YXV0aG9y\naXR5UmV2b2NhdGlvbkxpc3QwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsGAQUFBwME\nBggrBgEFBQcDCTAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPgVXUcMbHd7csQC\nF5Foorb3aglEMA0GCSqGSIb3DQEBCwUAA4ICAQBw+sqMp3SS7DVKcILEmXbdRAg3\nlLO1r457KY+YgCT9uX4VG5EdRKcGfWXK6VHGCi4Dos5eXFV34Mq/p8nu1sqMuoGP\nYjHn604eWDprhGy6GrTYdxzcE/GGHkpkuE3Ir/45UcmZlOU41SJ9SNjuIVrSHMOf\nccSY42BCspR/Q1Z/ykmIqQecdT3/Kkx02GzzSN2+HlW6cEO4GBW5RMqsvd2n0h2d\nfe2zcqOgkLtx7u2JCR/U77zfyxG3qXtcymoz0wgSHcsKIl+GUjITLkHfS9Op8V7C\nGr/dX437sIg5pVHmEAWadjkIzqdHux+EF94Z6kaHywohc1xG0KvPYPX7iSNjkvhz\n4NY53DHmxl4YEMLffZnaS/dqyhe1GTpcpyN8WiR4KuPfxrkVDOsuzWFtMSvNdlOV\ngdI0MXcLMP+EOeANZWX6lGgJ3vWyemo58nzgshKd24MY3w3i6masUkxJH2KvI7UH\n/1Db3SC8oOUjInvSRej6M3ZhYWgugm6gbpUgFoDw/o9Cg6Qm71hY0JtcaPC13rzm\nN8a2Br0+Fa5e2VhwLmAxyfe1JKzqPwuHT0S5u05SQghL5VdzqfA8FCL/j4XC9yI6\ncsZTAQi73xFQYVjZt3+aoSz84lOlTmVo/jgvGMY/JzH9I4mETGgAJRNj34Z/0meh\nM+pKWCojNH/dgyJSwDGCAlIwggJOAgEBMIG/MIG2MQswCQYDVQQGEwJERTEPMA0G\nA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UECgwHU2llbWVu\nczERMA8GA1UEBRMIWlpaWlpaQTYxHTAbBgNVBAsMFFNpZW1lbnMgVHJ1c3QgQ2Vu\ndGVyMT8wPQYDVQQDDDZTaWVtZW5zIElzc3VpbmcgQ0EgTWVkaXVtIFN0cmVuZ3Ro\nIEF1dGhlbnRpY2F0aW9uIDIwMTYCBBXXLOIwCwYJYIZIAWUDBAIBoGkwHAYJKoZI\nhvcNAQkFMQ8XDTE5MTEyMDE0NTYyMFowLwYJKoZIhvcNAQkEMSIEIJDnZUpcVLzC\nOdtpkH8gtxwLPIDE0NmAmFC9uM8q2z+OMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B\nBwEwCwYJKoZIhvcNAQEBBIIBAH/Pqv2xp3a0jSPkwU1K3eGA/1lfoNJMUny4d/PS\nLVWlkgrmedXdLmuBzAGEaaZOJS0lEpNd01pR/reHs7xxZ+RZ0olTs2ufM0CijQSx\nOL9HDl2O3OoD77NWx4tl3Wy1yJCeV3XH/cEI7AkKHCmKY9QMoMYWh16ORBtr+YcS\nYK+gONOjpjgcgTJgZ3HSFgQ50xiD4WT1kFBHsuYsLqaOSbTfTN6Ayyg4edjrPQqa\nVcVf1OQcIrfWA3yMQrnEZfOYfN/D4EPjTfxBV+VCi/F2bdZmMbJ7jNk1FbewSwWO\nSDH1i0K32NyFbnh0BSos7njq7ELqKlYBsoB/sZfaH2vKy5U=\n-----END SIGNED MESSAGE-----"), - MessageSize: 6494, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Roger Meier"), - Email: []byte("r.meier@siemens.com"), - Date: ×tamppb.Timestamp{Seconds: 1574261780}, - Timezone: []byte("+0100"), - }, - SignatureType: gitalypb.SignatureType_X509, - }, - { - Name: []byte("v1.2.0"), - Id: annotatedTagID.String(), - Message: []byte("Blob tag"), - MessageSize: 8, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - }, - { - Name: []byte("v1.3.0"), - Id: commitID.String(), - TargetCommit: gitCommit, - }, - { - Name: []byte("v1.4.0"), - Id: blobID.String(), - }, - { - Name: []byte("v1.5.0"), - Id: commitID.String(), - TargetCommit: gitCommit, - }, - { - Name: []byte("v1.6.0"), - Id: bigCommitID.String(), - TargetCommit: bigCommit, - }, - { - Name: []byte("v1.7.0"), - Id: bigMessageTag1ID.String(), - Message: []byte(bigMessage[:helper.MaxCommitOrTagMessageSize]), - MessageSize: int64(len(bigMessage)), - TargetCommit: gitCommit, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - }, - } - - for _, expectedTag := range expectedTags { - rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: expectedTag.Name} - - resp, err := client.FindTag(ctx, rpcRequest) - require.NoError(t, err) - - testhelper.ProtoEqual(t, expectedTag, resp.GetTag()) - } -} - -func TestFindTagNestedTag(t *testing.T) { - ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupRefService(ctx, t) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") - commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") - - testCases := []struct { - description string - depth int - originalOid git.ObjectID - }{ - { - description: "nested 1 deep, points to a commit", - depth: 1, - originalOid: commitID, - }, - { - description: "nested 4 deep, points to a commit", - depth: 4, - originalOid: commitID, - }, - { - description: "nested 3 deep, points to a blob", - depth: 3, - originalOid: blobID, - }, - { - description: "nested 20 deep, points to a commit", - depth: 20, - originalOid: commitID, - }, - } - - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { - tags, err := repo.GetReferences(ctx, "refs/tags/") - require.NoError(t, err) - - updater, err := updateref.New(ctx, repo) - require.NoError(t, err) - for _, tag := range tags { - require.NoError(t, updater.Delete(tag.Name)) - } - require.NoError(t, updater.Commit()) - - catfileCache := catfile.NewCache(cfg) - defer catfileCache.Stop() - - objectReader, err := catfileCache.ObjectReader(ctx, repo) - require.NoError(t, err) - - objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo) - require.NoError(t, err) - - info, err := objectInfoReader.Info(ctx, git.Revision(tc.originalOid)) - require.NoError(t, err) - - tagID := tc.originalOid - var tagName, tagMessage string - - for depth := 0; depth < tc.depth; depth++ { - tagName = fmt.Sprintf("tag-depth-%d", depth) - tagMessage = fmt.Sprintf("a commit %d deep", depth) - tagID = gittest.WriteTag(t, cfg, repoPath, tagName, tagID.Revision(), gittest.WriteTagConfig{Message: tagMessage}) - } - expectedTag := &gitalypb.Tag{ - Name: []byte(tagName), - Id: tagID.String(), - Message: []byte(tagMessage), - MessageSize: int64(len([]byte(tagMessage))), - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Scrooge McDuck"), - Email: []byte("scrooge@mcduck.com"), - Date: ×tamppb.Timestamp{Seconds: 1572776879}, - Timezone: []byte("+0100"), - }, - } - if info.Type == "commit" { - commit, err := catfile.GetCommit(ctx, objectReader, git.Revision(tc.originalOid)) - require.NoError(t, err) - expectedTag.TargetCommit = commit - } - rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: []byte(tagName)} - - resp, err := client.FindTag(ctx, rpcRequest) - require.NoError(t, err) - require.Equal(t, expectedTag, resp.GetTag()) - }) - } -} - -func TestInvalidFindTagRequest(t *testing.T) { - ctx := testhelper.Context(t) - _, repo, _, client := setupRefService(ctx, t) - - testCases := []struct { - desc string - request *gitalypb.FindTagRequest - }{ - { - desc: "empty request", - request: &gitalypb.FindTagRequest{}, - }, - { - desc: "invalid repo", - request: &gitalypb.FindTagRequest{ - Repository: &gitalypb.Repository{ - StorageName: "fake", - RelativePath: "repo", - }, - }, - }, - { - desc: "empty tag name", - request: &gitalypb.FindTagRequest{ - Repository: repo, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := client.FindTag(ctx, tc.request) - testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) - }) - } -} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches.go index 57ed609997..617c7fa003 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FindAllRemoteBranches(req *gitalypb.FindAllRemoteBranchesRequest, stream gitalypb.RefService_FindAllRemoteBranchesServer) error { @@ -31,10 +31,11 @@ func (s *server) findAllRemoteBranches(req *gitalypb.FindAllRemoteBranchesReques patterns := []string{"refs/remotes/" + req.GetRemoteName()} ctx := stream.Context() - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() opts := buildFindRefsOpts(ctx, nil) opts.cmdArgs = args diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches_test.go index 9fa8ba90c7..a3ec8843d4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/remote_branches_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/remote_branches_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/server.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/server.go index 825b7a0dd5..5d03b89130 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/server.go @@ -1,13 +1,13 @@ package ref import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages.go index 6f885ededa..ccb18a26db 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages.go @@ -5,11 +5,11 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -37,10 +37,11 @@ func (s *server) getAndStreamTagMessages(request *gitalypb.GetTagMessagesRequest ctx := stream.Context() repo := s.localrepo(request.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() for _, tagID := range request.GetTagIds() { tag, err := catfile.GetTag(ctx, objectReader, git.Revision(tagID), "") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages_test.go index 36d236d4eb..68199f401e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_messages_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_messages_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -6,10 +8,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures.go index 8bdf78479f..b73c5df6ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures.go @@ -6,11 +6,11 @@ import ( "io" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gitpipe" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -39,10 +39,11 @@ func (s *server) GetTagSignatures(req *gitalypb.GetTagSignaturesRequest, stream ctx := stream.Context() repo := s.localrepo(req.GetRepository()) - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return helper.ErrInternalf("creating object reader: %w", err) } + defer cancel() chunker := chunk.New(&tagSignatureSender{ send: func(signatures []*gitalypb.GetTagSignaturesResponse_TagSignature) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures_test.go index 3e0b7252c5..35f91762ea 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/tag_signatures_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/tag_signatures_test.go @@ -1,16 +1,19 @@ +//go:build !gitaly_test_sha256 + package ref import ( "errors" + "fmt" "io" "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -23,16 +26,16 @@ func TestGetTagSignatures(t *testing.T) { message1 := strings.Repeat("a", helper.MaxCommitOrTagMessageSize) + "\n" signature1 := string(testhelper.MustReadFile(t, "testdata/tag-1e292f8fedd741b75372e19097c76d327140c312-signature")) tag1ID := gittest.WriteTag(t, cfg, repoPath, "big-tag-1", "master", gittest.WriteTagConfig{Message: message1 + signature1}) - content1 := "object 1e292f8fedd741b75372e19097c76d327140c312\ntype commit\ntag big-tag-1\ntagger Scrooge McDuck 1572776879 +0100\n\n" + message1 + content1 := fmt.Sprintf("object 1e292f8fedd741b75372e19097c76d327140c312\ntype commit\ntag big-tag-1\ntagger %s\n\n%s", gittest.DefaultCommitterSignature, message1) message2 := strings.Repeat("b", helper.MaxCommitOrTagMessageSize) + "\n" signature2 := string(testhelper.MustReadFile(t, "testdata/tag-7975be0116940bf2ad4321f79d02a55c5f7779aa-signature")) tag2ID := gittest.WriteTag(t, cfg, repoPath, "big-tag-2", "master~", gittest.WriteTagConfig{Message: message2 + signature2}) - content2 := "object 7975be0116940bf2ad4321f79d02a55c5f7779aa\ntype commit\ntag big-tag-2\ntagger Scrooge McDuck 1572776879 +0100\n\n" + message2 + content2 := fmt.Sprintf("object 7975be0116940bf2ad4321f79d02a55c5f7779aa\ntype commit\ntag big-tag-2\ntagger %s\n\n%s", gittest.DefaultCommitterSignature, message2) message3 := "tag message\n" tag3ID := gittest.WriteTag(t, cfg, repoPath, "tag-3", "master~~", gittest.WriteTagConfig{Message: message3}) - content3 := "object 60ecb67744cb56576c30214ff52294f8ce2def98\ntype commit\ntag tag-3\ntagger Scrooge McDuck 1572776879 +0100\n\n" + message3 + content3 := fmt.Sprintf("object 60ecb67744cb56576c30214ff52294f8ce2def98\ntype commit\ntag tag-3\ntagger %s\n\n%s", gittest.DefaultCommitterSignature, message3) for _, tc := range []struct { desc string diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/branches.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/branches.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/branches.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/branches.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/tag-1e292f8fedd741b75372e19097c76d327140c312-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/tag-1e292f8fedd741b75372e19097c76d327140c312-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/tag-1e292f8fedd741b75372e19097c76d327140c312-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/tag-1e292f8fedd741b75372e19097c76d327140c312-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/tag-7975be0116940bf2ad4321f79d02a55c5f7779aa-signature b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/tag-7975be0116940bf2ad4321f79d02a55c5f7779aa-signature similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/tag-7975be0116940bf2ad4321f79d02a55c5f7779aa-signature rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/tag-7975be0116940bf2ad4321f79d02a55c5f7779aa-signature diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/truncated_pgp_msg.patch b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/truncated_pgp_msg.patch similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testdata/truncated_pgp_msg.patch rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testdata/truncated_pgp_msg.patch diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testhelper_test.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testhelper_test.go index b21d5a61dc..cd5e4ee1ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ref import ( @@ -6,17 +8,18 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) var localBranches = map[string]*gitalypb.GitCommit{ @@ -34,37 +37,37 @@ func TestMain(m *testing.M) { })) } -func setupRefService(ctx context.Context, t testing.TB) (config.Cfg, *gitalypb.Repository, string, gitalypb.RefServiceClient) { - cfg, client := setupRefServiceWithoutRepo(t) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ +func setupRefService(ctx context.Context, tb testing.TB) (config.Cfg, *gitalypb.Repository, string, gitalypb.RefServiceClient) { + cfg, client := setupRefServiceWithoutRepo(tb) + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) return cfg, repo, repoPath, client } -func setupRefServiceWithoutRepo(t testing.TB) (config.Cfg, gitalypb.RefServiceClient) { - cfg := testcfg.Build(t) +func setupRefServiceWithoutRepo(tb testing.TB) (config.Cfg, gitalypb.RefServiceClient) { + cfg := testcfg.Build(tb) - testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalyHooks(tb, cfg) - serverSocketPath := runRefServiceServer(t, cfg) + serverSocketPath := runRefServiceServer(tb, cfg) cfg.SocketPath = serverSocketPath - client, conn := newRefServiceClient(t, serverSocketPath) - t.Cleanup(func() { conn.Close() }) + client, conn := newRefServiceClient(tb, serverSocketPath) + tb.Cleanup(func() { conn.Close() }) return cfg, client } -func runRefServiceServer(t testing.TB, cfg config.Cfg) string { - return testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { +func runRefServiceServer(tb testing.TB, cfg config.Cfg) string { + return testserver.RunGitalyServer(tb, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterRefServiceServer(srv, NewServer( deps.GetLocator(), deps.GetGitCmdFactory(), deps.GetTxManager(), deps.GetCatfileCache(), )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( deps.GetCfg(), deps.GetRubyServer(), @@ -79,12 +82,12 @@ func runRefServiceServer(t testing.TB, cfg config.Cfg) string { }) } -func newRefServiceClient(t testing.TB, serverSocketPath string) (gitalypb.RefServiceClient, *grpc.ClientConn) { +func newRefServiceClient(tb testing.TB, serverSocketPath string) (gitalypb.RefServiceClient, *grpc.ClientConn) { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) - require.NoError(t, err) + require.NoError(tb, err) return gitalypb.NewRefServiceClient(conn), conn } @@ -99,7 +102,7 @@ func assertContainsLocalBranch(t *testing.T, branches []*gitalypb.FindLocalBranc } testhelper.ProtoEqual(t, branch.Commit, b.Commit) - return // Found the branch and it maches. Success! + return // Found the branch and it matches. Success! } } t.Errorf("Expected to find branch %q in local branches", branch.Name) @@ -118,7 +121,7 @@ func findLocalBranchResponsesEqual(a *gitalypb.FindLocalBranchResponse, b *gital findLocalBranchCommitAuthorsEqual(a.CommitCommitter, b.CommitCommitter) } -func assertContainsBranch(t *testing.T, branches []*gitalypb.FindAllBranchesResponse_Branch, branch *gitalypb.FindAllBranchesResponse_Branch) { +func assertContainsAllBranchesResponseBranch(t *testing.T, branches []*gitalypb.FindAllBranchesResponse_Branch, branch *gitalypb.FindAllBranchesResponse_Branch) { t.Helper() var branchNames [][]byte @@ -126,7 +129,23 @@ func assertContainsBranch(t *testing.T, branches []*gitalypb.FindAllBranchesResp for _, b := range branches { if bytes.Equal(branch.Name, b.Name) { testhelper.ProtoEqual(t, b.Target, branch.Target) - return // Found the branch and it maches. Success! + return // Found the branch and it matches. Success! + } + branchNames = append(branchNames, b.Name) + } + + t.Errorf("Expected to find branch %q in branches %s", branch.Name, branchNames) +} + +func assertContainsBranch(t *testing.T, branches []*gitalypb.Branch, branch *gitalypb.Branch) { + t.Helper() + + var branchNames [][]byte + + for _, b := range branches { + if bytes.Equal(branch.Name, b.Name) { + testhelper.ProtoEqual(t, b.TargetCommit, branch.TargetCommit) + return // Found the branch and it matches. Success! } branchNames = append(branchNames, b.Name) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util.go index 375715967a..309a5ad773 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util.go @@ -5,10 +5,11 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) var localBranchFormatFields = []string{"%(refname)", "%(objectname)"} @@ -84,23 +85,48 @@ func buildBranch(ctx context.Context, objectReader catfile.ObjectReader, element func newFindLocalBranchesWriter(stream gitalypb.RefService_FindLocalBranchesServer, objectReader catfile.ObjectReader) lines.Sender { return func(refs [][]byte) error { - var branches []*gitalypb.FindLocalBranchResponse ctx := stream.Context() + var response *gitalypb.FindLocalBranchesResponse - for _, ref := range refs { - elements, err := parseRef(ref) - if err != nil { - return err + if featureflag.SimplifyFindLocalBranchesResponse.IsEnabled(ctx) { + var branches []*gitalypb.Branch + + for _, ref := range refs { + elements, err := parseRef(ref) + if err != nil { + return err + } + + branch, err := buildBranch(ctx, objectReader, elements) + if err != nil { + return err + } + + branches = append(branches, branch) } - target, err := catfile.GetCommit(ctx, objectReader, git.Revision(elements[1])) - if err != nil { - return err + response = &gitalypb.FindLocalBranchesResponse{LocalBranches: branches} + } else { + var branches []*gitalypb.FindLocalBranchResponse + + for _, ref := range refs { + elements, err := parseRef(ref) + if err != nil { + return err + } + + target, err := catfile.GetCommit(ctx, objectReader, git.Revision(elements[1])) + if err != nil { + return err + } + + branches = append(branches, buildLocalBranch(elements[0], target)) } - branches = append(branches, buildLocalBranch(elements[0], target)) + response = &gitalypb.FindLocalBranchesResponse{Branches: branches} } - return stream.Send(&gitalypb.FindLocalBranchesResponse{Branches: branches}) + + return stream.Send(response) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util_test.go index 38550b156a..9c17825d1f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref/util_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref/util_test.go @@ -1,10 +1,12 @@ +//go:build !gitaly_test_sha256 + package ref import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository.go index 5504da6863..4b537ec3ee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository.go @@ -5,8 +5,8 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository_test.go index 23e2afa12a..2cd1b2263f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package remote import ( @@ -8,8 +10,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref.go index 2929fe9c19..7ec4012e56 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref.go @@ -6,9 +6,9 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref_test.go index 34ab682521..193946176b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/find_remote_root_ref_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/find_remote_root_ref_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package remote import ( @@ -7,11 +9,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -63,7 +65,7 @@ func TestFindRemoteRootRefWithUnbornRemoteHead(t *testing.T) { // We're creating an empty repository. Empty repositories do have a HEAD set up, but they // point to an unborn branch because the default branch hasn't yet been created. - _, clientRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + _, clientRepoPath := gittest.CreateRepository(ctx, t, cfg) gittest.Exec(t, cfg, "-C", remoteRepoPath, "remote", "add", "foo", "file://"+clientRepoPath) response, err := client.FindRemoteRootRef(ctx, &gitalypb.FindRemoteRootRefRequest{ Repository: remoteRepo, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/server.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/server.go index 0341051964..7bb69474e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/server.go @@ -1,14 +1,14 @@ package remote import ( - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/testdata/lsremotedata.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/testdata/lsremotedata.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/testdata/lsremotedata.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/testdata/lsremotedata.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/testhelper_test.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/testhelper_test.go index db36b43cac..f0a84b3584 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/testhelper_test.go @@ -1,18 +1,21 @@ +//go:build !gitaly_test_sha256 + package remote import ( "context" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func TestMain(m *testing.M) { @@ -60,7 +63,7 @@ func newRemoteClient(t *testing.T, serverSocketPath string) (gitalypb.RemoteServ t.Helper() connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror.go index 5ff3d53e58..9aeb5161ce 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror.go @@ -8,11 +8,11 @@ import ( "regexp" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -185,7 +185,7 @@ func (s *server) updateRemoteMirror(stream gitalypb.RemoteService_UpdateRemoteMi continue } - // The commit in the extra branch in the remote repositoy has not been merged in to the + // The commit in the extra branch in the remote repository has not been merged in to the // local repository's default branch. Keep it to avoid losing work. delete(toDelete, remoteRef) } @@ -234,7 +234,7 @@ func (s *server) updateRemoteMirror(stream gitalypb.RemoteService_UpdateRemoteMi // be updated in the mirror repository. Tags are always matched successfully. // branchMatchers optionally contain patterns that are used to match branches. // The patterns should only include the branch name without the `refs/heads/` -// prefix. "*" can be used as a wilcard in the patterns. If no branchMatchers +// prefix. "*" can be used as a wildcard in the patterns. If no branchMatchers // are specified, all branches are matched successfully. func newReferenceMatcher(branchMatchers [][]byte) (*regexp.Regexp, error) { sb := &strings.Builder{} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror_test.go index 5d624c531e..18f0717871 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote/update_remote_mirror_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote/update_remote_mirror_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package remote import ( @@ -9,19 +11,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - repositorysvc "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + repositorysvc "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) @@ -324,13 +326,13 @@ func TestUpdateRemoteMirror(t *testing.T) { "refs/heads/non-diverging": {"commit-3"}, }, keepDivergentRefs: true, - wrapCommandFactory: func(t testing.TB, original git.CommandFactory) git.CommandFactory { + wrapCommandFactory: func(tb testing.TB, original git.CommandFactory) git.CommandFactory { return commandFactoryWrapper{ CommandFactory: original, newFunc: func(ctx context.Context, repo repository.GitRepo, sc git.Cmd, opts ...git.CmdOpt) (*command.Command, error) { if sc.Subcommand() == "push" { subCmd, ok := sc.(git.SubCmd) - require.True(t, ok) + require.True(tb, ok) // This is really hacky: we extract the // remote name from the subcommands @@ -338,7 +340,7 @@ func TestUpdateRemoteMirror(t *testing.T) { // how we hijack the command factory is kind // of hacky in the first place. remoteName := subCmd.Args[0] - require.Contains(t, remoteName, "inmemory-") + require.Contains(tb, remoteName, "inmemory-") // Make the branch diverge on the remote before actually performing the pushes the RPC // is attempting to perform to simulate a ref diverging after the RPC has performed @@ -348,10 +350,10 @@ func TestUpdateRemoteMirror(t *testing.T) { Flags: []git.Option{git.Flag{Name: "--force"}}, Args: []string{remoteName, "refs/heads/non-diverging:refs/heads/diverging"}, }, opts...) - if !assert.NoError(t, err) { + if !assert.NoError(tb, err) { return nil, err } - assert.NoError(t, cmd.Wait()) + assert.NoError(tb, cmd.Wait()) } return original.New(ctx, repo, sc, opts...) @@ -425,7 +427,7 @@ func TestUpdateRemoteMirror(t *testing.T) { }, { desc: "pushes default branch in the first batch", - wrapCommandFactory: func(t testing.TB, original git.CommandFactory) git.CommandFactory { + wrapCommandFactory: func(tb testing.TB, original git.CommandFactory) git.CommandFactory { firstPush := true return commandFactoryWrapper{ CommandFactory: original, @@ -433,8 +435,8 @@ func TestUpdateRemoteMirror(t *testing.T) { if sc.Subcommand() == "push" && firstPush { firstPush = false args, err := sc.CommandArgs() - assert.NoError(t, err) - assert.Contains(t, args, "refs/heads/master", "first push should contain the default branch") + assert.NoError(tb, err) + assert.Contains(tb, args, "refs/heads/master", "first push should contain the default branch") } return original.New(ctx, repo, sc, opts...) @@ -558,7 +560,7 @@ func TestUpdateRemoteMirror(t *testing.T) { for _, commit := range commits { var err error commitOID, err = executor.Commit(ctx, gittest.RewrittenRepository(ctx, t, cfg, c.repoProto), - git2go.CommitParams{ + git2go.CommitCommand{ Repository: c.repoPath, Author: commitSignature, Committer: commitSignature, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes.go index 5167176e7b..460a86ba56 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes.go @@ -9,15 +9,15 @@ import ( "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const attributesFileMode os.FileMode = 0o644 @@ -64,7 +64,7 @@ func (s *server) applyGitattributes(ctx context.Context, repo *localrepo.Repo, o // We use the zero OID as placeholder to vote on removal of the // gitattributes file. - if err := s.vote(ctx, git.ZeroOID, voting.Prepared); err != nil { + if err := s.vote(ctx, git.ObjectHashSHA1.ZeroOID, voting.Prepared); err != nil { return fmt.Errorf("preimage vote: %w", err) } @@ -72,7 +72,7 @@ func (s *server) applyGitattributes(ctx context.Context, repo *localrepo.Repo, o return err } - if err := s.vote(ctx, git.ZeroOID, voting.Committed); err != nil { + if err := s.vote(ctx, git.ObjectHashSHA1.ZeroOID, voting.Committed); err != nil { return fmt.Errorf("postimage vote: %w", err) } @@ -132,10 +132,11 @@ func (s *server) ApplyGitattributes(ctx context.Context, in *gitalypb.ApplyGitat return nil, helper.ErrInvalidArgumentf("revision: %v", err) } - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return nil, err } + defer cancel() if err := s.applyGitattributes(ctx, repo, objectReader, repoPath, in.GetRevision()); err != nil { return nil, err diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes_test.go index 802e3db7df..ddfc888fc9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/apply_gitattributes_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/apply_gitattributes_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -11,15 +13,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -92,26 +92,14 @@ func TestApplyGitattributesWithTransaction(t *testing.T) { cfg, repo, repoPath := testcfg.BuildWithRepo(t) transactionServer := &testTransactionServer{} - testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterRepositoryServiceServer(srv, NewServer( - deps.GetCfg(), - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }) + runRepositoryService(t, cfg, nil) // We're using internal listener in order to route around // Praefect in our tests. Otherwise Praefect would replace our // carefully crafted transaction and server information. logger := testhelper.NewDiscardingLogEntry(t) - client := newMuxedRepositoryClient(t, ctx, cfg, "unix://"+cfg.GitalyInternalSocketPath(), + client := newMuxedRepositoryClient(t, ctx, cfg, "unix://"+cfg.InternalSocketPath(), backchannel.NewClientHandshaker(logger, func() backchannel.Server { srv := grpc.NewServer() gitalypb.RegisterRefTransactionServer(srv, transactionServer) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive.go index 878572f91e..b2688fcb75 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive.go @@ -4,44 +4,37 @@ import ( "context" "crypto/sha256" "encoding/hex" - "encoding/json" "fmt" "io" "os" - "os/exec" - "path/filepath" "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/protobuf/proto" ) type archiveParams struct { - ctx context.Context - writer io.Writer - in *gitalypb.GetArchiveRequest - compressCmd *exec.Cmd - format string - archivePath string - exclude []string - internalCfg []byte - tlsCfg []byte - binDir string - loggingDir string + writer io.Writer + in *gitalypb.GetArchiveRequest + compressArgs []string + format string + archivePath string + exclude []string + loggingDir string } func (s *server) GetArchive(in *gitalypb.GetArchiveRequest, stream gitalypb.RepositoryService_GetArchiveServer) error { ctx := stream.Context() - compressCmd, format := parseArchiveFormat(in.GetFormat()) + compressArgs, format := parseArchiveFormat(in.GetFormat()) repo := s.localrepo(in.GetRepository()) repoRoot, err := repo.Path() @@ -86,41 +79,27 @@ func (s *server) GetArchive(in *gitalypb.GetArchiveRequest, stream gitalypb.Repo return stream.Send(&gitalypb.GetArchiveResponse{Data: p}) }) - gitlabConfig, err := json.Marshal(s.cfg.Gitlab) - if err != nil { - return err - } - - tlsCfg, err := json.Marshal(s.cfg.TLS) - if err != nil { - return err - } - ctxlogrus.Extract(ctx).WithField("request_hash", requestHash(in)).Info("request details") - return s.handleArchive(archiveParams{ - ctx: ctx, - writer: writer, - in: in, - compressCmd: compressCmd, - format: format, - archivePath: path, - exclude: exclude, - internalCfg: gitlabConfig, - tlsCfg: tlsCfg, - binDir: s.binDir, - loggingDir: s.loggingCfg.Dir, + return s.handleArchive(ctx, archiveParams{ + writer: writer, + in: in, + compressArgs: compressArgs, + format: format, + archivePath: path, + exclude: exclude, + loggingDir: s.loggingCfg.Dir, }) } -func parseArchiveFormat(format gitalypb.GetArchiveRequest_Format) (*exec.Cmd, string) { +func parseArchiveFormat(format gitalypb.GetArchiveRequest_Format) ([]string, string) { switch format { case gitalypb.GetArchiveRequest_TAR: return nil, "tar" case gitalypb.GetArchiveRequest_TAR_GZ: - return exec.Command("gzip", "-c", "-n"), "tar" + return []string{"gzip", "-c", "-n"}, "tar" case gitalypb.GetArchiveRequest_TAR_BZ2: - return exec.Command("bzip2", "-c"), "tar" + return []string{"bzip2", "-c"}, "tar" case gitalypb.GetArchiveRequest_ZIP: return nil, "zip" } @@ -147,15 +126,17 @@ func (s *server) validateGetArchivePrecondition( path string, exclude []string, ) error { - objectReader, err := s.catfileCache.ObjectReader(ctx, repo) + objectReader, cancel, err := s.catfileCache.ObjectReader(ctx, repo) if err != nil { return err } + defer cancel() - objectInfoReader, err := s.catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(ctx, repo) if err != nil { return err } + defer cancel() f := catfile.NewTreeEntryFinder(objectReader, objectInfoReader) if path != "." { @@ -189,7 +170,7 @@ func findGetArchivePath(ctx context.Context, f *catfile.TreeEntryFinder, commitI return true, nil } -func (s *server) handleArchive(p archiveParams) error { +func (s *server) handleArchive(ctx context.Context, p archiveParams) error { var args []string pathspecs := make([]string, 0, len(p.exclude)+1) if !p.in.GetElidePath() { @@ -208,23 +189,36 @@ func (s *server) handleArchive(p archiveParams) error { pathspecs = append(pathspecs, ":(exclude)"+exclude) } - env := []string{ - fmt.Sprintf("GL_REPOSITORY=%s", p.in.GetRepository().GetGlRepository()), - fmt.Sprintf("GL_PROJECT_PATH=%s", p.in.GetRepository().GetGlProjectPath()), - fmt.Sprintf("GL_INTERNAL_CONFIG=%s", p.internalCfg), - fmt.Sprintf("GITALY_TLS=%s", p.tlsCfg), - fmt.Sprintf("CORRELATION_ID=%s", correlation.ExtractFromContext(p.ctx)), - fmt.Sprintf("%s=%s", log.GitalyLogDirEnvKey, p.loggingDir), - } - + var env []string var config []git.ConfigPair if p.in.GetIncludeLfsBlobs() { - binary := filepath.Join(p.binDir, "gitaly-lfs-smudge") - config = append(config, git.ConfigPair{Key: "filter.lfs.smudge", Value: binary}) + smudgeCfg := smudge.Config{ + GlRepository: p.in.GetRepository().GetGlRepository(), + Gitlab: s.cfg.Gitlab, + TLS: s.cfg.TLS, + DriverType: smudge.DriverTypeProcess, + } + + smudgeEnv, err := smudgeCfg.Environment() + if err != nil { + return fmt.Errorf("setting up smudge environment: %w", err) + } + + smudgeGitConfig, err := smudgeCfg.GitConfiguration(s.cfg) + if err != nil { + return fmt.Errorf("setting up smudge gitconfig: %w", err) + } + + env = append( + env, + smudgeEnv, + fmt.Sprintf("%s=%s", log.GitalyLogDirEnvKey, p.loggingDir), + ) + config = append(config, smudgeGitConfig) } - archiveCommand, err := s.gitCmdFactory.New(p.ctx, p.in.GetRepository(), git.SubCmd{ + archiveCommand, err := s.gitCmdFactory.New(ctx, p.in.GetRepository(), git.SubCmd{ Name: "archive", Flags: []git.Option{git.ValueFlag{Name: "--format", Value: p.format}, git.ValueFlag{Name: "--prefix", Value: p.in.GetPrefix() + "/"}}, Args: args, @@ -234,8 +228,10 @@ func (s *server) handleArchive(p archiveParams) error { return err } - if p.compressCmd != nil { - command, err := command.New(p.ctx, p.compressCmd, archiveCommand, p.writer, nil) + if len(p.compressArgs) > 0 { + command, err := command.New(ctx, p.compressArgs, + command.WithStdin(archiveCommand), command.WithStdout(p.writer), + ) if err != nil { return err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive_test.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive_test.go index ac8f32de0a..b5ac1f0d23 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/archive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/archive_test.go @@ -1,9 +1,10 @@ +//go:build !gitaly_test_sha256 + package repository import ( "archive/zip" "bytes" - "encoding/json" "fmt" "io" "os" @@ -12,15 +13,17 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/codes" ) @@ -30,8 +33,9 @@ const ( lfsBody = "hello world\n" ) -func TestGetArchiveSuccess(t *testing.T) { +func TestGetArchive_success(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) _, repo, _, client := setupRepositoryService(ctx, t) @@ -147,13 +151,7 @@ func TestGetArchiveSuccess(t *testing.T) { data, err := consumeArchive(stream) require.NoError(t, err) - archiveFile, err := os.Create(filepath.Join(testhelper.TempDir(t), "archive")) - require.NoError(t, err) - - _, err = archiveFile.Write(data) - require.NoError(t, err) - - contents := string(compressedFileContents(t, format, archiveFile.Name())) + contents := compressedFileContents(t, format, data) for _, content := range tc.contents { require.Contains(t, contents, tc.prefix+content) @@ -167,8 +165,11 @@ func TestGetArchiveSuccess(t *testing.T) { } } -func TestGetArchiveWithLfsSuccess(t *testing.T) { +func TestGetArchive_includeLfsBlobs(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) + defaultOptions := gitlab.TestServerOptions{ SecretToken: secretToken, LfsBody: lfsBody, @@ -187,11 +188,9 @@ func TestGetArchiveWithLfsSuccess(t *testing.T) { }, })) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil) - client := newRepositoryClient(t, cfg, serverSocketPath) + client, serverSocketPath := runRepositoryService(t, cfg, nil) cfg.SocketPath = serverSocketPath - ctx := testhelper.Context(t) repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -279,8 +278,9 @@ func TestGetArchiveWithLfsSuccess(t *testing.T) { } } -func TestGetArchiveFailure(t *testing.T) { +func TestGetArchive_inputValidation(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) _, repo, _, client := setupRepositoryService(ctx, t) @@ -405,135 +405,156 @@ func TestGetArchiveFailure(t *testing.T) { } } -func TestGetArchivePathInjection(t *testing.T) { +func TestGetArchive_pathInjection(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupRepositoryServiceWithWorktree(ctx, t) + cfg, repo, repoPath, client := setupRepositoryService(ctx, t) - // Adding a temp directory representing the .ssh directory - sshDirectory := testhelper.TempDir(t) + // It used to be possible to inject options into `git-archive(1)`, with the worst outcome + // being that an adversary may create or overwrite arbitrary files in the filesystem in case + // they passed `--output`. + // + // We pretend that the adversary wants to override a fixed file `/non/existent`. In + // practice, thus would be something more interesting like `/etc/shadow` or `allowed_keys`. + // We then create a file inside the repository itself that has `--output=/non/existent` as + // relative path. This is done to verify that git-archive(1) indeed treats the parameter as + // a path and does not interpret it as an option. + outputPath := "/non/existent" - // Adding an empty authorized_keys file - authorizedKeysPath := filepath.Join(sshDirectory, "authorized_keys") + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTree(gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "--output=", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "non", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "existent", Mode: "040000", OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "injected file", Mode: "100644", Content: "injected content"}, + })}, + })}, + })}, + }))) - authorizedKeysFile, err := os.Create(authorizedKeysPath) - require.NoError(t, err) - require.NoError(t, authorizedKeysFile.Close()) - - // Create the directory on the repository - repoExploitPath := filepath.Join(repoPath, "--output=", authorizedKeysPath) - require.NoError(t, os.MkdirAll(repoExploitPath, os.ModeDir|0o755)) - - f, err := os.Create(filepath.Join(repoExploitPath, "id_12345.pub")) - require.NoError(t, err) - - evilPubKeyFile := `# - ssh-ed25519 my_super_evil_ssh_pubkey - #` - - _, err = fmt.Fprint(f, evilPubKeyFile) - require.NoError(t, err) - require.NoError(t, f.Close()) - - // Add the directory to the repository - gittest.Exec(t, cfg, "-C", repoPath, "add", ".") - gittest.Exec(t, cfg, "-C", repoPath, "commit", "-m", "adding fake key file") - commitID := strings.TrimRight(string(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")), "\n") - - injectionPath := fmt.Sprintf("--output=%s", authorizedKeysPath) - - req := &gitalypb.GetArchiveRequest{ + // And now we fire the request path our bogus path to try and overwrite the output path. + stream, err := client.GetArchive(ctx, &gitalypb.GetArchiveRequest{ Repository: repo, - CommitId: commitID, + CommitId: commitID.String(), Prefix: "", Format: gitalypb.GetArchiveRequest_TAR, - Path: []byte(injectionPath), - } - - stream, err := client.GetArchive(ctx, req) + Path: []byte("--output=" + outputPath), + }) require.NoError(t, err) - _, err = consumeArchive(stream) + content, err := consumeArchive(stream) require.NoError(t, err) - authorizedKeysFile, err = os.Open(authorizedKeysPath) - require.NoError(t, err) - defer authorizedKeysFile.Close() - - authorizedKeysFileBytes, err := io.ReadAll(authorizedKeysFile) - require.NoError(t, err) - authorizedKeysFileStat, err := authorizedKeysFile.Stat() - require.NoError(t, err) - - require.NotContains(t, string(authorizedKeysFileBytes), evilPubKeyFile) // this should fail first in pre-fix failing test - require.Zero(t, authorizedKeysFileStat.Size()) + require.NoFileExists(t, outputPath) + require.Equal(t, + strings.Join([]string{ + "/", + "/--output=/", + "/--output=/non/", + "/--output=/non/existent/", + "/--output=/non/existent/injected file", + }, "\n"), + compressedFileContents(t, gitalypb.GetArchiveRequest_TAR, content), + ) } -func TestGetArchiveEnv(t *testing.T) { - testhelper.SkipWithPraefect(t, "It's not possible to create repositories through the API with the git command overwritten by the script.") - +func TestGetArchive_environment(t *testing.T) { t.Parallel() - cfg := testcfg.Build(t) - ctx := testhelper.Context(t) + testhelper.SkipWithPraefect(t, "It's not possible to create repositories through the API with the git command overwritten by the script.") - gitCmdFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(git.ExecutionEnvironment) string { - return `#!/bin/sh + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + // Intercept commands to git-archive(1) to print the environment. Note that we continue to + // execute any other Git commands so that the command factory behaves as expected. + gitCmdFactory := gittest.NewInterceptingCommandFactory(ctx, t, cfg, func(execEnv git.ExecutionEnvironment) string { + return fmt.Sprintf(`#!/bin/bash + if [[ ! "$@" =~ "archive" ]]; then + exec %q "$@" + fi env | grep -E '^GL_|CORRELATION|GITALY_' - ` + `, execEnv.BinaryPath) }) testcfg.BuildGitalyHooks(t, cfg) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil, testserver.WithGitCommandFactory(gitCmdFactory)) + client, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithGitCommandFactory(gitCmdFactory)) cfg.SocketPath = serverSocketPath - client := newRepositoryClient(t, cfg, serverSocketPath) - - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) commitID := "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" correlationID := correlation.SafeRandomID() ctx = correlation.ContextWithCorrelation(ctx, correlationID) - req := &gitalypb.GetArchiveRequest{ - Repository: repo, - CommitId: commitID, + smudgeCfg := smudge.Config{ + GlRepository: gittest.GlRepository, + Gitlab: cfg.Gitlab, + TLS: cfg.TLS, + DriverType: smudge.DriverTypeProcess, } - cfgData, err := json.Marshal(cfg.Gitlab) + smudgeEnv, err := smudgeCfg.Environment() require.NoError(t, err) - tlsCfgData, err := json.Marshal(cfg.TLS) - require.NoError(t, err) + for _, tc := range []struct { + desc string + includeLFSBlobs bool + expectedEnv []string + }{ + { + desc: "without LFS blobs", + includeLFSBlobs: false, + expectedEnv: []string{ + "CORRELATION_ID=" + correlationID, + }, + }, + { + desc: "with LFS blobs", + includeLFSBlobs: true, + expectedEnv: []string{ + "CORRELATION_ID=" + correlationID, + smudgeEnv, + "GITALY_LOG_DIR=" + cfg.Logging.Dir, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + stream, err := client.GetArchive(ctx, &gitalypb.GetArchiveRequest{ + Repository: repo, + CommitId: commitID, + IncludeLfsBlobs: tc.includeLFSBlobs, + }) + require.NoError(t, err) - stream, err := client.GetArchive(ctx, req) - require.NoError(t, err) - - data, err := consumeArchive(stream) - require.NoError(t, err) - require.Contains(t, string(data), "GL_REPOSITORY="+gittest.GlRepository) - require.Contains(t, string(data), "GL_PROJECT_PATH="+gittest.GlProjectPath) - require.Contains(t, string(data), "GL_INTERNAL_CONFIG="+string(cfgData)) - require.Contains(t, string(data), "GITALY_TLS="+string(tlsCfgData)) - require.Contains(t, string(data), "CORRELATION_ID="+correlationID) - require.Contains(t, string(data), "GITALY_LOG_DIR="+cfg.Logging.Dir) + data, err := consumeArchive(stream) + require.NoError(t, err) + require.ElementsMatch(t, tc.expectedEnv, strings.Split(text.ChompBytes(data), "\n")) + }) + } } -func compressedFileContents(t *testing.T, format gitalypb.GetArchiveRequest_Format, name string) []byte { +func compressedFileContents(t *testing.T, format gitalypb.GetArchiveRequest_Format, contents []byte) string { + path := filepath.Join(testhelper.TempDir(t), "archive") + require.NoError(t, os.WriteFile(path, contents, 0o644)) + switch format { case gitalypb.GetArchiveRequest_TAR: - return testhelper.MustRunCommand(t, nil, "tar", "tf", name) + return text.ChompBytes(testhelper.MustRunCommand(t, nil, "tar", "tf", path)) case gitalypb.GetArchiveRequest_TAR_GZ: - return testhelper.MustRunCommand(t, nil, "tar", "ztf", name) + return text.ChompBytes(testhelper.MustRunCommand(t, nil, "tar", "ztf", path)) case gitalypb.GetArchiveRequest_TAR_BZ2: - return testhelper.MustRunCommand(t, nil, "tar", "jtf", name) + return text.ChompBytes(testhelper.MustRunCommand(t, nil, "tar", "jtf", path)) case gitalypb.GetArchiveRequest_ZIP: - return testhelper.MustRunCommand(t, nil, "unzip", "-l", name) + return text.ChompBytes(testhelper.MustRunCommand(t, nil, "unzip", "-l", path)) + default: + require.FailNow(t, "unsupported archive format: %v", format) + return "" } - - return nil } func consumeArchive(stream gitalypb.RepositoryService_GetArchiveClient) ([]byte, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks.go index 4f06837240..9a44385d7c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks.go @@ -2,12 +2,11 @@ package repository import ( "os" - "os/exec" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -29,8 +28,8 @@ func (s *server) BackupCustomHooks(in *gitalypb.BackupCustomHooksRequest, stream } ctx := stream.Context() - tar := exec.Command("tar", "-c", "-f", "-", "-C", repoPath, customHooksDir) - cmd, err := command.New(ctx, tar, nil, writer, nil) + tar := []string{"tar", "-c", "-f", "-", "-C", repoPath, customHooksDir} + cmd, err := command.New(ctx, tar, command.WithStdout(writer)) if err != nil { return status.Errorf(codes.Internal, "%v", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks_test.go index 8582ddd6dd..25e898cda9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/backup_custom_hooks_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/backup_custom_hooks_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,9 +12,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func TestSuccessfullBackupCustomHooksRequest(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum.go index 9d57a4cb33..3407936ec7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum.go @@ -7,8 +7,8 @@ import ( "encoding/hex" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -43,7 +43,7 @@ func (s *server) CalculateChecksum(ctx context.Context, in *gitalypb.CalculateCh if err := cmd.Wait(); checksum.IsZero() || err != nil { if s.isValidRepo(ctx, repo) { - return &gitalypb.CalculateChecksumResponse{Checksum: git.ZeroOID.String()}, nil + return &gitalypb.CalculateChecksumResponse{Checksum: git.ObjectHashSHA1.ZeroOID.String()}, nil } return nil, status.Errorf(codes.DataLoss, "CalculateChecksum: not a git repository '%s'", repoPath) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum_test.go index 7762742f3e..e8f705904a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/calculate_checksum_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/calculate_checksum_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -7,10 +9,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -38,31 +40,33 @@ func TestSuccessfulCalculateChecksum(t *testing.T) { func TestEmptyRepositoryCalculateChecksum(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) cfg, client := setupRepositoryServiceWithoutRepo(t) - testCtx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(testCtx, t, cfg) + repo, _ := gittest.CreateRepository(ctx, t, cfg) request := &gitalypb.CalculateChecksumRequest{Repository: repo} - response, err := client.CalculateChecksum(testCtx, request) + response, err := client.CalculateChecksum(ctx, request) require.NoError(t, err) - require.Equal(t, git.ZeroOID.String(), response.Checksum) + require.Equal(t, git.ObjectHashSHA1.ZeroOID.String(), response.Checksum) } func TestBrokenRepositoryCalculateChecksum(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) cfg, client := setupRepositoryServiceWithoutRepo(t) - testCtx := testhelper.Context(t) - repo, repoPath := gittest.CreateRepository(testCtx, t, cfg) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) // Force an empty HEAD file require.NoError(t, os.Truncate(filepath.Join(repoPath, "HEAD"), 0)) request := &gitalypb.CalculateChecksumRequest{Repository: repo} - _, err := client.CalculateChecksum(testCtx, request) + _, err := client.CalculateChecksum(ctx, request) testhelper.RequireGrpcCode(t, err, codes.DataLoss) } @@ -114,5 +118,5 @@ func TestInvalidRefsCalculateChecksum(t *testing.T) { response, err := client.CalculateChecksum(ctx, request) require.NoError(t, err) - require.Equal(t, git.ZeroOID.String(), response.Checksum) + require.Equal(t, git.ObjectHashSHA1.ZeroOID.String(), response.Checksum) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup.go index 2953e43505..6c3668126c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup.go @@ -3,10 +3,10 @@ package repository import ( "context" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) Cleanup(ctx context.Context, in *gitalypb.CleanupRequest) (*gitalypb.CleanupResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup_test.go index 862ee0e5bf..3f8901a5a6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/cleanup_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/cleanup_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -9,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph.go index c5db827009..1e340b8340 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph.go @@ -3,10 +3,10 @@ package repository import ( "context" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // WriteCommitGraph write or update commit-graph file in a repository @@ -24,7 +24,12 @@ func (s *server) WriteCommitGraph( return nil, helper.ErrInvalidArgumentf("unsupported split strategy: %v", in.GetSplitStrategy()) } - if err := housekeeping.WriteCommitGraph(ctx, repo); err != nil { + writeCommitGraphCfg, err := housekeeping.WriteCommitGraphConfigForRepository(ctx, repo) + if err != nil { + return nil, helper.ErrInternalf("getting commit-graph config: %w", err) + } + + if err := housekeeping.WriteCommitGraph(ctx, repo, writeCommitGraphCfg); err != nil { return nil, err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph_test.go index c55c64665e..3d59dd2720 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/commit_graph_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/commit_graph_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -9,11 +11,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -142,12 +144,12 @@ func TestWriteCommitGraph_validationChecks(t *testing.T) { { desc: "invalid storage", req: &gitalypb.WriteCommitGraphRequest{Repository: &gitalypb.Repository{StorageName: "invalid"}}, - expErr: status.Error(codes.InvalidArgument, `GetStorageByName: no such storage: "invalid"`), + expErr: status.Error(codes.InvalidArgument, `getting commit-graph config: GetStorageByName: no such storage: "invalid"`), }, { desc: "not existing repository", req: &gitalypb.WriteCommitGraphRequest{Repository: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "invalid"}}, - expErr: status.Error(codes.NotFound, fmt.Sprintf(`GetRepoPath: not a git repository: "%s/invalid"`, cfg.Storages[0].Path)), + expErr: status.Error(codes.NotFound, fmt.Sprintf(`getting commit-graph config: GetRepoPath: not a git repository: "%s/invalid"`, cfg.Storages[0].Path)), }, } { t.Run(tc.desc, func(t *testing.T) { @@ -204,21 +206,21 @@ func TestUpdateCommitGraph(t *testing.T) { assertModTimeAfter(t, mt, chainPath) } -func requireBloomFilterUsed(t testing.TB, repoPath string) { - t.Helper() +func requireBloomFilterUsed(tb testing.TB, repoPath string) { + tb.Helper() commitGraphsPath := filepath.Join(repoPath, stats.CommitGraphChainRelPath) - ids := bytes.Split(testhelper.MustReadFile(t, commitGraphsPath), []byte{'\n'}) + ids := bytes.Split(testhelper.MustReadFile(tb, commitGraphsPath), []byte{'\n'}) for _, id := range ids { if len(id) == 0 { continue } graphFilePath := filepath.Join(repoPath, filepath.Dir(stats.CommitGraphChainRelPath), fmt.Sprintf("graph-%s.graph", id)) - graphFileData := testhelper.MustReadFile(t, graphFilePath) + graphFileData := testhelper.MustReadFile(tb, graphFilePath) - require.True(t, bytes.HasPrefix(graphFileData, []byte("CGPH")), "4-byte signature of the commit graph file") - require.True(t, bytes.Contains(graphFileData, []byte("BIDX")), "Bloom Filter Index") - require.True(t, bytes.Contains(graphFileData, []byte("BDAT")), "Bloom Filter Data") + require.True(tb, bytes.HasPrefix(graphFileData, []byte("CGPH")), "4-byte signature of the commit graph file") + require.True(tb, bytes.Contains(graphFileData, []byte("BIDX")), "Bloom Filter Index") + require.True(tb, bytes.Contains(graphFileData, []byte("BDAT")), "Bloom Filter Data") } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config.go index a0a7f420cf..b972a89a8f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config.go @@ -5,9 +5,9 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config_test.go index 18085e9331..b07de01f51 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/config_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/config_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,10 +10,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle.go index 7445103021..67127f0e92 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle.go @@ -3,10 +3,10 @@ package repository import ( "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list.go index 64b0057d23..b8ba37c6ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list.go @@ -4,10 +4,10 @@ import ( "bytes" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go index 9616137e35..ad101c775e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -9,11 +11,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_test.go index de98f8bec6..5af46df833 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_bundle_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_bundle_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,12 +10,12 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork.go index f6e5f66cff..7566a93441 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork.go @@ -4,10 +4,11 @@ import ( "context" "fmt" "os" + "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -38,24 +39,38 @@ func (s *server) CreateFork(ctx context.Context, req *gitalypb.CreateForkRequest // Ideally we'd just fetch into the already-created repo, but that wouldn't // allow us to easily set up HEAD to point to the correct ref. We thus have // no easy choice but to use git-clone(1). - cmd, err := s.gitCmdFactory.NewWithoutRepo(ctx, git.SubCmd{ - Name: "clone", - Flags: []git.Option{ - git.Flag{Name: "--bare"}, + var stderr strings.Builder + cmd, err := s.gitCmdFactory.NewWithoutRepo(ctx, + git.SubCmd{ + Name: "clone", + Flags: []git.Option{ + git.Flag{Name: "--bare"}, + git.Flag{Name: "--quiet"}, + }, + Args: []string{ + git.InternalGitalyURL, + targetPath, + }, }, - Args: []string{ - git.InternalGitalyURL, - targetPath, - }, - }, git.WithInternalFetch(&gitalypb.SSHUploadPackRequest{ - Repository: sourceRepository, - }), git.WithDisabledHooks()) + git.WithInternalFetch(&gitalypb.SSHUploadPackRequest{ + Repository: sourceRepository, + }), + git.WithConfig(git.ConfigPair{ + // Disable consistency checks for fetched objects when creating a + // fork. We don't want to end up in a situation where it's + // impossible to create forks we already have anyway because we have + // e.g. retroactively tightened the consistency checks. + Key: "fetch.fsckObjects", Value: "false", + }), + git.WithDisabledHooks(), + git.WithStderr(&stderr), + ) if err != nil { return fmt.Errorf("spawning fetch: %w", err) } if err := cmd.Wait(); err != nil { - return fmt.Errorf("fetching source repo: %w", err) + return fmt.Errorf("fetching source repo: %w, stderr: %q", err, stderr.String()) } if err := s.removeOriginInRepo(ctx, repo); err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork_test.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork_test.go index 22aa1c0dab..a9f6d99cb5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_fork_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_fork_test.go @@ -1,50 +1,34 @@ +//go:build !gitaly_test_sha256 + package repository import ( + "bytes" "crypto/tls" "crypto/x509" + "fmt" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - gserver "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - gitalyx509 "gitlab.com/gitlab-org/gitaly/v14/internal/x509" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + gitalyx509 "gitlab.com/gitlab-org/gitaly/v15/internal/x509" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) func TestCreateFork_successful(t *testing.T) { - t.Parallel() - // We need to inject this once across all tests given that crypto/x509 only initializes // certificates once. Changing injected certs during our tests is thus not going to fly well // and would cause failure. We should eventually address this and provide better testing @@ -70,20 +54,25 @@ func TestCreateFork_successful(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - var ( - client gitalypb.RepositoryServiceClient - conn *grpc.ClientConn - ) - createRepoConfig := gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, } + getReplicaPathConfig := gittest.GetReplicaPathConfig{} + + var client gitalypb.RepositoryServiceClient if tt.secure { cfg.TLS = tlsConfig - cfg.TLSListenAddr = runSecureServer(t, cfg, nil) + cfg.TLSListenAddr = "localhost:0" + + _, addr := runRepositoryService(t, cfg, nil) + cfg.TLSListenAddr = addr + + var conn *grpc.ClientConn client, conn = newSecureRepoClient(t, cfg.TLSListenAddr, cfg.Auth.Token, certPool) t.Cleanup(func() { conn.Close() }) + createRepoConfig.ClientConn = conn + getReplicaPathConfig.ClientConn = conn } else { client, cfg.SocketPath = runRepositoryService(t, cfg, nil) } @@ -103,13 +92,7 @@ func TestCreateFork_successful(t *testing.T) { }) require.NoError(t, err) - replicaPath := forkedRepo.GetRelativePath() - if !tt.secure { - // Only the insecure test cases run through Praefect, so we only rewrite the path - // in that case. - replicaPath = gittest.GetReplicaPath(ctx, t, cfg, forkedRepo) - } - + replicaPath := gittest.GetReplicaPath(ctx, t, cfg, forkedRepo, getReplicaPathConfig) forkedRepoPath := filepath.Join(cfg.Storages[0].Path, replicaPath) gittest.Exec(t, cfg, "-C", forkedRepoPath, "fsck") @@ -136,7 +119,7 @@ func TestCreateFork_refs(t *testing.T) { // Prepare the source repository with a bunch of refs and a non-default HEAD ref so we can // assert that the target repo gets created with the correct set of refs. - commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, sourceRepoPath) for _, ref := range []string{ "refs/environments/something", "refs/heads/something", @@ -179,6 +162,62 @@ func TestCreateFork_refs(t *testing.T) { ) } +func TestCreateFork_fsck(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + + testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(t, cfg) + + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath + + ctx := testhelper.Context(t) + ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + // Write a tree into the repository that's known-broken. + treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Content: "content", Path: "dup", Mode: "100644"}, + {Content: "content", Path: "dup", Mode: "100644"}, + }) + + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(), + gittest.WithBranch("main"), + gittest.WithTree(treeID), + ) + + forkedRepo := &gitalypb.Repository{ + RelativePath: gittest.NewRepositoryName(t, true), + StorageName: repo.GetStorageName(), + } + + // Create a fork from the repository with the broken tree. This should work alright: repos + // with preexisting broken objects that we already have on our disk anyway should not be + // subject to additional consistency checks. Otherwise we might end up in a situation where + // we retroactively tighten consistency checks for repositories such that preexisting repos + // wouldn't be forkable anymore. + _, err := client.CreateFork(ctx, &gitalypb.CreateForkRequest{ + Repository: forkedRepo, + SourceRepository: repo, + }) + require.NoError(t, err) + + forkedRepoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(ctx, t, cfg, forkedRepo)) + + // Verify that the broken tree is indeed in the fork and that it is reported as broken by + // git-fsck(1). + var stderr bytes.Buffer + fsckCmd := gittest.NewCommand(t, cfg, "-C", forkedRepoPath, "fsck") + fsckCmd.Stderr = &stderr + + require.EqualError(t, fsckCmd.Run(), "exit status 4") + require.Equal(t, fmt.Sprintf("error in tree %s: duplicateEntries: contains duplicate file entries\n", treeID), stderr.String()) +} + func TestCreateFork_targetExists(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -243,8 +282,7 @@ func TestCreateFork_targetExists(t *testing.T) { func injectCustomCATestCerts(t *testing.T) (*x509.CertPool, config.TLS) { certFile, keyFile := testhelper.GenerateCerts(t) - - testhelper.ModifyEnvironment(t, gitalyx509.SSLCertFile, certFile) + t.Setenv(gitalyx509.SSLCertFile, certFile) caPEMBytes := testhelper.MustReadFile(t, certFile) pool := x509.NewCertPool() @@ -253,93 +291,8 @@ func injectCustomCATestCerts(t *testing.T) (*x509.CertPool, config.TLS) { return pool, config.TLS{CertPath: certFile, KeyPath: keyFile} } -func runSecureServer(t *testing.T, cfg config.Cfg, rubySrv *rubyserver.Server) string { - t.Helper() - - registry := backchannel.NewRegistry() - locator := config.NewLocator(cfg) - cache := cache.New(cfg, locator) - limitHandler := limithandler.New(cfg, limithandler.LimitConcurrencyByRepo, limithandler.WithConcurrencyLimiters) - server, err := gserver.New(true, cfg, testhelper.NewDiscardingLogEntry(t), registry, cache, []*limithandler.LimiterMiddleware{limitHandler}) - require.NoError(t, err) - listener, addr := testhelper.GetLocalhostListener(t) - - txManager := transaction.NewManager(cfg, registry) - gitCmdFactory := gittest.NewCommandFactory(t, cfg) - hookManager := hook.NewManager(cfg, locator, gittest.NewCommandFactory(t, cfg), txManager, gitlab.NewMockClient( - t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, - )) - catfileCache := catfile.NewCache(cfg) - t.Cleanup(catfileCache.Stop) - - housekeepingManager := housekeeping.NewManager(cfg.Prometheus, txManager) - - connsPool := client.NewPool() - t.Cleanup(func() { testhelper.MustClose(t, connsPool) }) - - git2goExecutor := git2go.NewExecutor(cfg, gitCmdFactory, locator) - - gitalypb.RegisterRepositoryServiceServer(server, NewServer( - cfg, - rubySrv, - locator, - txManager, - gitCmdFactory, - catfileCache, - connsPool, - git2goExecutor, - housekeepingManager, - )) - gitalypb.RegisterHookServiceServer(server, hookservice.NewServer( - hookManager, - gitCmdFactory, - nil, - )) - gitalypb.RegisterRemoteServiceServer(server, remote.NewServer( - locator, - gitCmdFactory, - catfileCache, - txManager, - connsPool, - )) - gitalypb.RegisterSSHServiceServer(server, ssh.NewServer( - locator, - gitCmdFactory, - txManager, - )) - gitalypb.RegisterRefServiceServer(server, ref.NewServer( - locator, - gitCmdFactory, - txManager, - catfileCache, - )) - gitalypb.RegisterCommitServiceServer(server, commit.NewServer( - locator, - gitCmdFactory, - nil, - catfileCache, - )) - errQ := make(chan error, 1) - - // This creates a secondary GRPC server which isn't "secure". Reusing - // the one created above won't work as its internal socket would be - // protected by the same TLS certificate. - - cfg.TLS.KeyPath = "" - testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - }) - - t.Cleanup(func() { require.NoError(t, <-errQ) }) - - t.Cleanup(server.Stop) - go func() { errQ <- server.Serve(listener) }() - - return "tls://" + addr -} - -func newSecureRepoClient(t testing.TB, addr, token string, pool *x509.CertPool) (gitalypb.RepositoryServiceClient, *grpc.ClientConn) { - t.Helper() +func newSecureRepoClient(tb testing.TB, addr, token string, pool *x509.CertPool) (gitalypb.RepositoryServiceClient, *grpc.ClientConn) { + tb.Helper() connOpts := []grpc.DialOption{ grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ @@ -350,7 +303,7 @@ func newSecureRepoClient(t testing.TB, addr, token string, pool *x509.CertPool) } conn, err := client.Dial(addr, connOpts) - require.NoError(t, err) + require.NoError(tb, err) return gitalypb.NewRepositoryServiceClient(conn), conn } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository.go index 6b9dc23e18..41d207c8ee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository.go @@ -3,8 +3,8 @@ package repository import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) CreateRepository(ctx context.Context, req *gitalypb.CreateRepositoryRequest) (*gitalypb.CreateRepositoryResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle.go index 14ece1c430..f7da9c43d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle.go @@ -8,11 +8,11 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle_test.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle_test.go index f0bfba7e32..015b0d9e63 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_bundle_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_bundle_test.go @@ -1,28 +1,33 @@ +//go:build !gitaly_test_sha256 + package repository import ( "bytes" + "fmt" "io" "os" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -109,6 +114,7 @@ func TestCreateRepositoryFromBundle_transactional(t *testing.T) { txManager.Reset() masterOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/master")) + featureOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/feature")) // keep-around refs are not cloned in the initial step, but are added via the second call to // git-fetch(1). We thus create some of them to exercise their behaviour with regards to @@ -124,11 +130,13 @@ func TestCreateRepositoryFromBundle_transactional(t *testing.T) { stream, err := client.CreateRepositoryFromBundle(ctx) require.NoError(t, err) + createdRepo := &gitalypb.Repository{ + StorageName: repoProto.GetStorageName(), + RelativePath: gittest.NewRepositoryName(t, true), + } + require.NoError(t, stream.Send(&gitalypb.CreateRepositoryFromBundleRequest{ - Repository: &gitalypb.Repository{ - StorageName: repoProto.GetStorageName(), - RelativePath: "create.git", - }, + Repository: createdRepo, })) bundle := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", "-", @@ -152,15 +160,47 @@ func TestCreateRepositoryFromBundle_transactional(t *testing.T) { return transaction.PhasedVote{Vote: vote, Phase: phase} } - // While the following votes are opaque to us, this doesn't really matter. All we do - // care about is that they're stable. + createdRepoPath, err := config.NewLocator(cfg).GetRepoPath(gittest.RewrittenRepository(ctx, t, cfg, createdRepo)) + require.NoError(t, err) + + refsVote := voting.VoteFromData([]byte(strings.Join([]string{ + fmt.Sprintf("%s %s refs/keep-around/2", git.ObjectHashSHA1.ZeroOID, masterOID), + fmt.Sprintf("%s %s refs/keep-around/1", git.ObjectHashSHA1.ZeroOID, masterOID), + fmt.Sprintf("%s %s refs/heads/feature", git.ObjectHashSHA1.ZeroOID, featureOID), + fmt.Sprintf("%s %s refs/heads/master", git.ObjectHashSHA1.ZeroOID, masterOID), + }, "\n") + "\n")) + + // Compute the second vote hash to assert that we really hash exactly the files that we + // expect to hash. Furthermore, this is required for cross-platform compatibility given that + // the configuration may be different depending on the platform. + hash := voting.NewVoteHash() + for _, filePath := range []string{ + "HEAD", + "config", + "refs/heads/feature", + "refs/heads/master", + "refs/keep-around/1", + "refs/keep-around/2", + } { + file, err := os.Open(filepath.Join(createdRepoPath, filePath)) + require.NoError(t, err) + + _, err = io.Copy(hash, file) + require.NoError(t, err) + + testhelper.MustClose(t, file) + } + + filesVote, err := hash.Vote() + require.NoError(t, err) + require.Equal(t, []transaction.PhasedVote{ // These are the votes created by git-fetch(1). - createVote("47553c06f575f757ad56ef3216c59804b72aa4a6", voting.Prepared), - createVote("47553c06f575f757ad56ef3216c59804b72aa4a6", voting.Committed), + createVote(refsVote.String(), voting.Prepared), + createVote(refsVote.String(), voting.Committed), // And this is the manual votes we compute by walking the repository. - createVote("5947862798db146701879742c0d8fd988ca37797", voting.Prepared), - createVote("5947862798db146701879742c0d8fd988ca37797", voting.Committed), + createVote(filesVote.String(), voting.Prepared), + createVote(filesVote.String(), voting.Committed), }, txManager.Votes()) } @@ -225,8 +265,9 @@ func TestCreateRepositoryFromBundle_existingRepository(t *testing.T) { // The above test creates the second repository on the server. As this test can run with Praefect in front of it, // we'll use the next replica path Praefect will assign in order to ensure this repository creation conflicts even // with Praefect in front of it. - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ RelativePath: praefectutil.DeriveReplicaPath(1), + Seed: gittest.SeedGitLabTest, }) stream, err := client.CreateRepositoryFromBundle(ctx) @@ -237,7 +278,11 @@ func TestCreateRepositoryFromBundle_existingRepository(t *testing.T) { })) _, err = stream.CloseAndRecv() - testhelper.RequireGrpcError(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + if testhelper.IsPraefectEnabled() { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "route repository creation: reserve repository id: repository already exists"), err) + } else { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + } } func TestSanitizedError(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot.go index 79c5322f78..4965fd3bbe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot.go @@ -4,12 +4,11 @@ import ( "context" "net" "net/http" - "os/exec" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" "google.golang.org/grpc/codes" @@ -67,7 +66,7 @@ func untar(ctx context.Context, path string, in *gitalypb.CreateRepositoryFromSn return status.Errorf(codes.Internal, "HTTP server: %v", rsp.Status) } - cmd, err := command.New(ctx, exec.Command("tar", "-C", path, "-xvf", "-"), rsp.Body, nil, nil) + cmd, err := command.New(ctx, []string{"tar", "-C", path, "-xvf", "-"}, command.WithStdin(rsp.Body)) if err != nil { return err } @@ -88,7 +87,7 @@ func (s *server) CreateRepositoryFromSnapshot(ctx context.Context, in *gitalypb. // it needs (especially, the config file and hooks directory). // // NOTE: The received archive is trusted *a lot*. Before pointing this RPC - // at endpoints not under our control, it should undergo a lot of hardning. + // at endpoints not under our control, it should undergo a lot of hardening. if err := untar(ctx, path, in); err != nil { return helper.ErrInternalf("extracting snapshot: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot_test.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot_test.go index bda1cf756c..a5983eb689 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_snapshot_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_snapshot_test.go @@ -1,8 +1,9 @@ +//go:build !gitaly_test_sha256 + package repository import ( "bytes" - "context" "io" "net/http" "net/http/httptest" @@ -12,13 +13,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -67,21 +67,18 @@ func generateTarFile(t *testing.T, path string) ([]byte, []string) { return data, entries } -func createFromSnapshot(t *testing.T, ctx context.Context, req *gitalypb.CreateRepositoryFromSnapshotRequest, cfg config.Cfg) (*gitalypb.CreateRepositoryFromSnapshotResponse, error) { - t.Helper() - - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil) - client := newRepositoryClient(t, cfg, serverSocketPath) - - return client.CreateRepositoryFromSnapshot(ctx, req) -} - func TestCreateRepositoryFromSnapshot_success(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) cfg := testcfg.Build(t) - _, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath + + _, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) // Ensure these won't be in the archive require.NoError(t, os.Remove(filepath.Join(sourceRepoPath, "config"))) @@ -106,9 +103,6 @@ func TestCreateRepositoryFromSnapshot_success(t *testing.T) { HttpHost: host, } - cfg.SocketPath = runRepositoryServerWithConfig(t, cfg, nil) - client := newRepositoryClient(t, cfg, cfg.SocketPath) - rsp, err := client.CreateRepositoryFromSnapshot(ctx, req) require.NoError(t, err) testhelper.ProtoEqual(t, rsp, &gitalypb.CreateRepositoryFromSnapshotResponse{}) @@ -132,35 +126,45 @@ func TestCreateRepositoryFromSnapshot_repositoryExists(t *testing.T) { ctx := testhelper.Context(t) cfg := testcfg.Build(t) + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath // This creates the first repository on the server. As this test can run with Praefect in front of it, // we'll use the next replica path Praefect will assign in order to ensure this repository creation // conflicts even with Praefect in front of it. - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ RelativePath: praefectutil.DeriveReplicaPath(1), + Seed: gittest.SeedGitLabTest, }) req := &gitalypb.CreateRepositoryFromSnapshotRequest{Repository: repo} - rsp, err := createFromSnapshot(t, ctx, req, cfg) + rsp, err := client.CreateRepositoryFromSnapshot(ctx, req) testhelper.RequireGrpcCode(t, err, codes.AlreadyExists) - require.Contains(t, err.Error(), "creating repository: repository exists already") + if testhelper.IsPraefectEnabled() { + require.Contains(t, err.Error(), "route repository creation: reserve repository id: repository already exists") + } else { + require.Contains(t, err.Error(), "creating repository: repository exists already") + } require.Nil(t, rsp) } func TestCreateRepositoryFromSnapshot_badURL(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - require.NoError(t, os.RemoveAll(repoPath)) + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath req := &gitalypb.CreateRepositoryFromSnapshotRequest{ - Repository: repo, - HttpUrl: "invalid!scheme://invalid.invalid", + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: gittest.NewRepositoryName(t, true), + }, + HttpUrl: "invalid!scheme://invalid.invalid", } - rsp, err := createFromSnapshot(t, ctx, req, cfg) + rsp, err := client.CreateRepositoryFromSnapshot(ctx, req) testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) require.Contains(t, err.Error(), "Bad HTTP URL") require.Nil(t, rsp) @@ -206,20 +210,22 @@ func TestCreateRepositoryFromSnapshot_invalidArguments(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { cfg := testcfg.Build(t) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - require.NoError(t, os.RemoveAll(repoPath)) + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath req := &gitalypb.CreateRepositoryFromSnapshotRequest{ - Repository: repo, - HttpUrl: srv.URL + tc.url, - HttpAuth: tc.auth, - HttpHost: host, + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: gittest.NewRepositoryName(t, true), + }, + HttpUrl: srv.URL + tc.url, + HttpAuth: tc.auth, + HttpHost: host, } - rsp, err := createFromSnapshot(t, ctx, req, cfg) + rsp, err := client.CreateRepositoryFromSnapshot(ctx, req) testhelper.RequireGrpcCode(t, err, tc.code) require.Nil(t, rsp) - require.Contains(t, err.Error(), tc.errContains) }) } @@ -230,7 +236,12 @@ func TestCreateRepositoryFromSnapshot_malformedResponse(t *testing.T) { ctx := testhelper.Context(t) cfg := testcfg.Build(t) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + client, socketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = socketPath + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) require.NoError(t, os.Remove(filepath.Join(repoPath, "config"))) require.NoError(t, os.RemoveAll(filepath.Join(repoPath, "hooks"))) @@ -252,8 +263,7 @@ func TestCreateRepositoryFromSnapshot_malformedResponse(t *testing.T) { HttpHost: host, } - rsp, err := createFromSnapshot(t, ctx, req, cfg) - + rsp, err := client.CreateRepositoryFromSnapshot(ctx, req) require.Error(t, err) require.Nil(t, rsp) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url.go index 1079aea853..f7fd9b8539 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url.go @@ -8,10 +8,10 @@ import ( "net/url" "os" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -21,13 +21,6 @@ func (s *server) cloneFromURLCommand( repoURL, repoHost, repositoryFullPath, authorizationToken string, mirror bool, opts ...git.CmdOpt, ) (*command.Command, error) { - u, err := url.Parse(repoURL) - if err != nil { - return nil, helper.ErrInternal(err) - } - - var config []git.ConfigPair - cloneFlags := []git.Option{ git.Flag{Name: "--quiet"}, } @@ -38,12 +31,18 @@ func (s *server) cloneFromURLCommand( cloneFlags = append(cloneFlags, git.Flag{Name: "--bare"}) } + u, err := url.Parse(repoURL) + if err != nil { + return nil, helper.ErrInternal(err) + } + + var config []git.ConfigPair if u.User != nil { - pwd, set := u.User.Password() + password, hasPassword := u.User.Password() var creds string - if set { - creds = u.User.Username() + ":" + pwd + if hasPassword { + creds = u.User.Username() + ":" + password } else { creds = u.User.Username() } @@ -51,11 +50,9 @@ func (s *server) cloneFromURLCommand( u.User = nil authHeader := fmt.Sprintf("Authorization: Basic %s", base64.StdEncoding.EncodeToString([]byte(creds))) config = append(config, git.ConfigPair{Key: "http.extraHeader", Value: authHeader}) - } else { - if len(authorizationToken) > 0 { - authHeader := fmt.Sprintf("Authorization: %s", authorizationToken) - config = append(config, git.ConfigPair{Key: "http.extraHeader", Value: authHeader}) - } + } else if len(authorizationToken) > 0 { + authHeader := fmt.Sprintf("Authorization: %s", authorizationToken) + config = append(config, git.ConfigPair{Key: "http.extraHeader", Value: authHeader}) } if repoHost != "" { @@ -71,7 +68,7 @@ func (s *server) cloneFromURLCommand( Flags: cloneFlags, Args: []string{u.String(), repositoryFullPath}, }, - append(opts, git.WithConfig(config...))..., + append(opts, git.WithConfigEnv(config...))..., ) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url_test.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url_test.go index 19472412f0..b2274bd273 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_from_url_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_from_url_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,12 +12,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -184,62 +186,117 @@ func TestCreateRepositoryFromURL_redirect(t *testing.T) { require.Contains(t, err.Error(), "The requested URL returned error: 301") } -func TestServer_CloneFromURLCommand(t *testing.T) { +func TestCreateRepositoryFromURL_fsck(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) - var authToken string - userInfo := "user:pass%21%3F%40" - repositoryFullPath := "full/path/to/repository" - url := fmt.Sprintf("https://%s@192.0.2.1/secretrepo.git", userInfo) - host := "www.example.com" + cfg, client := setupRepositoryServiceWithoutRepo(t) - cfg := testcfg.Build(t) - s := server{cfg: cfg, gitCmdFactory: gittest.NewCommandFactory(t, cfg)} - cmd, err := s.cloneFromURLCommand(ctx, url, host, repositoryFullPath, authToken, false, git.WithDisabledHooks()) - require.NoError(t, err) + _, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg) - expectedBareFlag := "--bare" - expectedScrubbedURL := "https://192.0.2.1/secretrepo.git" - expectedBasicAuthHeader := fmt.Sprintf("Authorization: Basic %s", base64.StdEncoding.EncodeToString([]byte("user:pass!?@"))) - expectedAuthHeader := fmt.Sprintf("http.extraHeader=%s", expectedBasicAuthHeader) - expectedHostHeader := "http.extraHeader=Host: www.example.com" + // We're creating a new commit which has a root tree with duplicate entries. git-mktree(1) + // allows us to create these trees just fine, but git-fsck(1) complains. + gittest.WriteCommit(t, cfg, sourceRepoPath, + gittest.WithParents(), + gittest.WithBranch("main"), + gittest.WithTreeEntries( + gittest.TreeEntry{Content: "content", Path: "dup", Mode: "100644"}, + gittest.TreeEntry{Content: "content", Path: "dup", Mode: "100644"}, + ), + ) - args := cmd.Args() - require.Contains(t, args, expectedBareFlag) - require.Contains(t, args, expectedScrubbedURL) - require.Contains(t, args, expectedAuthHeader) - require.Contains(t, args, expectedHostHeader) - require.NotContains(t, args, userInfo) + targetRepoProto := &gitalypb.Repository{ + RelativePath: gittest.NewRepositoryName(t, true), + StorageName: cfg.Storages[0].Name, + } + + _, err := client.CreateRepositoryFromURL(ctx, &gitalypb.CreateRepositoryFromURLRequest{ + Repository: targetRepoProto, + Url: "file://" + sourceRepoPath, + }) + require.Error(t, err) + testhelper.RequireGrpcCode(t, err, codes.Internal) + require.Contains(t, err.Error(), "duplicateEntries: contains duplicate file entries") } -func TestServer_CloneFromURLCommand_withToken(t *testing.T) { +func TestServer_CloneFromURLCommand(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - - repositoryFullPath := "full/path/to/repository" - url := "https://www.example.com/secretrepo.git" - authToken := "GL-Geo EhEhKSUk_385GSLnS7BI:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoie1wic2NvcGVcIjpcInJvb3QvZ2l0bGFiLWNlXCJ9IiwianRpIjoiNmQ4ZDM1NGQtZjUxYS00MDQ5LWExZjctMjUyMjk4YmQwMTI4IiwiaWF0IjoxNjQyMDk1MzY5LCJuYmYiOjE2NDIwOTUzNjQsImV4cCI6MTY0MjA5NTk2OX0.YEpfzg8305dUqkYOiB7_dhbL0FVSaUPgpSpMuKrgNrg" cfg := testcfg.Build(t) s := server{cfg: cfg, gitCmdFactory: gittest.NewCommandFactory(t, cfg)} - cmd, err := s.cloneFromURLCommand(ctx, url, "", repositoryFullPath, authToken, false, git.WithDisabledHooks()) - require.NoError(t, err) - expectedScrubbedURL := "https://www.example.com/secretrepo.git" - expectedBasicAuthHeader := fmt.Sprintf("Authorization: %s", authToken) - expectedHeader := fmt.Sprintf("http.extraHeader=%s", expectedBasicAuthHeader) + user, password := "example_user", "pass%21%3F%40" - args := cmd.Args() - require.Contains(t, args, expectedScrubbedURL) - require.Contains(t, args, expectedHeader) + for _, tc := range []struct { + desc string + url string + token string + expectedAuthHeader string + }{ + { + desc: "user credentials", + url: fmt.Sprintf("https://%s:%s@192.0.2.1/secretrepo.git", user, password), + token: "", + expectedAuthHeader: fmt.Sprintf( + "Authorization: Basic %s", + base64.StdEncoding.EncodeToString([]byte("example_user:pass!?@")), + ), + }, + { + desc: "token", + url: "https://192.0.2.1/secretrepo.git", + token: "some-token", + expectedAuthHeader: fmt.Sprintf( + "Authorization: %s", "some-token", + ), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + cmd, err := s.cloneFromURLCommand( + ctx, + tc.url, + "www.example.com", + "full/path/to/repository", + tc.token, + false, + git.WithDisabledHooks(), + ) + require.NoError(t, err) + + // Kill the command so that it won't leak outside of the current test + // context. We know that it will return an error, but we cannot quite tell + // what kind of error it will be because it might fail either be to the kill + // signal or because it failed to clone the repository. + cancel() + require.Error(t, cmd.Wait()) + + args := cmd.Args() + require.Contains(t, args, "--bare") + require.Contains(t, args, "https://192.0.2.1/secretrepo.git") + for _, arg := range args { + require.NotContains(t, arg, user) + require.NotContains(t, arg, password) + require.NotContains(t, arg, tc.expectedAuthHeader) + } + + require.Subset(t, cmd.Env(), []string{ + "GIT_CONFIG_KEY_0=http.extraHeader", + "GIT_CONFIG_VALUE_0=" + tc.expectedAuthHeader, + "GIT_CONFIG_KEY_1=http.extraHeader", + "GIT_CONFIG_VALUE_1=Host: www.example.com", + }) + }) + } } func TestServer_CloneFromURLCommand_withMirror(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - repositoryFullPath := "full/path/to/repository" + repositoryFullPath := filepath.Join(testhelper.TempDir(t), "full/path/to/repository") url := "https://www.example.com/secretrepo.git" cfg := testcfg.Build(t) @@ -250,18 +307,19 @@ func TestServer_CloneFromURLCommand_withMirror(t *testing.T) { args := cmd.Args() require.Contains(t, args, "--mirror") require.NotContains(t, args, "--bare") + require.Error(t, cmd.Wait()) } -func gitServerWithBasicAuth(ctx context.Context, t testing.TB, gitCmdFactory git.CommandFactory, user, pass, repoPath string) (int, func() error) { - return gittest.HTTPServer(ctx, t, gitCmdFactory, repoPath, basicAuthMiddleware(t, user, pass)) +func gitServerWithBasicAuth(ctx context.Context, tb testing.TB, gitCmdFactory git.CommandFactory, user, pass, repoPath string) (int, func() error) { + return gittest.HTTPServer(ctx, tb, gitCmdFactory, repoPath, basicAuthMiddleware(tb, user, pass)) } -func basicAuthMiddleware(t testing.TB, user, pass string) func(http.ResponseWriter, *http.Request, http.Handler) { +func basicAuthMiddleware(tb testing.TB, user, pass string) func(http.ResponseWriter, *http.Request, http.Handler) { return func(w http.ResponseWriter, r *http.Request, next http.Handler) { authUser, authPass, ok := r.BasicAuth() - require.True(t, ok, "should contain basic auth") - require.Equal(t, user, authUser, "username should match") - require.Equal(t, pass, authPass, "password should match") + require.True(tb, ok, "should contain basic auth") + require.Equal(tb, user, authUser, "username should match") + require.Equal(tb, pass, authPass, "password should match") next.ServeHTTP(w, r) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_test.go index 9aafec9ee4..d1976715e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/create_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/create_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,19 +10,19 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sys/unix" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -32,7 +34,7 @@ func TestCreateRepository_missingAuth(t *testing.T) { cfg, repo, _ := testcfg.BuildWithRepo(t, testcfg.WithBase(config.Cfg{Auth: auth.Config{Token: "some"}})) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil) + _, serverSocketPath := runRepositoryService(t, cfg, nil) client := newRepositoryClient(t, config.Cfg{Auth: auth.Config{Token: ""}}, serverSocketPath) _, err := client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{Repository: repo}) @@ -205,14 +207,18 @@ func TestCreateRepository_transactional(t *testing.T) { // The above test creates the second repository on the server. As this test can run with Praefect in front of it, // we'll use the next replica path Praefect will assign in order to ensure this repository creation conflicts even // with Praefect in front of it. - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ RelativePath: praefectutil.DeriveReplicaPath(2), }) _, err = client.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{ Repository: repo, }) - testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + if testhelper.IsPraefectEnabled() { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "route repository creation: reserve repository id: repository already exists"), err) + } else { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + } }) } @@ -229,11 +235,15 @@ func TestCreateRepository_idempotent(t *testing.T) { // conflicts even with Praefect in front of it. RelativePath: praefectutil.DeriveReplicaPath(1), } - gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ + gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ RelativePath: repo.RelativePath, }) req := &gitalypb.CreateRepositoryRequest{Repository: repo} _, err := client.CreateRepository(ctx, req) - testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + if testhelper.IsPraefectEnabled() { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "route repository creation: reserve repository id: repository already exists"), err) + } else { + testhelper.ProtoEqual(t, status.Error(codes.AlreadyExists, "creating repository: repository exists already"), err) + } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch.go index 6cb933fd0c..ef10fee9b0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch.go @@ -5,11 +5,11 @@ import ( "errors" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) FetchSourceBranch(ctx context.Context, req *gitalypb.FetchSourceBranchRequest) (*gitalypb.FetchSourceBranchResponse, error) { @@ -76,7 +76,7 @@ func (s *server) FetchSourceBranch(ctx context.Context, req *gitalypb.FetchSourc []string{sourceOid.String()}, localrepo.FetchOpts{Tags: localrepo.FetchOptsTagsNone}, ); err != nil { - // Design quirk: if the fetch failse, this RPC returns Result: false, but no error. + // Design quirk: if the fetch fails, this RPC returns Result: false, but no error. if errors.As(err, &localrepo.ErrFetchFailed{}) { ctxlogrus.Extract(ctx). WithField("oid", sourceOid.String()). diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle.go index e44f31adb6..2f3fb560e8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle.go @@ -7,13 +7,13 @@ import ( "os" "path/filepath" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle_test.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle_test.go index f11327fcea..993c1aab35 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_bundle_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_bundle_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,19 +10,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) @@ -78,30 +77,11 @@ func TestServer_FetchBundle_transaction(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) hookManager := &mockHookManager{} - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterRepositoryServiceServer(srv, NewServer( - deps.GetCfg(), - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer( - deps.GetHookManager(), - deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - )) - }, testserver.WithHookManager(hookManager), testserver.WithDisablePraefect()) - - client := newRepositoryClient(t, cfg, addr) + client, _ := runRepositoryService(t, cfg, nil, testserver.WithHookManager(hookManager), testserver.WithDisablePraefect()) tmp := testhelper.TempDir(t) bundlePath := filepath.Join(tmp, "test.bundle") - gittest.BundleTestRepo(t, cfg, "gitlab-test.git", bundlePath) + gittest.BundleRepo(t, cfg, repoPath, bundlePath) hookManager.Reset() _, stopGitServer := gittest.HTTPServer(ctx, t, gitCmdFactory, repoPath, nil) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote.go index 285107ed30..5f7ceda05a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote.go @@ -7,14 +7,14 @@ import ( "io" "time" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote_test.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote_test.go index 998ba2be64..939767ed03 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_remote_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_remote_test.go @@ -1,8 +1,12 @@ +//go:build !gitaly_test_sha256 + package repository import ( + "bytes" "context" "fmt" + "io" "net/http" "net/http/httptest" "os" @@ -12,51 +16,96 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -func TestFetchRemoteSuccess(t *testing.T) { +func TestFetchRemote_checkTagsChanged(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, _, repoPath, client := setupRepositoryService(ctx, t) + cfg, client := setupRepositoryServiceWithoutRepo(t) - cloneRepo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, + _, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg) + + gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("main")) + + t.Run("check tags without tags", func(t *testing.T) { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) + + response, err := client.FetchRemote(ctx, &gitalypb.FetchRemoteRequest{ + Repository: repoProto, + RemoteParams: &gitalypb.Remote{ + Url: remoteRepoPath, + }, + CheckTagsChanged: true, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.FetchRemoteResponse{}, response) }) - // Ensure there's a new tag to fetch - gittest.WriteTag(t, cfg, repoPath, "testtag", "master") + gittest.WriteTag(t, cfg, remoteRepoPath, "testtag", "main") - req := &gitalypb.FetchRemoteRequest{Repository: cloneRepo, RemoteParams: &gitalypb.Remote{ - Url: repoPath, - }, Timeout: 120, CheckTagsChanged: true} - resp, err := client.FetchRemote(ctx, req) - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, resp.TagsChanged, true) + t.Run("check tags with tags", func(t *testing.T) { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) - // Ensure that it returns true if we're asked not to check - req.CheckTagsChanged = false - resp, err = client.FetchRemote(ctx, req) - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, resp.TagsChanged, true) + // The first fetch should report that the tags have changed, ... + response, err := client.FetchRemote(ctx, &gitalypb.FetchRemoteRequest{ + Repository: repoProto, + RemoteParams: &gitalypb.Remote{ + Url: remoteRepoPath, + }, + CheckTagsChanged: true, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.FetchRemoteResponse{ + TagsChanged: true, + }, response) + + // ... while the second fetch shouldn't fetch it anew, and thus the tag should not + // have changed. + response, err = client.FetchRemote(ctx, &gitalypb.FetchRemoteRequest{ + Repository: repoProto, + RemoteParams: &gitalypb.Remote{ + Url: remoteRepoPath, + }, + CheckTagsChanged: true, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.FetchRemoteResponse{}, response) + }) + + t.Run("without checking for changed tags", func(t *testing.T) { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) + + // We fetch into the same repository multiple times to assert that `TagsChanged` is + // `true` regardless of whether we have the tag locally already or not. + for i := 0; i < 2; i++ { + response, err := client.FetchRemote(ctx, &gitalypb.FetchRemoteRequest{ + Repository: repoProto, + RemoteParams: &gitalypb.Remote{ + Url: remoteRepoPath, + }, + CheckTagsChanged: false, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.FetchRemoteResponse{ + TagsChanged: true, + }, response) + } + }) } func TestFetchRemote_sshCommand(t *testing.T) { @@ -173,23 +222,9 @@ func TestFetchRemote_transaction(t *testing.T) { sourceCfg := testcfg.Build(t) txManager := transaction.NewTrackingManager() - addr := testserver.RunGitalyServer(t, sourceCfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterRepositoryServiceServer(srv, NewServer( - deps.GetCfg(), - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }, testserver.WithTransactionManager(txManager)) + client, addr := runRepositoryService(t, sourceCfg, nil, testserver.WithTransactionManager(txManager)) sourceCfg.SocketPath = addr - client := newRepositoryClient(t, sourceCfg, addr) - ctx := testhelper.Context(t) repo, _ := gittest.CreateRepository(ctx, t, sourceCfg, gittest.CreateRepositoryConfig{ RelativePath: t.Name(), @@ -441,7 +476,7 @@ func TestFetchRemote_force(t *testing.T) { } } -func TestFetchRemoteFailure(t *testing.T) { +func TestFetchRemote_inputValidation(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -586,11 +621,11 @@ func getRefnames(t *testing.T, cfg config.Cfg, repoPath string) []string { return strings.Split(text.ChompBytes(result), "\n") } -func TestFetchRemoteOverHTTP(t *testing.T) { +func TestFetchRemote_http(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, _, _, client := setupRepositoryService(ctx, t) + cfg, client := setupRepositoryServiceWithoutRepo(t) testCases := []struct { description string @@ -644,7 +679,7 @@ func TestFetchRemoteOverHTTP(t *testing.T) { } } -func TestFetchRemoteWithPath(t *testing.T) { +func TestFetchRemote_localPath(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -665,7 +700,7 @@ func TestFetchRemoteWithPath(t *testing.T) { require.Equal(t, getRefnames(t, cfg, sourceRepoPath), getRefnames(t, cfg, mirrorRepoPath)) } -func TestFetchRemoteOverHTTPWithRedirect(t *testing.T) { +func TestFetchRemote_httpWithRedirect(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) @@ -690,7 +725,7 @@ func TestFetchRemoteOverHTTPWithRedirect(t *testing.T) { require.Contains(t, err.Error(), "The requested URL returned error: 303") } -func TestFetchRemoteOverHTTPWithTimeout(t *testing.T) { +func TestFetchRemote_httpWithTimeout(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(testhelper.Context(t)) @@ -721,3 +756,121 @@ func TestFetchRemoteOverHTTPWithTimeout(t *testing.T) { require.Contains(t, err.Error(), "fetch remote: signal: terminated") } + +func TestFetchRemote_pooledRepository(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + // By default git-fetch(1) will always run with `core.alternateRefsCommand=exit 0 #`, which + // effectively disables use of alternate refs. We can't just unset this value, so instead we + // just write a script that knows to execute git-for-each-ref(1) as expected by this config + // option. + // + // Note that we're using a separate command factory here just to ease the setup because we + // need to recreate the other command factory with the Git configuration specified by the + // test. + alternateRefsCommandFactory := gittest.NewCommandFactory(t, testcfg.Build(t)) + exec := testhelper.WriteExecutable(t, + filepath.Join(testhelper.TempDir(t), "alternate-refs"), + []byte(fmt.Sprintf(`#!/bin/sh + exec %q -C "$1" for-each-ref --format='%%(objectname)' + `, alternateRefsCommandFactory.GetExecutionEnvironment(ctx).BinaryPath)), + ) + + for _, tc := range []struct { + desc string + cfg config.Cfg + shouldAnnouncePooledRefs bool + }{ + { + desc: "with default configuration", + }, + { + desc: "with alternates", + cfg: config.Cfg{ + Git: config.Git{ + Config: []config.GitConfig{ + { + Key: "core.alternateRefsCommand", + Value: exec, + }, + }, + }, + }, + shouldAnnouncePooledRefs: true, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + cfg := testcfg.Build(t, testcfg.WithBase(tc.cfg)) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) + + client, swocketPath := runRepositoryService(t, cfg, nil, testserver.WithGitCommandFactory(gitCmdFactory)) + cfg.SocketPath = swocketPath + + // Create a repository that emulates an object pool. This object contains a + // single reference with an object that is neither in the pool member nor in + // the remote. If alternate refs are used, then Git will announce it to the + // remote as "have". + _, poolRepoPath := gittest.CreateRepository(ctx, t, cfg) + poolCommitID := gittest.WriteCommit(t, cfg, poolRepoPath, + gittest.WithBranch("pooled"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "pool", Mode: "100644", Content: "pool contents"}), + ) + + // Create the pooled repository and link it to its pool. This is the + // repository we're fetching into. + pooledRepoProto, pooledRepoPath := gittest.CreateRepository(ctx, t, cfg) + require.NoError(t, os.WriteFile(filepath.Join(pooledRepoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolRepoPath, "objects")), 0o644)) + + // And then finally create a third repository that emulates the remote side + // we're fetching from. We need to create at least one reference so that Git + // would actually try to fetch objects. + _, remoteRepoPath := gittest.CreateRepository(ctx, t, cfg) + gittest.WriteCommit(t, cfg, remoteRepoPath, + gittest.WithBranch("remote"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "remote", Mode: "100644", Content: "remote contents"}), + ) + + // Set up an HTTP server and intercept the request. This is done so that we + // can observe the reference negotiation and check whether alternate refs + // are announced or not. + var requestBuffer bytes.Buffer + port, stop := gittest.HTTPServer(ctx, t, gitCmdFactory, remoteRepoPath, func(responseWriter http.ResponseWriter, request *http.Request, handler http.Handler) { + closer := request.Body + defer testhelper.MustClose(t, closer) + + request.Body = io.NopCloser(io.TeeReader(request.Body, &requestBuffer)) + + handler.ServeHTTP(responseWriter, request) + }) + defer func() { + require.NoError(t, stop()) + }() + + // Perform the fetch. + _, err := client.FetchRemote(ctx, &gitalypb.FetchRemoteRequest{ + Repository: pooledRepoProto, + RemoteParams: &gitalypb.Remote{ + Url: fmt.Sprintf("http://127.0.0.1:%d/%s", port, filepath.Base(remoteRepoPath)), + }, + }) + require.NoError(t, err) + + // This should result in the "remote" branch having been fetched into the + // pooled repository. + require.Equal(t, + gittest.ResolveRevision(t, cfg, pooledRepoPath, "refs/heads/remote"), + gittest.ResolveRevision(t, cfg, remoteRepoPath, "refs/heads/remote"), + ) + + // Verify whether alternate refs have been announced as part of the + // reference negotiation phase. + if tc.shouldAnnouncePooledRefs { + require.Contains(t, requestBuffer.String(), fmt.Sprintf("have %s", poolCommitID)) + } else { + require.NotContains(t, requestBuffer.String(), fmt.Sprintf("have %s", poolCommitID)) + } + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_test.go index 360ced75dd..7a3a281fdb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fetch_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fetch_test.go @@ -1,15 +1,17 @@ +//go:build !gitaly_test_sha256 + package repository import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -136,7 +138,9 @@ func TestFetchSourceBranchWrongRef(t *testing.T) { md := testcfg.GitalyServersMetadataFromCfg(t, cfg) ctx = testhelper.MergeOutgoingMetadata(ctx, md) - sourceRepo, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + sourceRepo, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) sourceBranch := "fetch-source-branch-testmas-branch" gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithBranch(sourceBranch)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck.go index d7435586cb..db6f8eee64 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck.go @@ -4,8 +4,8 @@ import ( "bytes" "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) Fsck(ctx context.Context, req *gitalypb.FsckRequest) (*gitalypb.FsckResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck_test.go index 307578306f..b6b27a8c72 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fsck_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fsck_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestFsckSuccess(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath.go new file mode 100644 index 0000000000..2f51949063 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath.go @@ -0,0 +1,58 @@ +package repository + +import ( + "context" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +const fullPathKey = "gitlab.fullpath" + +// SetFullPath writes the provided path value into the repository's gitconfig under the +// "gitlab.fullpath" key. +func (s *server) SetFullPath( + ctx context.Context, + request *gitalypb.SetFullPathRequest, +) (*gitalypb.SetFullPathResponse, error) { + if request.GetRepository() == nil { + return nil, helper.ErrInvalidArgumentf("empty Repository") + } + + if len(request.GetPath()) == 0 { + return nil, helper.ErrInvalidArgumentf("no path provided") + } + + repo := s.localrepo(request.GetRepository()) + + if err := repo.SetConfig(ctx, fullPathKey, request.GetPath(), s.txManager); err != nil { + return nil, helper.ErrInternalf("setting config: %w", err) + } + + return &gitalypb.SetFullPathResponse{}, nil +} + +// FullPath reads the path from the repository's gitconfig under the +// "gitlab.fullpath" key. +func (s *server) FullPath(ctx context.Context, request *gitalypb.FullPathRequest) (*gitalypb.FullPathResponse, error) { + if request.GetRepository() == nil { + return nil, helper.ErrInvalidArgument(errors.ErrEmptyRepository) + } + + repo := s.localrepo(request.GetRepository()) + var stdout strings.Builder + err := repo.ExecAndWait(ctx, git.SubCmd{ + Name: "config", + Args: []string{fullPathKey}, + }, git.WithStdout(&stdout)) + if err != nil { + return nil, helper.ErrInternalf("fetch config: %w", err) + } + + return &gitalypb.FullPathResponse{ + Path: strings.TrimSuffix(stdout.String(), "\n"), + }, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath_test.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath_test.go index c8ea732f4e..ad7be92dcd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/fullpath_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/fullpath_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -7,12 +9,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/codes" ) func TestSetFullPath(t *testing.T) { @@ -71,8 +74,7 @@ func TestSetFullPath(t *testing.T) { require.Nil(t, response) - expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = setting config: rpc "+ - "error: code = NotFound desc = GetRepoPath: not a git repository: %q", repoPath) + expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = setting config: GetRepoPath: not a git repository: %q", repoPath) if testhelper.IsPraefectEnabled() { expectedErr = `rpc error: code = NotFound desc = mutator call: route repository mutator: get repository id: repository "default"/"/path/to/repo.git" not found` } @@ -145,3 +147,68 @@ func TestSetFullPath(t *testing.T) { require.Equal(t, "replace", text.ChompBytes(fullPath)) }) } + +func TestFullPath(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + cfg, client := setupRepositoryServiceWithoutRepo(t) + + t.Run("missing repository", func(t *testing.T) { + response, err := client.FullPath(ctx, &gitalypb.FullPathRequest{ + Repository: nil, + }) + require.Nil(t, response) + require.Error(t, err) + require.Contains(t, err.Error(), "empty Repository") + testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) + }) + + t.Run("nonexistent repository", func(t *testing.T) { + repo := &gitalypb.Repository{ + RelativePath: "/path/to/repo.git", + StorageName: cfg.Storages[0].Name, + } + repoPath, err := config.NewLocator(cfg).GetPath(repo) + require.NoError(t, err) + + response, err := client.FullPath(ctx, &gitalypb.FullPathRequest{ + Repository: repo, + }) + require.Nil(t, response) + + expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = fetch config: GetRepoPath: not a git repository: %q", repoPath) + if testhelper.IsPraefectEnabled() { + expectedErr = `rpc error: code = NotFound desc = accessor call: route repository accessor: consistent storages: repository "default"/"/path/to/repo.git" not found` + } + + require.EqualError(t, err, expectedErr) + testhelper.RequireGrpcCode(t, err, codes.NotFound) + }) + + t.Run("missing config", func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + configPath := filepath.Join(repoPath, "config") + require.NoError(t, os.Remove(configPath)) + + response, err := client.FullPath(ctx, &gitalypb.FullPathRequest{ + Repository: repo, + }) + require.Nil(t, response) + require.EqualError(t, err, "rpc error: code = Internal desc = fetch config: exit status 1") + testhelper.RequireGrpcCode(t, err, codes.Internal) + }) + + t.Run("existing config", func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + gittest.Exec(t, cfg, "-C", repoPath, "config", "--add", fullPathKey, "foo/bar") + + response, err := client.FullPath(ctx, &gitalypb.FullPathRequest{ + Repository: repo, + }) + require.NoError(t, err) + testhelper.ProtoEqual(t, &gitalypb.FullPathResponse{Path: "foo/bar"}, response) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc.go index 6e9d3533fb..3acdaa6a0d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc.go @@ -11,14 +11,14 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/status" ) @@ -51,7 +51,9 @@ func (s *server) GarbageCollect(ctx context.Context, in *gitalypb.GarbageCollect return nil, err } - if err := housekeeping.WriteCommitGraph(ctx, repo); err != nil { + if err := housekeeping.WriteCommitGraph(ctx, repo, housekeeping.WriteCommitGraphConfig{ + ReplaceChain: true, + }); err != nil { return nil, err } @@ -61,7 +63,7 @@ func (s *server) GarbageCollect(ctx context.Context, in *gitalypb.GarbageCollect } func (s *server) gc(ctx context.Context, in *gitalypb.GarbageCollectRequest) error { - config := append(housekeeping.GetRepackGitConfig(ctx, in.CreateBitmap), git.ConfigPair{Key: "gc.writeCommitGraph", Value: "false"}) + config := append(housekeeping.GetRepackGitConfig(ctx, in.GetRepository(), in.CreateBitmap), git.ConfigPair{Key: "gc.writeCommitGraph", Value: "false"}) var flags []git.Option if in.Prune { @@ -96,10 +98,11 @@ func (s *server) cleanupKeepArounds(ctx context.Context, repo *localrepo.Repo) e return nil } - objectInfoReader, err := s.catfileCache.ObjectInfoReader(ctx, repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(ctx, repo) if err != nil { return nil } + defer cancel() keepAroundsPrefix := "refs/keep-around" keepAroundsPath := filepath.Join(repoPath, keepAroundsPrefix) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc_test.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc_test.go index 14abe909d4..b3fd470d52 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/gc_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/gc_test.go @@ -1,6 +1,9 @@ +//go:build !gitaly_test_sha256 + package repository import ( + "bytes" "fmt" "os" "path/filepath" @@ -11,13 +14,13 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -267,36 +270,72 @@ func TestGarbageCollectDeletesFileLocks(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - _, repo, repoPath, client := setupRepositoryService(ctx, t) + cfg, client := setupRepositoryServiceWithoutRepo(t) - req := &gitalypb.GarbageCollectRequest{Repository: repo} - - for _, tc := range []string{ - "config.lock", - "HEAD.lock", - "objects/info/commit-graphs/commit-graph-chain.lock", + for _, tc := range []struct { + desc string + lockfile string + expectedErrContains string + }{ + { + desc: "locked gitconfig", + lockfile: "config.lock", + }, + { + desc: "locked HEAD", + lockfile: "HEAD.lock", + }, + { + desc: "locked commit-graph", + lockfile: "objects/info/commit-graphs/commit-graph-chain.lock", + // Writing commit-graphs fails if there is another, concurrent process that + // has locked the commit-graph chain. + expectedErrContains: "Another git process seems to be running in this repository", + }, } { - lockPath := filepath.Join(repoPath, tc) - // No file on the lock path - //nolint:staticcheck - _, err := client.GarbageCollect(ctx, req) - assert.NoError(t, err) + t.Run(tc.desc, func(t *testing.T) { + // Create a lockfile and run GarbageCollect. Because the lock has been + // freshly created GarbageCollect shouldn't remove the not-yet-stale + // lockfile. + t.Run("with recent lockfile", func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) - // Fresh lock should remain - mustCreateFileWithTimes(t, lockPath, freshTime) - //nolint:staticcheck - _, err = client.GarbageCollect(ctx, req) + lockPath := filepath.Join(repoPath, tc.lockfile) + mustCreateFileWithTimes(t, lockPath, freshTime) - assert.NoError(t, err) + //nolint:staticcheck + _, err := client.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{ + Repository: repo, + }) + if tc.expectedErrContains == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErrContains) + } + require.FileExists(t, lockPath) + }) - assert.FileExists(t, lockPath) + // Redo the same test, but this time we create the lockfile so that it is + // considered stale. GarbageCollect should know to remove it. + t.Run("with stale lockfile", func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) - // Old lock should be removed - mustCreateFileWithTimes(t, lockPath, oldTime) - //nolint:staticcheck - _, err = client.GarbageCollect(ctx, req) - assert.NoError(t, err) - require.NoFileExists(t, lockPath) + lockPath := filepath.Join(repoPath, tc.lockfile) + mustCreateFileWithTimes(t, lockPath, oldTime) + + //nolint:staticcheck + _, err := client.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{ + Repository: repo, + }) + require.NoError(t, err) + require.NoFileExists(t, lockPath) + }) + }) } } @@ -426,7 +465,7 @@ func TestCleanupInvalidKeepAroundRefs(t *testing.T) { { desc: "Filled with the blank ref", refName: "0b4bc9a49b562e85de7cc9e834518ea6828729b9", - refContent: git.ZeroOID.String(), + refContent: git.ObjectHashSHA1.ZeroOID.String(), shouldExist: true, }, { @@ -483,12 +522,12 @@ func TestCleanupInvalidKeepAroundRefs(t *testing.T) { } } -func mustCreateFileWithTimes(t testing.TB, path string, mTime time.Time) { - t.Helper() +func mustCreateFileWithTimes(tb testing.TB, path string, mTime time.Time) { + tb.Helper() - require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755)) - require.NoError(t, os.WriteFile(path, nil, 0o644)) - require.NoError(t, os.Chtimes(path, mTime, mTime)) + require.NoError(tb, os.MkdirAll(filepath.Dir(path), 0o755)) + require.NoError(tb, os.WriteFile(path, nil, 0o644)) + require.NoError(tb, os.Chtimes(path, mTime, mTime)) } func TestGarbageCollectDeltaIslands(t *testing.T) { @@ -497,9 +536,49 @@ func TestGarbageCollectDeltaIslands(t *testing.T) { ctx := testhelper.Context(t) cfg, repo, repoPath, client := setupRepositoryService(ctx, t) - gittest.TestDeltaIslands(t, cfg, repoPath, func() error { + gittest.TestDeltaIslands(t, cfg, repoPath, repoPath, false, func() error { //nolint:staticcheck _, err := client.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{Repository: repo}) return err }) } + +func TestGarbageCollect_commitGraphsWithPrunedObjects(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, client := setupRepositoryServiceWithoutRepo(t) + + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + + // Write a first commit-graph that contains the root commit, only. + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + // Write a second, incremental commit-graph that contains a commit we're about to + // make unreachable and then prune. + unreachableCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(rootCommitID), gittest.WithBranch("main")) + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split=no-merge", "--changed-paths") + + // Reset the "main" branch back to the initial root commit ID and prune the now + // unreachable second commit. + gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/main", rootCommitID.String()) + gittest.Exec(t, cfg, "-C", repoPath, "prune", "--expire", "now") + + // The commit-graph chain now refers to the pruned commit, and git-commit-graph(1) + // should complain about that. + var stderr bytes.Buffer + verifyCmd := gittest.NewCommand(t, cfg, "-C", repoPath, "commit-graph", "verify") + verifyCmd.Stderr = &stderr + require.EqualError(t, verifyCmd.Run(), "exit status 1") + require.Equal(t, stderr.String(), fmt.Sprintf("error: Could not read %[1]s\nfailed to parse commit %[1]s from object database for commit-graph\n", unreachableCommitID)) + + // Given that GarbageCollect is an RPC that prunes objects it should know to fix up commit + // graphs... + //nolint:staticcheck + _, err := client.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{Repository: repoProto}) + require.NoError(t, err) + + // ... and it does. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "verify") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes.go index 98e4c0a6ca..023fc28fd9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes_test.go index 8f81ac0fbc..1083225071 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/info_attributes_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/info_attributes_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -8,9 +10,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func TestGetInfoAttributesExisting(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license.go new file mode 100644 index 0000000000..4d1b8fd43d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license.go @@ -0,0 +1,234 @@ +package repository + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "regexp" + "sort" + "strings" + + "github.com/go-enry/go-license-detector/v4/licensedb" + "github.com/go-enry/go-license-detector/v4/licensedb/api" + "github.com/go-enry/go-license-detector/v4/licensedb/filer" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// The `github.com/go-enry/go-license-detector` package uses https://spdx.org/licenses/ +// as the source of the licenses. That package doesn't provide `nickname` info. +// But because the `nickname` is required by the FindLicense RPC interface, we had to manually +// extract the list of all license-to-nickname pairs from the Licensee license +// database which is https://github.com/github/choosealicense.com/tree/gh-pages/_licenses +// and store them here. +var nicknameByLicenseIdentifier = map[string]string{ + "agpl-3.0": "GNU AGPLv3", + "lgpl-3.0": "GNU LGPLv3", + "bsd-3-clause-clear": "Clear BSD", + "odbl-1.0": "ODbL", + "ncsa": "UIUC/NCSA", + "lgpl-2.1": "GNU LGPLv2.1", + "gpl-3.0": "GNU GPLv3", + "gpl-2.0": "GNU GPLv2", +} + +func (s *server) FindLicense(ctx context.Context, req *gitalypb.FindLicenseRequest) (*gitalypb.FindLicenseResponse, error) { + if featureflag.GoFindLicense.IsEnabled(ctx) { + repo := localrepo.New(s.locator, s.gitCmdFactory, s.catfileCache, req.GetRepository()) + + hasHeadRevision, err := repo.HasRevision(ctx, "HEAD") + if err != nil { + return nil, helper.ErrInternalf("cannot check HEAD revision: %v", err) + } + if !hasHeadRevision { + return &gitalypb.FindLicenseResponse{}, nil + } + + repoFiler := &gitFiler{ctx: ctx, repo: repo} + detectedLicenses, err := licensedb.Detect(repoFiler) + if err != nil { + if errors.Is(err, licensedb.ErrNoLicenseFound) { + if repoFiler.foundLicense { + // In case the license is not identified, but a file containing some + // sort of license is found, we return a predefined response. + return &gitalypb.FindLicenseResponse{ + LicenseName: "Other", + LicenseShortName: "other", + LicenseUrl: "http://choosealicense.com/licenses/other/", + LicensePath: repoFiler.path, + }, nil + } + return &gitalypb.FindLicenseResponse{}, nil + } + return nil, helper.ErrInternal(fmt.Errorf("FindLicense: Err: %w", err)) + } + + // This should not happen as the error must be returned, but let's keep it safe to avoid panics. + if len(detectedLicenses) == 0 { + return &gitalypb.FindLicenseResponse{}, nil + } + + type bestMatch struct { + shortName string + api.Match + } + bestMatches := make([]bestMatch, 0, len(detectedLicenses)) + for candidate, match := range detectedLicenses { + bestMatches = append(bestMatches, bestMatch{Match: match, shortName: candidate}) + } + sort.Slice(bestMatches, func(i, j int) bool { + // Because there could be multiple matches with the same confidence, we need + // to make sure the function is consistent and returns the same license on + // each invocation. That is why we sort by the short name as well. + if bestMatches[i].Confidence == bestMatches[j].Confidence { + return trimDeprecatedPrefix(bestMatches[i].shortName) < trimDeprecatedPrefix(bestMatches[j].shortName) + } + return bestMatches[i].Confidence > bestMatches[j].Confidence + }) + + // We also don't want to return the prefix back to the caller if it exists. + shortName := trimDeprecatedPrefix(bestMatches[0].shortName) + + name, err := licensedb.LicenseName(shortName) + if err != nil { + return nil, helper.ErrInternal(fmt.Errorf("license name by id %q: %w", shortName, err)) + } + + urls, err := licensedb.LicenseURLs(shortName) + if err != nil { + return nil, helper.ErrInternal(fmt.Errorf("license URLs by id %q: %w", shortName, err)) + } + var url string + if len(urls) > 0 { + // The URL list is returned in an ordered slice, so we just pick up the first one from the list. + url = urls[0] + } + + // The license identifier used by `github.com/go-enry/go-license-detector` is + // case-sensitive, but the API requires all license identifiers to be lower-cased. + shortName = strings.ToLower(shortName) + nickname := nicknameByLicenseIdentifier[shortName] + return &gitalypb.FindLicenseResponse{ + LicenseShortName: shortName, + LicensePath: bestMatches[0].File, + LicenseName: name, + LicenseUrl: url, + LicenseNickname: nickname, + }, nil + } + + client, err := s.ruby.RepositoryServiceClient(ctx) + if err != nil { + return nil, err + } + clientCtx, err := rubyserver.SetHeaders(ctx, s.locator, req.GetRepository()) + if err != nil { + return nil, err + } + return client.FindLicense(clientCtx, req) +} + +// For the deprecated licenses, the `github.com/go-enry/go-license-detector` package +// uses the "deprecated_" prefix in the identifier. But the license database stores +// information using the identifier without prefix, so we need to cut off the +// prefix before searching for full license name and license URLs. +func trimDeprecatedPrefix(name string) string { + return strings.TrimPrefix(name, "deprecated_") +} + +var readmeRegexp = regexp.MustCompile(`(readme|guidelines)(\.md|\.rst|\.html|\.txt)?$`) + +type gitFiler struct { + ctx context.Context + repo *localrepo.Repo + foundLicense bool + path string +} + +func (f *gitFiler) ReadFile(path string) ([]byte, error) { + var stdout, stderr bytes.Buffer + if err := f.repo.ExecAndWait(f.ctx, git.SubCmd{ + Name: "cat-file", + Args: []string{"blob", fmt.Sprintf("HEAD:%s", path)}, + }, git.WithStdout(&stdout), git.WithStderr(&stderr)); err != nil { + return nil, fmt.Errorf("cat-file failed: %w, stderr: %q", err, stderr.String()) + } + + // `licensedb.Detect` only opens files that look like licenses. Failing that, it will + // also open readme files to try to identify license files. The RPC handler needs the + // knowledge of whether any license files were encountered, so we filter out the + // readme files as defined in licensedb.Detect: + // https://github.com/go-enry/go-license-detector/blob/4f2ca6af2ab943d9b5fa3a02782eebc06f79a5f4/licensedb/internal/investigation.go#L61 + // + // This doesn't filter out the possible license files identified from the readme files which may in fact not + // be licenses. + if !f.foundLicense { + f.foundLicense = !readmeRegexp.MatchString(strings.ToLower(path)) + if f.foundLicense { + f.path = path + } + } + + return stdout.Bytes(), nil +} + +func (f *gitFiler) ReadDir(string) ([]filer.File, error) { + // We're doing a recursive listing returning all files at once such that we do not have to + // call git-ls-tree(1) multiple times. + var stderr bytes.Buffer + cmd, err := f.repo.Exec(f.ctx, git.SubCmd{ + Name: "ls-tree", + Flags: []git.Option{ + git.Flag{Name: "--full-tree"}, + git.Flag{Name: "-z"}, + }, + Args: []string{"HEAD"}, + }, git.WithStderr(&stderr)) + if err != nil { + return nil, err + } + + tree := lstree.NewParser(cmd, git.ObjectHashSHA1) + + var files []filer.File + for { + entry, err := tree.NextEntry() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + + // Given that we're doing a recursive listing, we skip over all types which aren't + // blobs. + if entry.Type != lstree.Blob { + continue + } + + files = append(files, filer.File{ + Name: entry.Path, + IsDir: false, + }) + } + + if err := cmd.Wait(); err != nil { + return nil, fmt.Errorf("ls-tree failed: %w, stderr: %q", err, stderr.String()) + } + + return files, nil +} + +func (f *gitFiler) Close() {} + +func (f *gitFiler) PathsAreAlwaysSlash() bool { + // git ls-files uses unix slash `/` + return true +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license_test.go new file mode 100644 index 0000000000..23059844a3 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/license_test.go @@ -0,0 +1,184 @@ +//go:build !gitaly_test_sha256 + +package repository + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func testSuccessfulFindLicenseRequest(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { + testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { + deprecatedLicenseData := testhelper.MustReadFile(t, "testdata/gnu_license.deprecated.txt") + licenseText := testhelper.MustReadFile(t, "testdata/gpl-2.0_license.txt") + for _, tc := range []struct { + desc string + nonExistentRepository bool + files map[string]string + // expectedLicenseRuby is used to verify the response received from the Ruby side-car. + // Also is it used if expectedLicenseGo is not set. Because the Licensee gem and + // the github.com/go-enry/go-license-detector go package use different license databases + // and different methods to detect the license, they will not always return the + // same result. So we need to provide different expected results in some cases. + expectedLicenseRuby *gitalypb.FindLicenseResponse + expectedLicenseGo *gitalypb.FindLicenseResponse + errorContains string + }{ + { + desc: "repository does not exist", + nonExistentRepository: true, + errorContains: "GetRepoPath: not a git repository", + }, + { + desc: "empty if no license file in repo", + files: map[string]string{ + "README.md": "readme content", + }, + expectedLicenseRuby: &gitalypb.FindLicenseResponse{}, + }, + { + desc: "high confidence mit result and less confident mit-0 result", + files: map[string]string{ + "LICENSE": `MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.`, + }, + expectedLicenseRuby: &gitalypb.FindLicenseResponse{ + LicenseShortName: "mit", + LicenseUrl: "http://choosealicense.com/licenses/mit/", + LicenseName: "MIT License", + LicensePath: "LICENSE", + }, + expectedLicenseGo: &gitalypb.FindLicenseResponse{ + LicenseShortName: "mit", + LicenseUrl: "https://opensource.org/licenses/MIT", + LicenseName: "MIT License", + LicensePath: "LICENSE", + }, + }, + { + desc: "unknown license", + files: map[string]string{ + "LICENSE.md": "this doesn't match any known license", + }, + expectedLicenseRuby: &gitalypb.FindLicenseResponse{ + LicenseShortName: "other", + LicenseUrl: "http://choosealicense.com/licenses/other/", + LicenseName: "Other", + LicensePath: "LICENSE.md", + }, + }, + { + desc: "deprecated license", + files: map[string]string{ + "LICENSE": string(deprecatedLicenseData), + }, + expectedLicenseRuby: &gitalypb.FindLicenseResponse{ + LicenseShortName: "gpl-3.0", + LicenseUrl: "http://choosealicense.com/licenses/gpl-3.0/", + LicenseName: "GNU General Public License v3.0", + LicensePath: "LICENSE", + LicenseNickname: "GNU GPLv3", + }, + expectedLicenseGo: &gitalypb.FindLicenseResponse{ + LicenseShortName: "gpl-3.0+", + LicenseUrl: "https://www.gnu.org/licenses/gpl-3.0-standalone.html", + LicenseName: "GNU General Public License v3.0 or later", + LicensePath: "LICENSE", + // The nickname is not set because there is no nickname defined for gpl-3.0+ license. + }, + }, + { + desc: "license with nickname", + files: map[string]string{ + "LICENSE": string(licenseText), + }, + expectedLicenseRuby: &gitalypb.FindLicenseResponse{ + LicenseShortName: "gpl-2.0", + LicenseUrl: "http://choosealicense.com/licenses/gpl-2.0/", + LicenseName: "GNU General Public License v2.0", + LicensePath: "LICENSE", + LicenseNickname: "GNU GPLv2", + }, + expectedLicenseGo: &gitalypb.FindLicenseResponse{ + LicenseShortName: "gpl-2.0", + LicenseUrl: "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", + LicenseName: "GNU General Public License v2.0 only", + LicensePath: "LICENSE", + LicenseNickname: "GNU GPLv2", + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + var treeEntries []gittest.TreeEntry + for file, content := range tc.files { + treeEntries = append(treeEntries, gittest.TreeEntry{ + Mode: "100644", + Path: file, + Content: content, + }) + } + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithTreeEntries(treeEntries...)) + + if tc.nonExistentRepository { + require.NoError(t, os.RemoveAll(repoPath)) + } + + resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) + if tc.errorContains != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errorContains) + return + } + + require.NoError(t, err) + if featureflag.GoFindLicense.IsEnabled(ctx) && tc.expectedLicenseGo != nil { + testhelper.ProtoEqual(t, tc.expectedLicenseGo, resp) + } else { + testhelper.ProtoEqual(t, tc.expectedLicenseRuby, resp) + } + }) + } + }) +} + +func testFindLicenseRequestEmptyRepo(t *testing.T, cfg config.Cfg, client gitalypb.RepositoryServiceClient, rubySrv *rubyserver.Server) { + testhelper.NewFeatureSets(featureflag.GoFindLicense).Run(t, func(t *testing.T, ctx context.Context) { + repo, _ := gittest.CreateRepository(ctx, t, cfg) + + resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: repo}) + require.NoError(t, err) + + require.Empty(t, resp.GetLicenseShortName()) + }) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base.go index 52653d1503..0879e72437 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base.go @@ -4,9 +4,9 @@ import ( "context" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base_test.go index a9559aa676..5079cd954f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/merge_base_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/merge_base_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package repository import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx.go index 0540e2ae1e..7691c0680e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx.go @@ -9,18 +9,18 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/status" ) const ( - //nolint: revive // This is unintentionally missing documentation. + // This is unintentionally missing documentation. MidxRelPath = "objects/pack/multi-pack-index" ) @@ -186,7 +186,7 @@ func (s *server) midxRepack(ctx context.Context, repo repository.GitRepo) error git.ValueFlag{Name: "--batch-size", Value: strconv.FormatInt(batchSize, 10)}, }, }, - git.WithConfig(housekeeping.GetRepackGitConfig(ctx, false)...), + git.WithConfig(housekeeping.GetRepackGitConfig(ctx, repo, false)...), ) if err != nil { return err diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx_test.go index 1dec37ebff..ea358bf363 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/midx_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/midx_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,17 +12,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/peer" "google.golang.org/grpc/status" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize.go index 8ea1555abc..f77e4b619d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize.go @@ -3,9 +3,9 @@ package repository import ( "context" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) OptimizeRepository(ctx context.Context, in *gitalypb.OptimizeRepositoryRequest) (*gitalypb.OptimizeRepositoryResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize_test.go index 13f5804daf..61a21499c4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/optimize_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/optimize_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,11 +12,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -104,7 +106,6 @@ func TestOptimizeRepository(t *testing.T) { OID: git.ObjectID(blobID), Mode: "100644", Path: "blob", }), gittest.WithBranch(blobID), - gittest.WithParents(), ) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects.go index 4cacb04d9c..2ba270830c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects.go @@ -3,10 +3,11 @@ package repository import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // PruneUnreachableObjects prunes objects which aren't reachable from any of its references. To @@ -38,6 +39,14 @@ func (s *server) PruneUnreachableObjects( return nil, helper.ErrInternalf("pruning objects: %w", err) } + // Rewrite the commit-graph so that it doesn't contain references to pruned commits + // anymore. + if err := housekeeping.WriteCommitGraph(ctx, repo, housekeeping.WriteCommitGraphConfig{ + ReplaceChain: true, + }); err != nil { + return nil, helper.ErrInternalf("rewriting commit-graph: %w", err) + } + stats.LogObjectsInfo(ctx, repo) return &gitalypb.PruneUnreachableObjectsResponse{}, nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects_test.go index 3c1c1d640d..29bb18eac3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/prune_unreachable_objects_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/prune_unreachable_objects_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -7,11 +9,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestPruneUnreachableObjects(t *testing.T) { @@ -57,7 +59,7 @@ func TestPruneUnreachableObjects(t *testing.T) { repo, repoPath := gittest.CreateRepository(ctx, t, cfg) // Create the commit and a branch pointing to it to make it reachable. - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithBranch("branch")) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("branch")) _, err := client.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ Repository: repo, @@ -72,7 +74,7 @@ func TestPruneUnreachableObjects(t *testing.T) { repo, repoPath := gittest.CreateRepository(ctx, t, cfg) // Create the commit, but don't create a reference pointing to it. - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, repoPath) // Set the object time to something that's close to 30 minutes, but gives us enough // room to not cause flakes. setObjectTime(t, repoPath, commitID, time.Now().Add(-28*time.Minute)) @@ -91,7 +93,7 @@ func TestPruneUnreachableObjects(t *testing.T) { repo, repoPath := gittest.CreateRepository(ctx, t, cfg) // Create the commit, but don't create a reference pointing to it. - commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, repoPath) setObjectTime(t, repoPath, commitID, time.Now().Add(-31*time.Minute)) _, err := client.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ @@ -108,13 +110,13 @@ func TestPruneUnreachableObjects(t *testing.T) { t.Run("repository with mixed objects", func(t *testing.T) { repo, repoPath := gittest.CreateRepository(ctx, t, cfg) - reachableOldCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithMessage("a"), gittest.WithBranch("branch")) + reachableOldCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("a"), gittest.WithBranch("branch")) setObjectTime(t, repoPath, reachableOldCommit, time.Now().Add(-31*time.Minute)) - unreachableRecentCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("b"), gittest.WithParents()) + unreachableRecentCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("b")) setObjectTime(t, repoPath, unreachableRecentCommit, time.Now().Add(-28*time.Minute)) - unreachableOldCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("c"), gittest.WithParents()) + unreachableOldCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("c")) setObjectTime(t, repoPath, unreachableOldCommit, time.Now().Add(-31*time.Minute)) _, err := client.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ @@ -132,4 +134,32 @@ func TestPruneUnreachableObjects(t *testing.T) { require.Error(t, err) require.Equal(t, "fatal: Needed a single revision\n", string(output)) }) + + t.Run("repository with commit-graph", func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + // Write two commits into the repository and create a commit-graph. The second + // commit will become unreachable and will be pruned, but will be contained in the + // commit-graph. + rootCommitID := gittest.WriteCommit(t, cfg, repoPath) + unreachableCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(rootCommitID), gittest.WithBranch("main")) + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "write", "--reachable", "--split", "--changed-paths") + + // Reset the "main" branch back to the initial root commit ID and prune the now + // unreachable second commit. + gittest.Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/main", rootCommitID.String()) + + // Modify the modification time of the unreachable commit ID so that it will be + // pruned. + setObjectTime(t, repoPath, unreachableCommitID, time.Now().Add(-30*time.Minute)) + + _, err := client.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ + Repository: repo, + }) + require.NoError(t, err) + + // The commit-graph chain should have been rewritten by PruneUnreachableObjects so + // that it doesn't refer to the pruned commit anymore. + gittest.Exec(t, cfg, "-C", repoPath, "commit-graph", "verify") + }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes.go index fb1c2c5a11..9a81e16377 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes.go @@ -7,12 +7,12 @@ import ( "regexp" "strconv" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/rawdiff" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/rawdiff" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -20,10 +20,11 @@ func (s *server) GetRawChanges(req *gitalypb.GetRawChangesRequest, stream gitaly ctx := stream.Context() repo := s.localrepo(req.GetRepository()) - objectInfoReader, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) + objectInfoReader, cancel, err := s.catfileCache.ObjectInfoReader(stream.Context(), repo) if err != nil { return helper.ErrInternal(err) } + defer cancel() if err := validateRawChangesRequest(ctx, req, objectInfoReader); err != nil { return helper.ErrInvalidArgument(err) @@ -37,13 +38,13 @@ func (s *server) GetRawChanges(req *gitalypb.GetRawChangesRequest, stream gitaly } func validateRawChangesRequest(ctx context.Context, req *gitalypb.GetRawChangesRequest, objectInfoReader catfile.ObjectInfoReader) error { - if from := req.FromRevision; !git.ObjectID(from).IsZeroOID() { + if from := req.FromRevision; !git.ObjectHashSHA1.IsZeroOID(git.ObjectID(from)) { if _, err := objectInfoReader.Info(ctx, git.Revision(from)); err != nil { return fmt.Errorf("invalid 'from' revision: %q", from) } } - if to := req.ToRevision; !git.ObjectID(to).IsZeroOID() { + if to := req.ToRevision; !git.ObjectHashSHA1.IsZeroOID(git.ObjectID(to)) { if _, err := objectInfoReader.Info(ctx, git.Revision(to)); err != nil { return fmt.Errorf("invalid 'to' revision: %q", to) } @@ -53,12 +54,12 @@ func validateRawChangesRequest(ctx context.Context, req *gitalypb.GetRawChangesR } func (s *server) getRawChanges(stream gitalypb.RepositoryService_GetRawChangesServer, repo git.RepositoryExecutor, objectInfoReader catfile.ObjectInfoReader, from, to string) error { - if git.ObjectID(to).IsZeroOID() { + if git.ObjectHashSHA1.IsZeroOID(git.ObjectID(to)) { return nil } - if git.ObjectID(from).IsZeroOID() { - from = git.EmptyTreeOID.String() + if git.ObjectHashSHA1.IsZeroOID(git.ObjectID(from)) { + from = git.ObjectHashSHA1.EmptyTreeOID.String() } ctx := stream.Context() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes_test.go index d1d7c21ff3..b91d1ecdc4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/raw_changes_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/raw_changes_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -7,11 +9,11 @@ import ( "unicode/utf8" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "google.golang.org/grpc/codes" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestGetRawChanges(t *testing.T) { @@ -48,7 +50,7 @@ func TestGetRawChanges(t *testing.T) { }, }, { - oldRev: git.ZeroOID.String(), + oldRev: git.ObjectHashSHA1.ZeroOID.String(), newRev: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", changes: []*gitalypb.GetRawChangesResponse_RawChange{ { @@ -162,51 +164,50 @@ func TestGetRawChangesFailures(t *testing.T) { ctx := testhelper.Context(t) _, repo, _, client := setupRepositoryService(ctx, t) - testCases := []struct { - oldRev string - newRev string - code codes.Code - omitRepository bool + for _, tc := range []struct { + desc string + request *gitalypb.GetRawChangesRequest + expectedErr error }{ { - oldRev: "", - newRev: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", - code: codes.InvalidArgument, - }, - { - oldRev: "cfe32cf61b73a0d5e9f13e774abde7ff789b1660", - newRev: "913c66a37b4a45b9769037c55c2d238bd0942d2e", - code: codes.InvalidArgument, - omitRepository: true, - }, - { - // A Gitaly commit, unresolvable in gitlab-test - oldRev: "32800ed8206c0087f65e90a1a396b76d3c33f648", - newRev: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", - code: codes.InvalidArgument, - }, - } - - for _, tc := range testCases { - t.Run(fmt.Sprintf("old:%s,new:%s", tc.oldRev, tc.newRev), func(t *testing.T) { - req := &gitalypb.GetRawChangesRequest{ + desc: "missing from-revision", + request: &gitalypb.GetRawChangesRequest{ Repository: repo, - FromRevision: tc.oldRev, - ToRevision: tc.newRev, - } - - if tc.omitRepository { - req.Repository = nil - } - - resp, err := client.GetRawChanges(ctx, req) + FromRevision: "", + ToRevision: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", + }, + expectedErr: helper.ErrInvalidArgumentf("invalid 'from' revision: %q", ""), + }, + { + desc: "missing repository", + request: &gitalypb.GetRawChangesRequest{ + FromRevision: "cfe32cf61b73a0d5e9f13e774abde7ff789b1660", + ToRevision: "913c66a37b4a45b9769037c55c2d238bd0942d2e", + }, + expectedErr: helper.ErrInvalidArgumentf(gitalyOrPraefect( + "GetStorageByName: no such storage: \"\"", + "repo scoped: empty Repository", + )), + }, + { + desc: "missing commit", + request: &gitalypb.GetRawChangesRequest{ + Repository: repo, + // A Gitaly commit, unresolvable in gitlab-test + FromRevision: "32800ed8206c0087f65e90a1a396b76d3c33f648", + ToRevision: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863", + }, + expectedErr: helper.ErrInvalidArgumentf("invalid 'from' revision: %q", "32800ed8206c0087f65e90a1a396b76d3c33f648"), + }, + } { + t.Run(fmt.Sprintf(tc.desc), func(t *testing.T) { + stream, err := client.GetRawChanges(ctx, tc.request) require.NoError(t, err) for err == nil { - _, err = resp.Recv() + _, err = stream.Recv() } - - testhelper.RequireGrpcCode(t, err, tc.code) + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/redirecting_test_server_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/redirecting_test_server_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/redirecting_test_server_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/redirecting_test_server_test.go index c93ea59381..2b3fe9e956 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/redirecting_test_server_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/redirecting_test_server_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -7,10 +9,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) const redirectURL = "/redirect_url" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove.go index 936172a44e..b166df6d4f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove.go @@ -8,12 +8,12 @@ import ( "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) RemoveRepository(ctx context.Context, in *gitalypb.RemoveRepositoryRequest) (*gitalypb.RemoveRepositoryResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove_test.go index b6c922ecbd..5b8ab01b11 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/remove_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/remove_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -6,11 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestRemoveRepository(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename.go index 9f619e4e2f..cb5c5d1726 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename.go @@ -8,10 +8,10 @@ import ( "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) RenameRepository(ctx context.Context, in *gitalypb.RenameRepositoryRequest) (*gitalypb.RenameRepositoryResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename_test.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename_test.go index 9983eb8946..cf72673086 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/rename_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/rename_test.go @@ -1,6 +1,9 @@ +//go:build !gitaly_test_sha256 + package repository import ( + "context" "fmt" "os" "path/filepath" @@ -8,19 +11,23 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestRenameRepository_success(t *testing.T) { + testhelper.NewFeatureSets(featureflag.PraefectGeneratedReplicaPaths).Run(t, testRenameRepositorySuccess) +} + +func testRenameRepositorySuccess(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) // Praefect does not move repositories on the disk so this test case is not run with Praefect. cfg, repo, _, client := setupRepositoryService(ctx, t, testserver.WithDisablePraefect()) @@ -43,8 +50,11 @@ func TestRenameRepository_success(t *testing.T) { } func TestRenameRepository_DestinationExists(t *testing.T) { + testhelper.NewFeatureSets(featureflag.PraefectGeneratedReplicaPaths).Run(t, testRenameRepositoryDestinationExists) +} + +func testRenameRepositoryDestinationExists(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) cfg, client := setupRepositoryServiceWithoutRepo(t) @@ -57,7 +67,7 @@ func TestRenameRepository_DestinationExists(t *testing.T) { require.NoError(t, err) destinationRepoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(ctx, t, cfg, existingDestinationRepo)) - commitID := gittest.WriteCommit(t, cfg, destinationRepoPath, gittest.WithParents()) + commitID := gittest.WriteCommit(t, cfg, destinationRepoPath) _, err = client.RenameRepository(ctx, &gitalypb.RenameRepositoryRequest{ Repository: renamedRepo, @@ -70,11 +80,11 @@ func TestRenameRepository_DestinationExists(t *testing.T) { } func TestRenameRepository_invalidRequest(t *testing.T) { - // Prafect applies renames to metadata even on failed requests, which fails this test. - testhelper.SkipWithPraefect(t, "https://gitlab.com/gitlab-org/gitaly/-/issues/4003") + testhelper.NewFeatureSets(featureflag.PraefectGeneratedReplicaPaths).Run(t, testRenameRepositoryInvalidRequest) +} +func testRenameRepositoryInvalidRequest(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) _, repo, repoPath, client := setupRepositoryService(ctx, t) storagePath := strings.TrimSuffix(repoPath, "/"+repo.RelativePath) @@ -87,7 +97,7 @@ func TestRenameRepository_invalidRequest(t *testing.T) { { desc: "empty repository", req: &gitalypb.RenameRepositoryRequest{Repository: nil, RelativePath: "/tmp/abc"}, - exp: status.Error(codes.InvalidArgument, gitalyOrPraefect("empty Repository", "repo scoped: empty Repository")), + exp: status.Error(codes.InvalidArgument, "empty Repository"), }, { desc: "empty destination relative path", @@ -101,20 +111,20 @@ func TestRenameRepository_invalidRequest(t *testing.T) { }, { desc: "repository storage doesn't exist", - req: &gitalypb.RenameRepositoryRequest{Repository: &gitalypb.Repository{StorageName: "stub", RelativePath: repo.RelativePath}, RelativePath: "../usr/bin"}, - exp: status.Error(codes.InvalidArgument, gitalyOrPraefect(`GetStorageByName: no such storage: "stub"`, "repo scoped: invalid Repository")), + req: &gitalypb.RenameRepositoryRequest{Repository: &gitalypb.Repository{StorageName: "stub", RelativePath: repo.RelativePath}, RelativePath: "usr/bin"}, + exp: status.Error(codes.InvalidArgument, `GetStorageByName: no such storage: "stub"`), }, { desc: "repository relative path doesn't exist", - req: &gitalypb.RenameRepositoryRequest{Repository: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "stub"}, RelativePath: "../usr/bin"}, - exp: status.Error(codes.NotFound, fmt.Sprintf(`GetRepoPath: not a git repository: "%s/stub"`, storagePath)), + req: &gitalypb.RenameRepositoryRequest{Repository: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "stub"}, RelativePath: "non-existent/directory"}, + exp: status.Error(codes.NotFound, fmt.Sprintf(`GetRepoPath: not a git repository: "%s/stub"`, gitalyOrPraefect(storagePath, repo.GetStorageName()))), }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { _, err := client.RenameRepository(ctx, tc.req) - testhelper.RequireGrpcError(t, err, tc.exp) + testhelper.RequireGrpcError(t, tc.exp, err) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack.go index 6ba97185d0..51164133d3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/prometheus/client_golang/prometheus" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) var repackCounter = prometheus.NewCounterVec( @@ -37,7 +37,16 @@ func (s *server) RepackFull(ctx context.Context, in *gitalypb.RepackFullRequest) repackCounter.WithLabelValues(fmt.Sprint(in.GetCreateBitmap())).Inc() if err := housekeeping.RepackObjects(ctx, repo, cfg); err != nil { - return nil, helper.ErrInternal(err) + return nil, helper.ErrInternalf("repacking objects: %w", err) + } + + writeCommitGraphCfg, err := housekeeping.WriteCommitGraphConfigForRepository(ctx, repo) + if err != nil { + return nil, helper.ErrInternalf("getting commit-graph config: %w", err) + } + + if err := housekeeping.WriteCommitGraph(ctx, repo, writeCommitGraphCfg); err != nil { + return nil, helper.ErrInternalf("writing commit-graph: %w", err) } return &gitalypb.RepackFullResponse{}, nil @@ -57,7 +66,16 @@ func (s *server) RepackIncremental(ctx context.Context, in *gitalypb.RepackIncre repackCounter.WithLabelValues(fmt.Sprint(false)).Inc() if err := housekeeping.RepackObjects(ctx, repo, cfg); err != nil { - return nil, err + return nil, helper.ErrInternalf("repacking objects: %w", err) + } + + writeCommitGraphCfg, err := housekeeping.WriteCommitGraphConfigForRepository(ctx, repo) + if err != nil { + return nil, helper.ErrInternalf("getting commit-graph config: %w", err) + } + + if err := housekeeping.WriteCommitGraph(ctx, repo, writeCommitGraphCfg); err != nil { + return nil, helper.ErrInternalf("writing commit-graph: %w", err) } return &gitalypb.RepackIncrementalResponse{}, nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack_test.go index 4dcc1b2637..fb42f8d047 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repack_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,11 +12,11 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -118,12 +120,12 @@ func TestRepackIncrementalFailure(t *testing.T) { { desc: "invalid storage name", repo: &gitalypb.Repository{StorageName: "foo"}, - err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`GetStorageByName: no such storage: "foo"`, "repo scoped: invalid Repository")), + err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`repacking objects: GetStorageByName: no such storage: "foo"`, "repo scoped: invalid Repository")), }, { desc: "no storage name", repo: &gitalypb.Repository{RelativePath: "bar"}, - err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`GetStorageByName: no such storage: ""`, "repo scoped: invalid Repository")), + err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`repacking objects: GetStorageByName: no such storage: ""`, "repo scoped: invalid Repository")), }, { desc: "non-existing repo", @@ -131,7 +133,7 @@ func TestRepackIncrementalFailure(t *testing.T) { err: status.Error( codes.NotFound, gitalyOrPraefect( - fmt.Sprintf(`GetRepoPath: not a git repository: "%s/bar"`, cfg.Storages[0].Path), + fmt.Sprintf(`repacking objects: GetRepoPath: not a git repository: "%s/bar"`, cfg.Storages[0].Path), praefectErr, ), ), @@ -217,23 +219,23 @@ func TestRepackFullCollectLogStatistics(t *testing.T) { mustCountObjectLog(t, hook.AllEntries()...) } -func mustCountObjectLog(t testing.TB, entries ...*logrus.Entry) { - t.Helper() +func mustCountObjectLog(tb testing.TB, entries ...*logrus.Entry) { + tb.Helper() const key = "count_objects" for _, entry := range entries { if entry.Message == "git repo statistic" { - require.Contains(t, entry.Data, "grpc.request.glProjectPath") - require.Contains(t, entry.Data, "grpc.request.glRepository") - require.Contains(t, entry.Data, key, "statistics not found") + require.Contains(tb, entry.Data, "grpc.request.glProjectPath") + require.Contains(tb, entry.Data, "grpc.request.glRepository") + require.Contains(tb, entry.Data, key, "statistics not found") objectStats, ok := entry.Data[key].(map[string]interface{}) - require.True(t, ok, "expected count_objects to be a map") - require.Contains(t, objectStats, "count") + require.True(tb, ok, "expected count_objects to be a map") + require.Contains(tb, objectStats, "count") return } } - require.FailNow(t, "no info about statistics") + require.FailNow(tb, "no info about statistics") } func doBitmapsContainHashCache(t *testing.T, bitmapPaths []string) { @@ -263,12 +265,12 @@ func TestRepackFullFailure(t *testing.T) { { desc: "invalid storage name", repo: &gitalypb.Repository{StorageName: "foo"}, - err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`GetStorageByName: no such storage: "foo"`, "repo scoped: invalid Repository")), + err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`repacking objects: GetStorageByName: no such storage: "foo"`, "repo scoped: invalid Repository")), }, { desc: "no storage name", repo: &gitalypb.Repository{RelativePath: "bar"}, - err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`GetStorageByName: no such storage: ""`, "repo scoped: invalid Repository")), + err: status.Error(codes.InvalidArgument, gitalyOrPraefect(`repacking objects: GetStorageByName: no such storage: ""`, "repo scoped: invalid Repository")), }, { desc: "non-existing repo", @@ -276,7 +278,7 @@ func TestRepackFullFailure(t *testing.T) { err: status.Error( codes.NotFound, gitalyOrPraefect( - fmt.Sprintf(`GetRepoPath: not a git repository: "%s/bar"`, cfg.Storages[0].Path), + fmt.Sprintf(`repacking objects: GetRepoPath: not a git repository: "%s/bar"`, cfg.Storages[0].Path), praefectErr, ), ), @@ -298,7 +300,7 @@ func TestRepackFullDeltaIslands(t *testing.T) { ctx := testhelper.Context(t) cfg, repo, repoPath, client := setupRepositoryService(ctx, t) - gittest.TestDeltaIslands(t, cfg, repoPath, func() error { + gittest.TestDeltaIslands(t, cfg, repoPath, repoPath, false, func() error { //nolint:staticcheck _, err := client.RepackFull(ctx, &gitalypb.RepackFullRequest{Repository: repo}) return err diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate.go index 847c4ece86..67a52eca36 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate.go @@ -7,24 +7,23 @@ import ( "fmt" "io" "os" - "os/exec" "path/filepath" "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -188,7 +187,10 @@ func (s *server) extractSnapshot(ctx context.Context, source, target *gitalypb.R } stderr := &bytes.Buffer{} - cmd, err := command.New(ctx, exec.Command("tar", "-C", targetPath, "-xvf", "-"), snapshotReader, nil, stderr) + cmd, err := command.New(ctx, []string{"tar", "-C", targetPath, "-xvf", "-"}, + command.WithStdin(snapshotReader), + command.WithStderr(stderr), + ) if err != nil { return fmt.Errorf("create tar command: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate_test.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate_test.go index 6ac836783c..89ca307b8b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/replicate_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/replicate_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -14,25 +16,22 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" @@ -48,12 +47,12 @@ func TestReplicateRepository(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil, testserver.WithDisablePraefect()) + client, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) cfg.SocketPath = serverSocketPath - client := newRepositoryClient(t, cfg, serverSocketPath) - - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) // create a loose object to ensure snapshot replication is used blobData, err := text.RandomHex(10) @@ -111,6 +110,89 @@ func TestReplicateRepository(t *testing.T) { gittest.Exec(t, cfg, "-C", targetRepoPath, "cat-file", "-p", blobID) } +func TestReplicateRepository_hiddenRefs(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages("default", "replica")) + cfg := cfgBuilder.Build(t) + + testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(t, cfg) + + client, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) + cfg.SocketPath = serverSocketPath + + ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) + + t.Run("initial seeding", func(t *testing.T) { + sourceRepo, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg) + + // Create a bunch of internal references, regardless of whether we classify them as hidden + // or read-only. We should be able to replicate all of them. + var expectedRefs []string + for refPrefix := range git.InternalRefPrefixes { + commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) + gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) + expectedRefs = append(expectedRefs, fmt.Sprintf("%s commit\t%s", commitID, refPrefix+"1")) + } + + targetRepo := proto.Clone(sourceRepo).(*gitalypb.Repository) + targetRepo.StorageName = cfg.Storages[1].Name + targetRepoPath := filepath.Join(cfg.Storages[1].Path, targetRepo.GetRelativePath()) + + _, err := client.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ + Repository: targetRepo, + Source: sourceRepo, + }) + require.NoError(t, err) + + require.ElementsMatch(t, expectedRefs, strings.Split(text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), "\n")) + + // Perform another sanity-check to verify that source and target repository have the + // same references now. + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", sourceRepoPath, "for-each-ref")), + text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), + ) + }) + + t.Run("incremental replication", func(t *testing.T) { + sourceRepo, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg) + targetRepo, targetRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + RelativePath: sourceRepo.GetRelativePath(), + Storage: cfg.Storages[1], + }) + + // Create the same commit in both repositories so that they're in a known-good + // state. + sourceCommitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage("base"), gittest.WithBranch("main")) + targetCommitID := gittest.WriteCommit(t, cfg, targetRepoPath, gittest.WithParents(), gittest.WithMessage("base"), gittest.WithBranch("main")) + require.Equal(t, sourceCommitID, targetCommitID) + + // Create the internal references now. + for refPrefix := range git.InternalRefPrefixes { + commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) + gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) + } + + // And now replicate the with the new internal references having been created. + // Because the target repository exists already we'll do a fetch instead of + // replicating via an archive. + _, err := client.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ + Repository: targetRepo, + Source: sourceRepo, + }) + require.NoError(t, err) + + // Verify that the references for both repositories match. + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", sourceRepoPath, "for-each-ref")), + text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), + ) + }) +} + func TestReplicateRepositoryTransactional(t *testing.T) { t.Parallel() @@ -121,10 +203,12 @@ func TestReplicateRepositoryTransactional(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil, testserver.WithDisablePraefect()) + _, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) cfg.SocketPath = serverSocketPath - sourceRepo, sourceRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + sourceRepo, sourceRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) targetRepo := proto.Clone(sourceRepo).(*gitalypb.Repository) targetRepo.StorageName = cfg.Storages[1].Name @@ -310,16 +394,16 @@ func TestReplicateRepository_BadRepository(t *testing.T) { { desc: "source invalid", invalidSource: true, - error: func(t testing.TB, actual error) { - testhelper.RequireGrpcError(t, actual, ErrInvalidSourceRepository) + error: func(tb testing.TB, actual error) { + testhelper.RequireGrpcError(tb, ErrInvalidSourceRepository, actual) }, }, { desc: "both invalid", invalidSource: true, invalidTarget: true, - error: func(t testing.TB, actual error) { - require.Equal(t, ErrInvalidSourceRepository, actual) + error: func(tb testing.TB, actual error) { + testhelper.RequireGrpcError(tb, ErrInvalidSourceRepository, actual) }, }, } { @@ -330,13 +414,14 @@ func TestReplicateRepository_BadRepository(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil, testserver.WithDisablePraefect()) + client, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) cfg.SocketPath = serverSocketPath - client := newRepositoryClient(t, cfg, serverSocketPath) - - sourceRepo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - targetRepo, targetRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[1], gittest.CloneRepoOpts{ + sourceRepo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + targetRepo, targetRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Storage: cfg.Storages[1], RelativePath: sourceRepo.RelativePath, }) @@ -386,9 +471,12 @@ func TestReplicateRepository_FailedFetchInternalRemote(t *testing.T) { // Our test setup does not allow for Praefects with multiple storages. We thus have to // disable Praefect here. - cfg.SocketPath = runRepositoryServerWithConfig(t, cfg, nil, testserver.WithDisablePraefect()) + client, socketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) + cfg.SocketPath = socketPath - targetRepo, _ := gittest.InitRepo(t, cfg, cfg.Storages[1]) + targetRepo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Storage: cfg.Storages[1], + }) // The source repository must be at the same path as the target repository, and it must be a // real repository. In order to still have the fetch fail, we corrupt the repository by @@ -405,9 +493,7 @@ func TestReplicateRepository_FailedFetchInternalRemote(t *testing.T) { ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) - repoClient := newRepositoryClient(t, cfg, cfg.SocketPath) - - _, err = repoClient.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ + _, err = client.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ Repository: targetRepo, Source: sourceRepo, }) @@ -429,7 +515,7 @@ func listenGitalySSHCalls(t *testing.T, conf config.Cfg) func() gitalySSHParams t.Helper() require.NotEmpty(t, conf.BinDir) - initialPath := filepath.Join(conf.BinDir, "gitaly-ssh") + initialPath := conf.BinaryPath("gitaly-ssh") updatedPath := initialPath + "-actual" require.NoError(t, os.Rename(initialPath, updatedPath)) @@ -465,19 +551,7 @@ func TestFetchInternalRemote_successful(t *testing.T) { testcfg.BuildGitalyHooks(t, remoteCfg) gittest.WriteCommit(t, remoteCfg, remoteRepoPath, gittest.WithBranch("master")) - remoteAddr := testserver.RunGitalyServer(t, remoteCfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterSSHServiceServer(srv, ssh.NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - )) - gitalypb.RegisterRefServiceServer(srv, ref.NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - deps.GetCatfileCache(), - )) - }, testserver.WithDisablePraefect()) + _, remoteAddr := runRepositoryService(t, remoteCfg, nil, testserver.WithDisablePraefect()) localCfg, localRepoProto, localRepoPath := testcfg.BuildWithRepo(t) localRepo := localrepo.NewTestRepo(t, localCfg, localRepoProto) @@ -489,13 +563,7 @@ func TestFetchInternalRemote_successful(t *testing.T) { // We do not require the server's address, but it needs to be around regardless such that // `FetchInternalRemote` can reach the hook service which is injected via the config. - testserver.RunGitalyServer(t, localCfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterHookServiceServer(srv, hook.NewServer( - deps.GetHookManager(), - deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - )) - }, testserver.WithHookManager(gitalyhook.NewMockManager(t, nil, nil, nil, + runRepositoryService(t, localCfg, nil, testserver.WithHookManager(gitalyhook.NewMockManager(t, nil, nil, nil, func(t *testing.T, _ context.Context, _ gitalyhook.ReferenceTransactionState, _ []string, stdin io.Reader) error { // We need to discard stdin or otherwise the sending Goroutine may return an // EOF error and cause the test to fail. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository.go index f4858a8021..1f49b13c84 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository.go @@ -3,9 +3,9 @@ package repository import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository_test.go index a5cd0d85bf..74faba1c77 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -5,27 +7,30 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) func TestRepositoryExists(t *testing.T) { t.Parallel() + + ctx := testhelper.Context(t) cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages("default", "other", "broken")) cfg := cfgBuilder.Build(t) require.NoError(t, os.RemoveAll(cfg.Storages[2].Path), "third storage needs to be invalid") - serverSocketPath := runRepositoryServerWithConfig(t, cfg, nil, testserver.WithDisablePraefect()) + client, socketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) + cfg.SocketPath = socketPath - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - - client := newRepositoryClient(t, cfg, serverSocketPath) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) queries := []struct { desc string @@ -94,7 +99,6 @@ func TestRepositoryExists(t *testing.T) { for _, tc := range queries { t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) response, err := client.RepositoryExists(ctx, tc.request) require.Equal(t, tc.errorCode, helper.GrpcCode(err)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks.go index bb68650496..a3e2289e77 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks.go @@ -5,19 +5,18 @@ import ( "errors" "fmt" "os" - "os/exec" "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -62,7 +61,7 @@ func (s *server) RestoreCustomHooks(stream gitalypb.RepositoryService_RestoreCus } ctx := stream.Context() - cmd, err := command.New(ctx, exec.Command("tar", cmdArgs...), reader, nil, nil) + cmd, err := command.New(ctx, append([]string{"tar"}, cmdArgs...), command.WithStdin(reader)) if err != nil { return status.Errorf(codes.Internal, "RestoreCustomHooks: Could not untar custom hooks tar %v", err) } @@ -149,7 +148,7 @@ func (s *server) restoreCustomHooksWithVoting(stream gitalypb.RepositoryService_ customHooksDir, } - cmd, err := command.New(ctx, exec.Command("tar", cmdArgs...), reader, nil, nil) + cmd, err := command.New(ctx, append([]string{"tar"}, cmdArgs...), command.WithStdin(reader)) if err != nil { return helper.ErrInternalf("RestoreCustomHooks: Could not untar custom hooks tar %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks_test.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks_test.go index 8c02e0b4c3..e05e74a2d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/restore_custom_hooks_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/restore_custom_hooks_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -9,19 +11,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) @@ -38,23 +38,9 @@ func testSuccessfulRestoreCustomHooksRequest(t *testing.T, ctx context.Context) testcfg.BuildGitalyHooks(t, cfg) txManager := transaction.NewTrackingManager() - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterRepositoryServiceServer(srv, NewServer( - deps.GetCfg(), - deps.GetRubyServer(), - deps.GetLocator(), - deps.GetTxManager(), - deps.GetGitCmdFactory(), - deps.GetCatfileCache(), - deps.GetConnsPool(), - deps.GetGit2goExecutor(), - deps.GetHousekeepingManager(), - )) - }, testserver.WithTransactionManager(txManager)) + client, addr := runRepositoryService(t, cfg, nil, testserver.WithTransactionManager(txManager)) cfg.SocketPath = addr - client := newRepositoryClient(t, cfg, addr) - ctx, err := txinfo.InjectTransaction(ctx, 1, "node", true) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files.go index 4e37af1dd8..ba7598888a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files.go @@ -8,12 +8,12 @@ import ( "math" "regexp" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) const ( @@ -131,6 +131,11 @@ func (s *server) SearchFilesByName(req *gitalypb.SearchFilesByNameRequest, strea git.Flag{Name: "--full-tree"}, git.Flag{Name: "--name-status"}, git.Flag{Name: "-r"}, + // We use -z to force NULL byte termination here to prevent git from + // quoting and escaping unusual file names. Lstree parser would be a + // more ideal solution. Unfortunately, it supports parsing full + // output while we are interested in the filenames only. + git.Flag{Name: "-z"}, }, Args: []string{string(req.GetRef()), req.GetQuery()}}) if err != nil { return helper.ErrInternalf("SearchFilesByName: cmd start failed: %v", err) @@ -140,7 +145,7 @@ func (s *server) SearchFilesByName(req *gitalypb.SearchFilesByNameRequest, strea return stream.Send(&gitalypb.SearchFilesByNameResponse{Files: objs}) } - return lines.Send(cmd, lr, lines.SenderOpts{Delimiter: '\n', Limit: math.MaxInt32, Filter: filter}) + return lines.Send(cmd, lr, lines.SenderOpts{Delimiter: 0x00, Limit: math.MaxInt32, Filter: filter}) } type searchFilesRequest interface { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files_test.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files_test.go index bd6443ba35..092ef976af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/search_files_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/search_files_test.go @@ -1,26 +1,25 @@ +//go:build !gitaly_test_sha256 + package repository import ( "bytes" - "fmt" "io" - "os" - "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -152,55 +151,52 @@ func TestSearchFilesByContentSuccessful(t *testing.T) { func TestSearchFilesByContentLargeFile(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupRepositoryServiceWithWorktree(ctx, t) + cfg, repo, repoPath, client := setupRepositoryService(ctx, t) - committerName := "Scrooge McDuck" - committerEmail := "scrooge@mcduck.com" - - largeFiles := []struct { + for _, tc := range []struct { + desc string filename string line string repeated int query string }{ { + desc: "large file", filename: "large_file_of_abcdefg_2mb", line: "abcdefghi\n", // 10 bytes repeated: 210000, query: "abcdefg", }, { + desc: "large file with unicode", filename: "large_file_of_unicode_1.5mb", line: "你见天吃了什么东西?\n", // 22 bytes repeated: 70000, query: "什么东西", }, - } - - for _, largeFile := range largeFiles { - t.Run(largeFile.filename, func(t *testing.T) { - require.NoError(t, os.WriteFile(filepath.Join(repoPath, largeFile.filename), bytes.Repeat([]byte(largeFile.line), largeFile.repeated), 0o644)) - // By default, the worktree is detached. Checkout master so the branch advances with the commit. - gittest.Exec(t, cfg, "-C", repoPath, "checkout", "master") - gittest.Exec(t, cfg, "-C", repoPath, "add", ".") - gittest.Exec(t, cfg, "-C", repoPath, - "-c", fmt.Sprintf("user.name=%s", committerName), - "-c", fmt.Sprintf("user.email=%s", committerEmail), "commit", "-m", "large file commit", "--", largeFile.filename) + } { + t.Run(tc.filename, func(t *testing.T) { + gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(gittest.TreeEntry{ + Path: tc.filename, + Mode: "100644", + Content: strings.Repeat(tc.line, tc.repeated), + }), gittest.WithBranch("master")) stream, err := client.SearchFilesByContent(ctx, &gitalypb.SearchFilesByContentRequest{ Repository: repo, - Query: largeFile.query, + Query: tc.query, Ref: []byte("master"), ChunkedResponse: true, }) require.NoError(t, err) - resp, err := consumeFilenameByContentChunked(stream) + response, err := consumeFilenameByContentChunked(stream) require.NoError(t, err) - require.Equal(t, largeFile.repeated, len(bytes.Split(bytes.TrimRight(resp[0], "\n"), []byte("\n")))) + require.Equal(t, tc.repeated, len(bytes.Split(bytes.TrimRight(response[0], "\n"), []byte("\n")))) }) } } @@ -341,6 +337,104 @@ func TestSearchFilesByNameSuccessful(t *testing.T) { } } +func TestSearchFilesByNameUnusualFileNamesSuccessful(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) + + cfg, repo, repoPath, client := setupRepositoryService(ctx, t) + + ref := []byte("unusual_file_names") + gittest.WriteCommit(t, cfg, repoPath, + gittest.WithBranch(string(ref)), + gittest.WithMessage("commit message"), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "\"file with quote.txt", Mode: "100644", Content: "something"}, + gittest.TreeEntry{Path: ".vimrc", Mode: "100644", Content: "something"}, + gittest.TreeEntry{Path: "cuộc đời là những chuyến đi.md", Mode: "100644", Content: "something"}, + gittest.TreeEntry{Path: "编码 'foo'.md", Mode: "100644", Content: "something"}, + ), + ) + + testCases := []struct { + desc string + query string + filter string + expectedFiles [][]byte + }{ + { + desc: "file with quote", + query: "\"file with quote.txt", + expectedFiles: [][]byte{[]byte("\"file with quote.txt")}, + }, + { + desc: "dotfiles", + query: ".vimrc", + expectedFiles: [][]byte{[]byte(".vimrc")}, + }, + { + desc: "latin-base language", + query: "cuộc đời là những chuyến đi.md", + expectedFiles: [][]byte{[]byte("cuộc đời là những chuyến đi.md")}, + }, + { + desc: "non-latin language", + query: "编码 'foo'.md", + expectedFiles: [][]byte{[]byte("编码 'foo'.md")}, + }, + { + desc: "filter file with quote", + query: ".", + filter: "^\"file.*", + expectedFiles: [][]byte{[]byte("\"file with quote.txt")}, + }, + { + desc: "filter dotfiles", + query: ".", + filter: "^\\..*", + expectedFiles: [][]byte{[]byte(".vimrc")}, + }, + { + desc: "filter latin-base language", + query: ".", + filter: "cuộc đời .*\\.md", + expectedFiles: [][]byte{[]byte("cuộc đời là những chuyến đi.md")}, + }, + { + desc: "filter non-latin language", + query: ".", + filter: "编码 'foo'\\.(md|txt|rdoc)", + expectedFiles: [][]byte{[]byte("编码 'foo'.md")}, + }, + { + desc: "wildcard filter", + query: ".", + filter: ".*", + expectedFiles: [][]byte{ + []byte("\"file with quote.txt"), + []byte(".vimrc"), + []byte("cuộc đời là những chuyến đi.md"), + []byte("编码 'foo'.md"), + }, + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + stream, err := client.SearchFilesByName(ctx, &gitalypb.SearchFilesByNameRequest{ + Repository: repo, + Ref: ref, + Query: tc.query, + Filter: tc.filter, + }) + require.NoError(t, err) + + var files [][]byte + files, err = consumeFilenameByName(stream) + require.NoError(t, err) + require.Equal(t, tc.expectedFiles, files) + }) + } +} + func TestSearchFilesByNameFailure(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server.go index 3f9e7cf65f..a6d8faa07c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server.go @@ -1,18 +1,18 @@ package repository import ( - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { @@ -23,7 +23,6 @@ type server struct { txManager transaction.Manager gitCmdFactory git.CommandFactory cfg config.Cfg - binDir string loggingCfg config.Logging catfileCache catfile.Cache git2goExecutor *git2go.Executor @@ -49,7 +48,6 @@ func NewServer( gitCmdFactory: gitCmdFactory, conns: connsPool, cfg: cfg, - binDir: cfg.BinDir, loggingCfg: cfg.Logging, catfileCache: catfileCache, git2goExecutor: git2goExecutor, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server_test.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server_test.go index 042b0f3261..fd2165a2cf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/server_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/server_test.go @@ -1,12 +1,14 @@ +//go:build !gitaly_test_sha256 + package repository import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size.go new file mode 100644 index 0000000000..df03e23000 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size.go @@ -0,0 +1,204 @@ +package repository + +import ( + "bytes" + "context" + "fmt" + "io" + "strconv" + + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gitpipe" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// RepositorySize returns the size of the specified repository in kibibytes. +// By default, this calculation is performed using the disk usage command. +// +// Optionally the feature flags `revlist_for_repo_size` or `catfile_repo_size` +// can be enabled to log an alternative calculation of the repository size. +// The original size derived from disk usage is still returned. +// +// In conjunction with the other flags the `use_new_repository_size` feature +// flag can be enabled to return the alternative repository size calculation +// instead of the size derived from the disk usage command. +func (s *server) RepositorySize(ctx context.Context, in *gitalypb.RepositorySizeRequest) (*gitalypb.RepositorySizeResponse, error) { + repo := s.localrepo(in.GetRepository()) + + path, err := repo.Path() + if err != nil { + return nil, err + } + + sizeKiB := getPathSize(ctx, path) + + logger := ctxlogrus.Extract(ctx).WithField("repo_size_du_bytes", sizeKiB*1024) + + var newSizeBytes int64 + if featureflag.RevlistForRepoSize.IsEnabled(ctx) { + newSizeBytes, err = calculateSizeWithRevlist(ctx, repo) + if err != nil { + return nil, fmt.Errorf("calculating repository size with git-rev-list: %w", err) + } + + logger.WithField("repo_size_revlist_bytes", newSizeBytes).Info("repository size calculated") + + if featureflag.UseNewRepoSize.IsEnabled(ctx) { + sizeKiB = newSizeBytes / 1024 + } + } else if featureflag.CatfileRepoSize.IsEnabled(ctx) { + newSizeBytes, err = calculateSizeWithCatfile( + ctx, + repo, + s.locator, + s.gitCmdFactory, + s.catfileCache, + s.txManager, + s.housekeepingManager, + ) + if err != nil { + return nil, fmt.Errorf("calculating repository size with git-cat-file: %w", err) + } + + logger.WithField("repo_size_catfile_bytes", newSizeBytes).Info("repository size calculated") + + if featureflag.UseNewRepoSize.IsEnabled(ctx) { + sizeKiB = newSizeBytes / 1024 + } + } + + return &gitalypb.RepositorySizeResponse{Size: sizeKiB}, nil +} + +// calculateSizeWithCatfile calculates the repository size using git-cat-file. +// In the case the repository belongs to a pool, it will subract the total +// size of the pool repository objects from its total size. One limitation of +// this approach is that we don't distinguish whether an object in the pool +// repository belongs to the fork repository, so in fact we may end up with a +// smaller total size and theoretically could go negative. +func calculateSizeWithCatfile( + ctx context.Context, + repo *localrepo.Repo, + locator storage.Locator, + gitCmdFactory git.CommandFactory, + catfileCache catfile.Cache, + txManager transaction.Manager, + housekeepingManager housekeeping.Manager, +) (int64, error) { + var size int64 + + catfileInfoIterator := gitpipe.CatfileInfoAllObjects( + ctx, + repo, + gitpipe.WithDiskUsageSize(), + ) + + for catfileInfoIterator.Next() { + size += catfileInfoIterator.Result().ObjectSize() + } + + if err := catfileInfoIterator.Err(); err != nil { + return 0, err + } + + var poolSize int64 + + if pool, err := objectpool.FromRepo( + locator, + gitCmdFactory, + catfileCache, + txManager, + housekeepingManager, + repo, + ); err == nil && pool != nil { + catfileInfoIterator = gitpipe.CatfileInfoAllObjects( + ctx, + pool.Repo, + gitpipe.WithDiskUsageSize(), + ) + + for catfileInfoIterator.Next() { + poolSize += catfileInfoIterator.Result().ObjectSize() + } + + if err := catfileInfoIterator.Err(); err != nil { + return 0, err + } + } + + size -= poolSize + // return the size in bytes + return size, nil +} + +func calculateSizeWithRevlist(ctx context.Context, repo *localrepo.Repo) (int64, error) { + var excludes []string + for refPrefix := range git.InternalRefPrefixes { + excludes = append(excludes, refPrefix+"*") + } + + size, err := repo.Size( + ctx, + localrepo.WithExcludeRefs(excludes...), + localrepo.WithoutAlternates(), + ) + if err != nil { + return 0, err + } + + // return the size in bytes + return size, nil +} + +func (s *server) GetObjectDirectorySize(ctx context.Context, in *gitalypb.GetObjectDirectorySizeRequest) (*gitalypb.GetObjectDirectorySizeResponse, error) { + repo := s.localrepo(in.GetRepository()) + + path, err := repo.ObjectDirectoryPath() + if err != nil { + return nil, err + } + + return &gitalypb.GetObjectDirectorySizeResponse{Size: getPathSize(ctx, path)}, nil +} + +func getPathSize(ctx context.Context, path string) int64 { + cmd, err := command.New(ctx, []string{"du", "-sk", path}) + if err != nil { + ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring du command error") + return 0 + } + + sizeLine, err := io.ReadAll(cmd) + if err != nil { + ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring command read error") + return 0 + } + + if err := cmd.Wait(); err != nil { + ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring du wait error") + return 0 + } + + sizeParts := bytes.Split(sizeLine, []byte("\t")) + if len(sizeParts) != 2 { + ctxlogrus.Extract(ctx).Warn(fmt.Sprintf("ignoring du malformed output: %q", sizeLine)) + return 0 + } + + size, err := strconv.ParseInt(string(sizeParts[0]), 10, 0) + if err != nil { + ctxlogrus.Extract(ctx).WithError(err).Warn("ignoring parsing size error") + return 0 + } + + return size +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size_test.go index b9c7527239..0abb67c41d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/size_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/size_test.go @@ -1,16 +1,27 @@ +//go:build !gitaly_test_sha256 + package repository import ( + "bytes" "context" "testing" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/quarantine" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/quarantine" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" ) @@ -21,12 +32,87 @@ const testRepoMinSizeKB = 10000 func TestRepositorySize_SuccessfulRequest(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.RevlistForRepoSize). - Run(t, testSuccessfulRepositorySizeRequest) + + featureSet := testhelper.NewFeatureSets( + featureflag.RevlistForRepoSize, + featureflag.CatfileRepoSize, + featureflag.UseNewRepoSize, + ) + + featureSet.Run(t, testSuccessfulRepositorySizeRequest) + featureSet.Run(t, testSuccessfulRepositorySizeRequestPoolMember) +} + +func testSuccessfulRepositorySizeRequestPoolMember(t *testing.T, ctx context.Context) { + cfg := testcfg.Build(t) + + repoClient, serverSocketPath := runRepositoryService(t, cfg, nil) + cfg.SocketPath = serverSocketPath + + objectPoolClient := newObjectPoolClient(t, cfg, serverSocketPath) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + sizeRequest := &gitalypb.RepositorySizeRequest{Repository: repo} + response, err := repoClient.RepositorySize(ctx, sizeRequest) + require.NoError(t, err) + + sizeBeforePool := response.GetSize() + + storage := cfg.Storages[0] + relativePath := gittest.NewObjectPoolName(t) + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + + // create an object pool + gittest.InitRepoDir(t, storage.Path, relativePath) + pool, err := objectpool.NewObjectPool( + config.NewLocator(cfg), + gittest.NewCommandFactory(t, cfg), + catfileCache, + nil, + nil, + storage.Name, + relativePath, + ) + require.NoError(t, err) + + _, err = objectPoolClient.CreateObjectPool( + ctx, + &gitalypb.CreateObjectPoolRequest{ + ObjectPool: pool.ToProto(), + Origin: repo, + }) + require.NoError(t, err) + + _, err = objectPoolClient.LinkRepositoryToObjectPool( + ctx, + &gitalypb.LinkRepositoryToObjectPoolRequest{ + Repository: repo, + ObjectPool: pool.ToProto(), + }, + ) + require.NoError(t, err) + + gittest.Exec(t, cfg, "-C", repoPath, "gc") + + response, err = repoClient.RepositorySize(ctx, sizeRequest) + require.NoError(t, err) + + if featureflag.UseNewRepoSize.IsEnabled(ctx) && + (featureflag.RevlistForRepoSize.IsEnabled(ctx) || + featureflag.CatfileRepoSize.IsEnabled(ctx)) { + assert.Equal(t, int64(0), response.GetSize()) + } else { + assert.Less(t, response.GetSize(), sizeBeforePool) + } } func testSuccessfulRepositorySizeRequest(t *testing.T, ctx context.Context) { - _, repo, _, client := setupRepositoryService(ctx, t) + logger, hook := test.NewNullLogger() + cfg, repo, repoPath, client := setupRepositoryService(ctx, t, testserver.WithLogger(logger)) request := &gitalypb.RepositorySizeRequest{Repository: repo} response, err := client.RepositorySize(ctx, request) @@ -36,9 +122,85 @@ func testSuccessfulRepositorySizeRequest(t *testing.T, ctx context.Context) { response.Size > testRepoMinSizeKB, "repository size %d should be at least %d", response.Size, testRepoMinSizeKB, ) + + blob := bytes.Repeat([]byte("a"), 1000) + blobOID := gittest.WriteBlob(t, cfg, repoPath, blob) + treeOID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + { + OID: blobOID, + Mode: "100644", + Path: "1kbblob", + }, + }) + commitOID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTree(treeOID)) + + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName("refs/keep-around/keep1"), commitOID) + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName("refs/merge-requests/1123"), commitOID) + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName("refs/pipelines/pipeline2"), commitOID) + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName("refs/environments/env1"), commitOID) + + responseAfterRefs, err := client.RepositorySize(ctx, request) + require.NoError(t, err) + + // We expect two log entries with "repository size calculated" + // since we called RepositorySize twice, but we are really interested + // in the results of the second log. + var entries []*logrus.Entry + switch { + case featureflag.RevlistForRepoSize.IsEnabled(ctx): + for _, entry := range hook.AllEntries() { + _, ok := entry.Data["repo_size_revlist_bytes"] + if ok { + entries = append(entries, entry) + } + } + + require.Len(t, entries, 2) + revlistSizeInLog, ok := entries[1].Data["repo_size_revlist_bytes"] + require.True(t, ok) + require.Equal(t, "repository size calculated", entries[1].Message) + + duSizeInLog, ok := entries[1].Data["repo_size_du_bytes"] + require.True(t, ok) + + require.Less(t, revlistSizeInLog, duSizeInLog) + if featureflag.UseNewRepoSize.IsEnabled(ctx) { + assert.Equal( + t, + response.Size, + responseAfterRefs.Size, + "excluded refs do not contribute to the repository size", + ) + } + case featureflag.CatfileRepoSize.IsEnabled(ctx): + for _, entry := range hook.AllEntries() { + _, ok := entry.Data["repo_size_catfile_bytes"] + if ok { + entries = append(entries, entry) + } + } + + require.Len(t, entries, 2) + catfileSizeInLog, ok := entries[1].Data["repo_size_catfile_bytes"] + require.True(t, ok) + duSizeInLog, ok := entries[1].Data["repo_size_du_bytes"] + require.True(t, ok) + + require.Equal(t, "repository size calculated", entries[1].Message) + + require.Less(t, catfileSizeInLog, duSizeInLog) + + if featureflag.UseNewRepoSize.IsEnabled(ctx) { + // Because we divide by 1024 to get kibibytes, small + // differences might not appear in the final size. + assert.LessOrEqual(t, response.Size, responseAfterRefs.Size) + } + default: + assert.Less(t, response.Size, responseAfterRefs.Size) + } } -func TestRepositorySixe_FailedRequest(t *testing.T) { +func TestRepositorySize_FailedRequest(t *testing.T) { t.Parallel() testhelper.NewFeatureSets(featureflag.RevlistForRepoSize). Run(t, testFailedRepositorySizeRequest) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot.go index e4f277f6fd..5144d941b1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot.go @@ -8,11 +8,11 @@ import ( "regexp" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) var objectFiles = []*regexp.Regexp{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot_test.go index 4813c86ae9..c10b9a7f8d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/snapshot_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/snapshot_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -12,18 +14,18 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/archive" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" ) -func getSnapshot(t testing.TB, client gitalypb.RepositoryServiceClient, req *gitalypb.GetSnapshotRequest) ([]byte, error) { - ctx := testhelper.Context(t) +func getSnapshot(tb testing.TB, client gitalypb.RepositoryServiceClient, req *gitalypb.GetSnapshotRequest) ([]byte, error) { + ctx := testhelper.Context(tb) stream, err := client.GetSnapshot(ctx, req) if err != nil { @@ -250,10 +252,10 @@ func copyRepoUsingSnapshot(t *testing.T, ctx context.Context, cfg config.Cfg, cl srv := httptest.NewServer(&tarTesthandler{tarData: bytes.NewBuffer(data), secret: secret}) defer srv.Close() - repoCopy, repoCopyPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) - - // Delete the repository so we can re-use the path - require.NoError(t, os.RemoveAll(repoCopyPath)) + repoCopy := &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: gittest.NewRepositoryName(t, true), + } createRepoReq := &gitalypb.CreateRepositoryFromSnapshotRequest{ Repository: repoCopy, @@ -264,7 +266,8 @@ func copyRepoUsingSnapshot(t *testing.T, ctx context.Context, cfg config.Cfg, cl rsp, err := client.CreateRepositoryFromSnapshot(ctx, createRepoReq) require.NoError(t, err) testhelper.ProtoEqual(t, rsp, &gitalypb.CreateRepositoryFromSnapshotResponse{}) - return repoCopy, repoCopyPath + + return repoCopy, filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(ctx, t, cfg, repoCopy)) } func TestGetSnapshotFailsIfRepositoryMissing(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/advertise.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/advertise.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/advertise.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/advertise.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/checksum-test-invalid-refs b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/checksum-test-invalid-refs similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/checksum-test-invalid-refs rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/checksum-test-invalid-refs diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/checksum-test-packed-refs b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/checksum-test-packed-refs similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/checksum-test-packed-refs rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/checksum-test-packed-refs diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/corrupted_hooks.tar b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/corrupted_hooks.tar similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/corrupted_hooks.tar rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/corrupted_hooks.tar diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/custom_hooks.tar b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/custom_hooks.tar similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/custom_hooks.tar rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/custom_hooks.tar diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/fixed-size-repo.git/HEAD b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/fixed-size-repo.git/HEAD similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/fixed-size-repo.git/HEAD rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/fixed-size-repo.git/HEAD diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/fixed-size-repo.git/config b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/fixed-size-repo.git/config similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testdata/fixed-size-repo.git/config rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/fixed-size-repo.git/config diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gnu_license.deprecated.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gnu_license.deprecated.txt new file mode 100644 index 0000000000..f288702d2f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gnu_license.deprecated.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gpl-2.0_license.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gpl-2.0_license.txt new file mode 100644 index 0000000000..8e935f5ff1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testdata/gpl-2.0_license.txt @@ -0,0 +1,125 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testhelper_test.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testhelper_test.go index bd289de33b..c7b1d4be7f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/testhelper_test.go @@ -1,9 +1,10 @@ +//go:build !gitaly_test_sha256 + package repository import ( "context" "os" - "path/filepath" "reflect" "runtime" "testing" @@ -11,22 +12,23 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - gclient "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - internalclient "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + gclient "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -64,18 +66,28 @@ func TestWithRubySidecar(t *testing.T) { } } -func newRepositoryClient(t testing.TB, cfg config.Cfg, serverSocketPath string) gitalypb.RepositoryServiceClient { - var connOpts []grpc.DialOption +func newRepositoryClient(tb testing.TB, cfg config.Cfg, serverSocketPath string) gitalypb.RepositoryServiceClient { + connOpts := []grpc.DialOption{ + internalclient.UnaryInterceptor(), internalclient.StreamInterceptor(), + } if cfg.Auth.Token != "" { connOpts = append(connOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token))) } conn, err := gclient.Dial(serverSocketPath, connOpts) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, conn.Close()) }) + require.NoError(tb, err) + tb.Cleanup(func() { require.NoError(tb, conn.Close()) }) return gitalypb.NewRepositoryServiceClient(conn) } +func newObjectPoolClient(tb testing.TB, cfg config.Cfg, serverSocketPath string) gitalypb.ObjectPoolServiceClient { + conn, err := gclient.Dial(serverSocketPath, nil) + require.NoError(tb, err) + tb.Cleanup(func() { require.NoError(tb, conn.Close()) }) + + return gitalypb.NewObjectPoolServiceClient(conn) +} + func newMuxedRepositoryClient(t *testing.T, ctx context.Context, cfg config.Cfg, serverSocketPath string, handshaker internalclient.Handshaker) gitalypb.RepositoryServiceClient { conn, err := internalclient.Dial(ctx, serverSocketPath, []grpc.DialOption{ grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token)), @@ -101,8 +113,8 @@ func assertModTimeAfter(t *testing.T, afterTime time.Time, paths ...string) bool return t.Failed() } -func runRepositoryServerWithConfig(t testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server, opts ...testserver.GitalyServerOpt) string { - return testserver.RunGitalyServer(t, cfg, rubySrv, func(srv *grpc.Server, deps *service.Dependencies) { +func runRepositoryService(tb testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server, opts ...testserver.GitalyServerOpt) (gitalypb.RepositoryServiceClient, string) { + serverSocketPath := testserver.RunGitalyServer(tb, cfg, rubySrv, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterRepositoryServiceServer(srv, NewServer( cfg, deps.GetRubyServer(), @@ -114,7 +126,7 @@ func runRepositoryServerWithConfig(t testing.TB, cfg config.Cfg, rubySrv *rubyse deps.GetGit2goExecutor(), deps.GetHousekeepingManager(), )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterRemoteServiceServer(srv, remote.NewServer( deps.GetLocator(), deps.GetGitCmdFactory(), @@ -139,56 +151,49 @@ func runRepositoryServerWithConfig(t testing.TB, cfg config.Cfg, rubySrv *rubyse nil, deps.GetCatfileCache(), )) + gitalypb.RegisterObjectPoolServiceServer(srv, objectpool.NewServer( + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetTxManager(), + deps.GetHousekeepingManager(), + )) }, opts...) + + return newRepositoryClient(tb, cfg, serverSocketPath), serverSocketPath } -func runRepositoryService(t testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server, opts ...testserver.GitalyServerOpt) (gitalypb.RepositoryServiceClient, string) { - serverSocketPath := runRepositoryServerWithConfig(t, cfg, rubySrv, opts...) - client := newRepositoryClient(t, cfg, serverSocketPath) +func setupRepositoryService(ctx context.Context, tb testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.RepositoryServiceClient) { + cfg, client := setupRepositoryServiceWithoutRepo(tb, opts...) - return client, serverSocketPath -} - -func setupRepositoryService(ctx context.Context, t testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.RepositoryServiceClient) { - cfg, client := setupRepositoryServiceWithoutRepo(t, opts...) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) return cfg, repo, repoPath, client } // Sets up a repository that has been cloned using `--mirror` which contains GitLab internal references -func setupRepositoryServiceFromMirror(ctx context.Context, t testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.RepositoryServiceClient) { - cfg, client := setupRepositoryServiceWithoutRepo(t, opts...) +func setupRepositoryServiceFromMirror(ctx context.Context, tb testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.RepositoryServiceClient) { + cfg, client := setupRepositoryServiceWithoutRepo(tb, opts...) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + repo, repoPath := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTestMirror, }) return cfg, repo, repoPath, client } -func setupRepositoryServiceWithoutRepo(t testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, gitalypb.RepositoryServiceClient) { - cfg := testcfg.Build(t) +func setupRepositoryServiceWithoutRepo(tb testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, gitalypb.RepositoryServiceClient) { + cfg := testcfg.Build(tb) - testcfg.BuildGitalyHooks(t, cfg) - testcfg.BuildGitalySSH(t, cfg) + testcfg.BuildGitalyHooks(tb, cfg) + testcfg.BuildGitalySSH(tb, cfg) - client, serverSocketPath := runRepositoryService(t, cfg, nil, opts...) + client, serverSocketPath := runRepositoryService(tb, cfg, nil, opts...) cfg.SocketPath = serverSocketPath return cfg, client } -func setupRepositoryServiceWithWorktree(ctx context.Context, t testing.TB, opts ...testserver.GitalyServerOpt) (config.Cfg, *gitalypb.Repository, string, gitalypb.RepositoryServiceClient) { - cfg, repo, repoPath, client := setupRepositoryService(ctx, t, opts...) - - gittest.AddWorktree(t, cfg, repoPath, "worktree") - repoPath = filepath.Join(repoPath, "worktree") - - return cfg, repo, repoPath, client -} - func gitalyOrPraefect(gitalyMsg, praefectMsg string) string { if testhelper.IsPraefectEnabled() { return praefectMsg diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util.go index 852995543b..9f11c3707c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util.go @@ -10,13 +10,13 @@ import ( "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/tempdir" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) removeOriginInRepo(ctx context.Context, repository *gitalypb.Repository) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util_test.go index ffbb800019..8991ecad83 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/util_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/util_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repository import ( @@ -10,18 +12,18 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/peer" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref.go index d4ef97f50e..e0a83f561a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository/write_ref.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref.go @@ -5,11 +5,11 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) WriteRef(ctx context.Context, req *gitalypb.WriteRefRequest) (*gitalypb.WriteRefResponse, error) { @@ -38,16 +38,51 @@ func (s *server) writeRef(ctx context.Context, req *gitalypb.WriteRefRequest) er } func updateRef(ctx context.Context, repo *localrepo.Repo, req *gitalypb.WriteRefRequest) error { + var newObjectID git.ObjectID + if git.ObjectHashSHA1.IsZeroOID(git.ObjectID(req.GetRevision())) { + // Passing the all-zeroes object ID as new value means that we should delete the + // reference. + newObjectID = git.ObjectHashSHA1.ZeroOID + } else { + // We need to resolve the new revision in order to make sure that we're actually + // passing an object ID to git-update-ref(1), but more importantly this will also + // ensure that the object ID we're updating to actually exists. Note that we also + // verify that the object actually exists in the repository by adding "^{object}". + var err error + newObjectID, err = repo.ResolveRevision(ctx, git.Revision(req.GetRevision())+"^{object}") + if err != nil { + return fmt.Errorf("resolving new revision: %w", err) + } + } + + var oldObjectID git.ObjectID + if len(req.GetOldRevision()) > 0 { + if git.ObjectHashSHA1.IsZeroOID(git.ObjectID(req.GetOldRevision())) { + // Passing an all-zeroes object ID indicates that we should only update the + // reference if it didn't previously exist. + oldObjectID = git.ObjectHashSHA1.ZeroOID + } else { + var err error + oldObjectID, err = repo.ResolveRevision(ctx, git.Revision(req.GetOldRevision())+"^{object}") + if err != nil { + return fmt.Errorf("resolving old revision: %w", err) + } + } + } + u, err := updateref.New(ctx, repo) if err != nil { return fmt.Errorf("error when running creating new updater: %v", err) } - if err = u.Update(git.ReferenceName(req.GetRef()), string(req.GetRevision()), string(req.GetOldRevision())); err != nil { + + if err = u.Update(git.ReferenceName(req.GetRef()), newObjectID, oldObjectID); err != nil { return fmt.Errorf("error when creating update-ref command: %v", err) } + if err = u.Commit(); err != nil { return fmt.Errorf("error when running update-ref command: %v", err) } + return nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref_test.go new file mode 100644 index 0000000000..4434bf0f68 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository/write_ref_test.go @@ -0,0 +1,247 @@ +//go:build !gitaly_test_sha256 + +package repository + +import ( + "bytes" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/codes" +) + +func TestWriteRef_successful(t *testing.T) { + t.Parallel() + + txManager := transaction.NewTrackingManager() + cfg, repo, repoPath, client := setupRepositoryService(testhelper.Context(t), t, testserver.WithTransactionManager(txManager)) + + testCases := []struct { + desc string + req *gitalypb.WriteRefRequest + expectedVotes int + }{ + { + desc: "shell update HEAD to refs/heads/master", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("HEAD"), + Revision: []byte("refs/heads/master"), + }, + expectedVotes: 2, + }, + { + desc: "shell update refs/heads/master", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/master"), + Revision: []byte("b83d6e391c22777fca1ed3012fce84f633d7fed0"), + }, + expectedVotes: 2, + }, + { + desc: "shell update refs/heads/master w/ validation", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/master"), + Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), + OldRevision: []byte("b83d6e391c22777fca1ed3012fce84f633d7fed0"), + }, + expectedVotes: 2, + }, + { + desc: "race-free creation of reference", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/branch"), + Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), + OldRevision: []byte("0000000000000000000000000000000000000000"), + }, + expectedVotes: 2, + }, + { + desc: "race-free delete of reference", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/branch"), + Revision: []byte("0000000000000000000000000000000000000000"), + OldRevision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), + }, + expectedVotes: 2, + }, + } + + ctx, err := txinfo.InjectTransaction(testhelper.Context(t), 1, "node", true) + require.NoError(t, err) + ctx = metadata.IncomingToOutgoing(ctx) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + txManager.Reset() + _, err = client.WriteRef(ctx, tc.req) + require.NoError(t, err) + + require.Len(t, txManager.Votes(), tc.expectedVotes) + + if bytes.Equal(tc.req.Ref, []byte("HEAD")) { + content := testhelper.MustReadFile(t, filepath.Join(repoPath, "HEAD")) + + refRevision := bytes.Join([][]byte{[]byte("ref: "), tc.req.Revision, []byte("\n")}, nil) + + require.EqualValues(t, refRevision, content) + return + } + + revParseCmd := gittest.NewCommand(t, cfg, "-C", repoPath, "rev-parse", "--verify", string(tc.req.Ref)) + output, err := revParseCmd.CombinedOutput() + + if git.ObjectHashSHA1.IsZeroOID(git.ObjectID(tc.req.GetRevision())) { + // If the new OID is the all-zeroes object ID then it indicates we + // should delete the branch. It's thus expected to get an error when + // we try to resolve the reference here given that it should not + // exist anymore. + require.Error(t, err) + require.Equal(t, "fatal: Needed a single revision\n", string(output)) + } else { + require.NoError(t, err) + require.Equal(t, string(tc.req.Revision), text.ChompBytes(output)) + } + }) + } +} + +func TestWriteRef_validation(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + _, repo, _, client := setupRepositoryService(ctx, t) + + testCases := []struct { + desc string + req *gitalypb.WriteRefRequest + }{ + { + desc: "empty revision", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/master"), + }, + }, + { + desc: "empty ref name", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), + }, + }, + { + desc: "non-prefixed ref name for shell", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("master"), + Revision: []byte("498214de67004b1da3d820901307bed2a68a8ef6"), + }, + }, + { + desc: "revision contains \\x00", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/master"), + Revision: []byte("012301230123\x001243"), + }, + }, + { + desc: "ref contains \\x00", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/head\x00s/master\x00"), + Revision: []byte("0123012301231243"), + }, + }, + { + desc: "ref contains whitespace", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads /master"), + Revision: []byte("0123012301231243"), + }, + }, + { + desc: "invalid revision", + req: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/master"), + Revision: []byte("--output=/meow"), + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := client.WriteRef(ctx, tc.req) + + testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) + }) + } +} + +func TestWriteRef_missingRevisions(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, client := setupRepositoryServiceWithoutRepo(t) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + commitID := gittest.WriteCommit(t, cfg, repoPath) + + for _, tc := range []struct { + desc string + request *gitalypb.WriteRefRequest + expectedErr error + }{ + { + desc: "revision refers to missing reference", + request: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/main"), + Revision: []byte("refs/heads/missing"), + }, + expectedErr: helper.ErrInternalf("resolving new revision: reference not found"), + }, + { + desc: "revision refers to missing object", + request: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/main"), + Revision: bytes.Repeat([]byte("1"), gittest.DefaultObjectHash.EncodedLen()), + }, + expectedErr: helper.ErrInternalf("resolving new revision: reference not found"), + }, + { + desc: "old revision refers to missing reference", + request: &gitalypb.WriteRefRequest{ + Repository: repo, + Ref: []byte("refs/heads/main"), + Revision: []byte(commitID), + OldRevision: bytes.Repeat([]byte("1"), gittest.DefaultObjectHash.EncodedLen()), + }, + expectedErr: helper.ErrInternalf("resolving old revision: reference not found"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + _, err := client.WriteRef(ctx, tc.request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/clocksynced.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/clocksynced.go new file mode 100644 index 0000000000..d3c64fa025 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/clocksynced.go @@ -0,0 +1,20 @@ +package server + +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// ClockSynced returns whether the system clock has an acceptable time drift when compared to NTP service. +func (s *server) ClockSynced(_ context.Context, req *gitalypb.ClockSyncedRequest) (*gitalypb.ClockSyncedResponse, error) { + if err := req.DriftThreshold.CheckValid(); err != nil { + return nil, helper.ErrInvalidArgument(err) + } + synced, err := helper.CheckClockSync(req.NtpHost, req.DriftThreshold.AsDuration()) + if err != nil { + return nil, err + } + return &gitalypb.ClockSyncedResponse{Synced: synced}, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats.go index e2c7025e2a..f24c627acc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats.go @@ -4,7 +4,7 @@ import ( "context" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) DiskStatistics(ctx context.Context, _ *gitalypb.DiskStatisticsRequest) (*gitalypb.DiskStatisticsResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats_test.go index f422ad665b..f0e5f34f4e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/disk_stats_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/disk_stats_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package server import ( @@ -5,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sys/unix" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info.go index 1a9d9127a0..91edb6457d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info.go @@ -6,11 +6,11 @@ import ( "path/filepath" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) ServerInfo(ctx context.Context, in *gitalypb.ServerInfoRequest) (*gitalypb.ServerInfoResponse, error) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info_test.go index 840614dd73..8f31fdb259 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/info_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/info_test.go @@ -1,22 +1,25 @@ +//go:build !gitaly_test_sha256 + package server import ( "testing" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" ) func TestGitalyServerInfo(t *testing.T) { @@ -65,7 +68,7 @@ func TestServerNoAuth(t *testing.T) { addr := runServer(t, cfg) - conn, err := grpc.Dial(addr, grpc.WithInsecure()) + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { testhelper.MustClose(t, conn) }) ctx := testhelper.Context(t) @@ -78,7 +81,7 @@ func TestServerNoAuth(t *testing.T) { func newServerClient(t *testing.T, serverSocketPath string) gitalypb.ServerServiceClient { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(testhelper.RepositoryAuthToken)), } conn, err := grpc.Dial(serverSocketPath, connOpts...) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/readiness.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/readiness.go new file mode 100644 index 0000000000..59708e2ed9 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/readiness.go @@ -0,0 +1,13 @@ +package server + +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// ReadinessCheck is a stub that does nothing but exists to support single interface for gitaly +// and praefect. The praefect service requires this method. +func (s *server) ReadinessCheck(context.Context, *gitalypb.ReadinessCheckRequest) (*gitalypb.ReadinessCheckResponse, error) { + return &gitalypb.ReadinessCheckResponse{Result: &gitalypb.ReadinessCheckResponse_OkResponse{}}, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server.go index 2d4f8acff1..f2cad1ceb5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server.go @@ -1,9 +1,9 @@ package server import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server_test.go index b2570c260c..d7e3b9c3ec 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/server_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/server_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package server import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_openbsd.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_openbsd.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_openbsd.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_openbsd.go index 8d15d42e0b..0b0050c0d8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_openbsd.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_openbsd.go @@ -1,8 +1,8 @@ package server import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sys/unix" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_unix.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_unix.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_unix.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_unix.go index 22dbd1457c..aae1836bdb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server/storage_status_unix.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server/storage_status_unix.go @@ -1,11 +1,10 @@ //go:build !openbsd -// +build !openbsd package server import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sys/unix" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup/register.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup/register.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup/register.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup/register.go index 32746ce4a6..a3ddffb026 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup/register.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup/register.go @@ -4,25 +4,25 @@ import ( grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/blob" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/cleanup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/conflicts" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/diff" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/internalgitaly" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/namespace" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/operations" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/remote" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/blob" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/cleanup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/commit" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/conflicts" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/diff" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/internalgitaly" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/namespace" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/operations" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/remote" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" @@ -144,6 +144,7 @@ func RegisterAll(srv *grpc.Server, deps *service.Dependencies) { deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), + deps.GetPackObjectsConcurrencyTracker(), )) gitalypb.RegisterInternalGitalyServer(srv, internalgitaly.NewServer(deps.GetCfg().Storages)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/cache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/cache.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/cache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/cache.go index 5531d02368..a60b169598 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/cache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/cache.go @@ -9,8 +9,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs.go index d2bc80391b..9a48d26e6a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs.go @@ -7,10 +7,10 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs_test.go similarity index 60% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs_test.go index 4c95547a52..cc72902ef4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/inforefs_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/inforefs_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package smarthttp import ( @@ -12,48 +14,122 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" ) -func TestSuccessfulInfoRefsUploadPack(t *testing.T) { +func TestInfoRefsUploadPack_successful(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) - cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) + tagID := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", }) rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} response, err := makeInfoRefsUploadPackRequest(ctx, t, cfg.SocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) - assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), "001e# service=git-upload-pack", "0000", []string{ - "003ef4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0", - "00416f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 refs/tags/v1.0.0^{}", + requireAdvertisedRefs(t, string(response), "git-upload-pack", []string{ + commitID.String() + " HEAD", + commitID.String() + " refs/heads/main\n", + tagID.String() + " refs/tags/v1.0.0\n", + commitID.String() + " refs/tags/v1.0.0^{}\n", }) } +func TestInfoRefsUploadPack_internalRefs(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + cfg.SocketPath = runSmartHTTPServer(t, cfg) + ctx := testhelper.Context(t) + + for _, tc := range []struct { + ref string + expectedAdvertisements []string + }{ + { + ref: "refs/merge-requests/1/head", + expectedAdvertisements: []string{ + "HEAD", + "refs/heads/main\n", + "refs/merge-requests/1/head\n", + }, + }, + { + ref: "refs/environments/1", + expectedAdvertisements: []string{ + "HEAD", + "refs/environments/1\n", + "refs/heads/main\n", + }, + }, + { + ref: "refs/pipelines/1", + expectedAdvertisements: []string{ + "HEAD", + "refs/heads/main\n", + "refs/pipelines/1\n", + }, + }, + { + ref: "refs/tmp/1", + expectedAdvertisements: []string{ + "HEAD", + "refs/heads/main\n", + }, + }, + { + ref: "refs/keep-around/1", + expectedAdvertisements: []string{ + "HEAD", + "refs/heads/main\n", + }, + }, + } { + t.Run(tc.ref, func(t *testing.T) { + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) + gittest.Exec(t, cfg, "-C", repoPath, "update-ref", tc.ref, commitID.String()) + + var expectedAdvertisements []string + for _, expectedRef := range tc.expectedAdvertisements { + expectedAdvertisements = append(expectedAdvertisements, commitID.String()+" "+expectedRef) + } + + response, err := makeInfoRefsUploadPackRequest(ctx, t, cfg.SocketPath, cfg.Auth.Token, &gitalypb.InfoRefsRequest{ + Repository: repo, + }) + require.NoError(t, err) + requireAdvertisedRefs(t, string(response), "git-upload-pack", expectedAdvertisements) + }) + } +} + func TestInfoRefsUploadPack_repositoryDoesntExist(t *testing.T) { t.Parallel() @@ -77,7 +153,7 @@ func TestInfoRefsUploadPack_repositoryDoesntExist(t *testing.T) { testhelper.RequireGrpcError(t, expectedErr, err) } -func TestSuccessfulInfoRefsUploadWithPartialClone(t *testing.T) { +func TestInfoRefsUploadPack_partialClone(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -104,16 +180,16 @@ func TestSuccessfulInfoRefsUploadWithPartialClone(t *testing.T) { } } -func TestSuccessfulInfoRefsUploadPackWithGitConfigOptions(t *testing.T) { +func TestInfoRefsUploadPack_gitConfigOptions(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) ctx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) // transfer.hideRefs=refs will hide every ref that info-refs would normally // output, allowing us to test that the custom configuration is respected @@ -123,19 +199,21 @@ func TestSuccessfulInfoRefsUploadPackWithGitConfigOptions(t *testing.T) { } response, err := makeInfoRefsUploadPackRequest(ctx, t, cfg.SocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) - assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), "001e# service=git-upload-pack", "0000", []string{}) + requireAdvertisedRefs(t, string(response), "git-upload-pack", []string{ + commitID.String() + " HEAD", + }) } -func TestSuccessfulInfoRefsUploadPackWithGitProtocol(t *testing.T) { +func TestInfoRefsUploadPack_gitProtocol(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) ctx := testhelper.Context(t) - gitCmdFactory, readProtocol := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ - testserver.WithGitCommandFactory(gitCmdFactory), + testserver.WithGitCommandFactory(protocolDetectingFactory), }) cfg.SocketPath = server.Address() @@ -161,7 +239,7 @@ func TestSuccessfulInfoRefsUploadPackWithGitProtocol(t *testing.T) { } } - envData := readProtocol() + envData := protocolDetectingFactory.ReadProtocol(t) require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) } @@ -184,30 +262,32 @@ func makeInfoRefsUploadPackRequest(ctx context.Context, t *testing.T, serverSock return response, err } -func TestSuccessfulInfoRefsReceivePack(t *testing.T) { +func TestInfoRefsReceivePack_successful(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) - cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) + tagID := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", }) - rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} - - response, err := makeInfoRefsReceivePackRequest(ctx, t, cfg.SocketPath, cfg.Auth.Token, rpcRequest) + response, err := makeInfoRefsReceivePackRequest(ctx, t, cfg.SocketPath, cfg.Auth.Token, &gitalypb.InfoRefsRequest{ + Repository: repo, + }) require.NoError(t, err) - assertGitRefAdvertisement(t, "InfoRefsReceivePack", string(response), "001f# service=git-receive-pack", "0000", []string{ - "003ef4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0", - "003e8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b refs/tags/v1.1.0", + requireAdvertisedRefs(t, string(response), "git-receive-pack", []string{ + commitID.String() + " refs/heads/main", + tagID.String() + " refs/tags/v1.0.0\n", }) } -func TestObjectPoolRefAdvertisementHiding(t *testing.T) { +func TestInfoRefsReceivePack_hiddenRefs(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -250,7 +330,7 @@ func TestObjectPoolRefAdvertisementHiding(t *testing.T) { require.NotContains(t, string(response), commitID+" .have") } -func TestFailureRepoNotFoundInfoRefsReceivePack(t *testing.T) { +func TestInfoRefsReceivePack_repoNotFound(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -270,7 +350,7 @@ func TestFailureRepoNotFoundInfoRefsReceivePack(t *testing.T) { testhelper.RequireGrpcError(t, expectedErr, err) } -func TestFailureRepoNotSetInfoRefsReceivePack(t *testing.T) { +func TestInfoRefsReceivePack_repoNotSet(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -302,23 +382,28 @@ func makeInfoRefsReceivePackRequest(ctx context.Context, t *testing.T, serverSoc return response, err } -func assertGitRefAdvertisement(t *testing.T, rpc, responseBody string, firstLine, lastLine string, middleLines []string) { - responseLines := strings.Split(responseBody, "\n") +func requireAdvertisedRefs(t *testing.T, responseBody, expectedService string, expectedRefs []string) { + t.Helper() - if responseLines[0] != firstLine { - t.Errorf("%q: expected response first line to be %q, found %q", rpc, firstLine, responseLines[0]) + responseLines := strings.SplitAfter(responseBody, "\n") + require.Greater(t, len(responseLines), 2) + + for i, expectedRef := range expectedRefs { + expectedRefs[i] = gittest.Pktlinef(t, "%s", expectedRef) } - lastIndex := len(responseLines) - 1 - if responseLines[lastIndex] != lastLine { - t.Errorf("%q: expected response last line to be %q, found %q", rpc, lastLine, responseLines[lastIndex]) - } + // The first line contains the service announcement. + require.Equal(t, gittest.Pktlinef(t, "# service=%s\n", expectedService), responseLines[0]) - for _, ref := range middleLines { - if !strings.Contains(responseBody, ref) { - t.Errorf("%q: expected response to contain %q, found none", rpc, ref) - } - } + // The second line contains the first reference as well as the capability announcement. We + // thus split the string at "\x00" and ignore the capability announcement here. + refAndCapabilities := strings.SplitN(responseLines[1], "\x00", 2) + require.Len(t, refAndCapabilities, 2) + // We just replace the first advertised reference to make it easier to compare refs. + responseLines[1] = gittest.Pktlinef(t, "%s", refAndCapabilities[0][8:]) + + require.Equal(t, responseLines[1:len(responseLines)-1], expectedRefs) + require.Equal(t, "0000", responseLines[len(responseLines)-1]) } type mockStreamer struct { @@ -333,7 +418,7 @@ func (ms *mockStreamer) PutStream(ctx context.Context, repo *gitalypb.Repository return ms.Streamer.PutStream(ctx, repo, req, src) } -func TestCacheInfoRefsUploadPack(t *testing.T) { +func TestInfoRefsUploadPack_cache(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -350,17 +435,21 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { cfg.SocketPath = gitalyServer.Address() ctx := testhelper.Context(t) - repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) + tagID := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated tag", }) rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} // The key computed for the cache entry takes into account all feature flags. Because - // Praefect explicitly injects all unset feature flags, the key is thus differend depending + // Praefect explicitly injects all unset feature flags, the key is thus different depending // on whether Praefect is in use or not. We thus manually inject all feature flags here such // that they're forced to the same state. - for _, ff := range featureflag.All { + for _, ff := range featureflag.DefinedFlags() { ctx = featureflag.OutgoingCtxWithFeatureFlag(ctx, ff, true) ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, ff, true) } @@ -369,13 +458,12 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { response, err := makeInfoRefsUploadPackRequest(ctx, t, addr, cfg.Auth.Token, rpcRequest) require.NoError(t, err) - assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), - "001e# service=git-upload-pack", "0000", - []string{ - "003ef4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0", - "00416f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 refs/tags/v1.0.0^{}", - }, - ) + requireAdvertisedRefs(t, string(response), "git-upload-pack", []string{ + commitID.String() + " HEAD", + commitID.String() + " refs/heads/main\n", + tagID.String() + " refs/tags/v1.0.0\n", + commitID.String() + " refs/tags/v1.0.0^{}\n", + }) } assertNormalResponse(gitalyServer.Address()) @@ -393,9 +481,7 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { replaceCachedResponse(t, ctx, cache, rewrittenRequest, strings.Join(replacedContents, "\n")) response, err := makeInfoRefsUploadPackRequest(ctx, t, gitalyServer.Address(), cfg.Auth.Token, rpcRequest) require.NoError(t, err) - assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), - replacedContents[0], replacedContents[3], replacedContents[1:3], - ) + require.Equal(t, strings.Join(replacedContents, "\n"), string(response)) invalidateCacheForRepo := func() { ender, err := cache.StartLease(rewrittenRequest.Repository) @@ -441,25 +527,25 @@ func withInfoRefCache(cache infoRefCache) ServerOpt { } } -func createInvalidRepo(t testing.TB, repoDir string) func() { +func createInvalidRepo(tb testing.TB, repoDir string) func() { for _, subDir := range []string{"objects", "refs", "HEAD"} { - require.NoError(t, os.MkdirAll(filepath.Join(repoDir, subDir), 0o755)) + require.NoError(tb, os.MkdirAll(filepath.Join(repoDir, subDir), 0o755)) } - return func() { require.NoError(t, os.RemoveAll(repoDir)) } + return func() { require.NoError(tb, os.RemoveAll(repoDir)) } } -func replaceCachedResponse(t testing.TB, ctx context.Context, cache *cache.DiskCache, req *gitalypb.InfoRefsRequest, newContents string) { - path := pathToCachedResponse(t, ctx, cache, req) - require.NoError(t, os.WriteFile(path, []byte(newContents), 0o644)) +func replaceCachedResponse(tb testing.TB, ctx context.Context, cache *cache.DiskCache, req *gitalypb.InfoRefsRequest, newContents string) { + path := pathToCachedResponse(tb, ctx, cache, req) + require.NoError(tb, os.WriteFile(path, []byte(newContents), 0o644)) } func setInfoRefsUploadPackMethod(ctx context.Context) context.Context { return testhelper.SetCtxGrpcMethod(ctx, "/gitaly.SmartHTTPService/InfoRefsUploadPack") } -func pathToCachedResponse(t testing.TB, ctx context.Context, cache *cache.DiskCache, req *gitalypb.InfoRefsRequest) string { +func pathToCachedResponse(tb testing.TB, ctx context.Context, cache *cache.DiskCache, req *gitalypb.InfoRefsRequest) string { ctx = setInfoRefsUploadPackMethod(ctx) path, err := cache.KeyPath(ctx, req.GetRepository(), req) - require.NoError(t, err) + require.NoError(tb, err) return path } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack.go index 1653594bcb..323b6742cc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack.go @@ -5,12 +5,12 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack_test.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack_test.go index e7349ac809..b78ef44671 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/receive_pack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/receive_pack_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package smarthttp import ( @@ -6,42 +8,41 @@ import ( "errors" "fmt" "io" - "os" "path/filepath" "strings" "testing" - "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - gitalyhook "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + gitalyhook "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" - "google.golang.org/grpc/codes" ) const ( uploadPackCapabilities = "report-status side-band-64k agent=git/2.12.0" ) -func TestSuccessfulReceivePackRequest(t *testing.T) { +func TestPostReceivePack_successful(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) cfg.GitlabShell.Dir = "/foo/bar/gitlab-shell" gitCmdFactory, hookOutputFile := gittest.CaptureHookEnv(t, cfg) @@ -51,10 +52,10 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { }) cfg.SocketPath = server.Address() - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) + repo.GlProjectPath = "project/path" client, conn := newSmartHTTPClient(t, server.Address(), cfg.Auth.Token) defer conn.Close() @@ -67,7 +68,7 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { // the context's feature flags we see here and the context's metadata as it would // arrive on the proxied Gitaly. To fix this, we thus inject all feature flags // explicitly here. - for _, ff := range featureflag.All { + for _, ff := range featureflag.DefinedFlags() { ctx = featureflag.OutgoingCtxWithFeatureFlag(ctx, ff, true) ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, ff, true) } @@ -75,19 +76,21 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, cfg, nil) + _, newCommitID, request := createPushRequest(t, cfg) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlUsername: "user", + GlId: "123", + GlRepository: "project-456", + }, request) - projectPath := "project/path" + requireSideband(t, []string{ + "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n0000", + }, response) - repo.GlProjectPath = projectPath - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlUsername: "user", GlId: "123", GlRepository: "project-456"} - response := doPush(t, stream, firstRequest, push.body) - - expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) - - // The fact that this command succeeds means that we got the commit correctly, no further checks should be needed. - gittest.Exec(t, cfg, "-C", repoPath, "show", push.newHead) + // The fact that this command succeeds means that we got the commit correctly, no further + // checks should be needed. + gittest.Exec(t, cfg, "-C", repoPath, "show", newCommitID.String()) envData := testhelper.MustReadFile(t, hookOutputFile) payload, err := git.HooksPayloadFromEnv(strings.Split(string(envData), "\n")) @@ -102,27 +105,39 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { // figuring out their actual contents. So let's just remove it, too. payload.Transaction = nil + var expectedFeatureFlags []git.FeatureFlagWithValue + for feature, enabled := range featureflag.FromContext(ctx) { + expectedFeatureFlags = append(expectedFeatureFlags, git.FeatureFlagWithValue{ + Flag: feature, Enabled: enabled, + }) + } + + // Compare here without paying attention to the order given that flags aren't sorted and + // unset the struct member afterwards. + require.ElementsMatch(t, expectedFeatureFlags, payload.FeatureFlagsWithValue) + payload.FeatureFlagsWithValue = nil + require.Equal(t, git.HooksPayload{ RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, - ReceiveHooksPayload: &git.ReceiveHooksPayload{ + UserDetails: &git.UserDetails{ UserID: "123", Username: "user", Protocol: "http", }, RequestedHooks: git.ReceivePackHooks, - FeatureFlags: featureflag.RawFromContext(ctx), }, payload) } -func TestReceivePackHiddenRefs(t *testing.T) { +func TestPostReceivePack_hiddenRefs(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -146,44 +161,44 @@ func TestReceivePackHiddenRefs(t *testing.T) { "refs/pipelines/1", } { t.Run(ref, func(t *testing.T) { - request := &bytes.Buffer{} - gittest.WritePktlineString(t, request, fmt.Sprintf("%s %s %s\x00 %s", - oldHead, newHead, ref, uploadPackCapabilities)) - gittest.WritePktlineFlush(t, request) + var request bytes.Buffer + gittest.WritePktlinef(t, &request, "%s %s %s\x00 %s", oldHead, newHead, ref, uploadPackCapabilities) + gittest.WritePktlineFlush(t, &request) // The options passed are the same ones used when doing an actual push. revisions := strings.NewReader(fmt.Sprintf("^%s\n%s\n", oldHead, newHead)) - pack := gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: revisions}, + gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: revisions, Stdout: &request}, "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q", ) - request.Write(pack) stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - response := doPush(t, stream, &gitalypb.PostReceivePackRequest{ - Repository: repoProto, GlUsername: "user", GlId: "123", GlRepository: "project-456", - }, request) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repoProto, + GlUsername: "user", + GlId: "123", + GlRepository: "project-456", + }, &request) - require.Contains(t, string(response), fmt.Sprintf("%s deny updating a hidden ref", ref)) + require.Contains(t, response, fmt.Sprintf("%s deny updating a hidden ref", ref)) }) } } -func TestSuccessfulReceivePackRequestWithGitProtocol(t *testing.T) { +func TestPostReceivePack_protocolV2(t *testing.T) { t.Parallel() - cfg := testcfg.Build(t) - - testcfg.BuildGitalyHooks(t, cfg) ctx := testhelper.Context(t) - gitCmdFactory, readProto := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + cfg := testcfg.Build(t) + testcfg.BuildGitalyHooks(t, cfg) + + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ - testserver.WithGitCommandFactory(gitCmdFactory), + testserver.WithGitCommandFactory(protocolDetectingFactory), }) - cfg.SocketPath = server.Address() repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ @@ -196,25 +211,86 @@ func TestSuccessfulReceivePackRequestWithGitProtocol(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, cfg, nil) - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123", GitProtocol: git.ProtocolV2} - doPush(t, stream, firstRequest, push.body) + _, newCommitID, request := createPushRequest(t, cfg) + performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "user-123", + GlRepository: "project-123", + GitProtocol: git.ProtocolV2, + }, request) - envData := readProto() + envData := protocolDetectingFactory.ReadProtocol(t) require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) // The fact that this command succeeds means that we got the commit correctly, no further checks should be needed. - gittest.Exec(t, cfg, "-C", repoPath, "show", push.newHead) + gittest.Exec(t, cfg, "-C", repoPath, "show", newCommitID.String()) } -func TestFailedReceivePackRequestWithGitOpts(t *testing.T) { +func TestPostReceivePack_packfiles(t *testing.T) { t.Parallel() - cfg := testcfg.Build(t) + ctx := testhelper.Context(t) - cfg.SocketPath = runSmartHTTPServer(t, cfg) + cfg := testcfg.Build(t) + cfg.SocketPath = startSmartHTTPServer(t, cfg).Address() + testcfg.BuildGitalyHooks(t, cfg) + + client, conn := newSmartHTTPClient(t, cfg.SocketPath, cfg.Auth.Token) + defer conn.Close() + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + stream, err := client.PostReceivePack(ctx) + require.NoError(t, err) + + // Verify the before-state of the repository. It should have a single packfile, ... + packfiles, err := filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.pack")) + require.NoError(t, err) + require.Len(t, packfiles, 1) + + // ... but no reverse index. `gittest.CreateRepository()` uses `CreateRepositoryFromURL()` + // with a file path that doesn't use `file://` as prefix. As a result, Git uses the local + // transport and just copies objects over without generating a reverse index. This is thus + // expected as we don't want to perform a "real" clone, which would be a lot more expensive. + reverseIndices, err := filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.rev")) + require.NoError(t, err) + require.Empty(t, reverseIndices) + + _, _, request := createPushRequest(t, cfg) + performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "user-123", + GlRepository: "project-123", + GitProtocol: git.ProtocolV2, + // By default, Git would unpack the received packfile if it has less than + // 100 objects. Decrease this limit so that we indeed end up with another + // new packfile even though we only push a small set of objects. + GitConfigOptions: []string{ + "receive.unpackLimit=0", + }, + }, request) + + // We now should have two packfiles, ... + packfiles, err = filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.pack")) + require.NoError(t, err) + require.Len(t, packfiles, 2) + + // ... and one reverse index for the newly added packfile. + reverseIndices, err = filepath.Glob(filepath.Join(repoPath, "objects", "pack", "*.rev")) + require.NoError(t, err) + require.Len(t, reverseIndices, 1) +} + +func TestPostReceivePack_rejectViaGitConfigOptions(t *testing.T) { + t.Parallel() ctx := testhelper.Context(t) + + cfg := testcfg.Build(t) + cfg.SocketPath = runSmartHTTPServer(t, cfg) + repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -225,23 +301,29 @@ func TestFailedReceivePackRequestWithGitOpts(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, cfg, nil) - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123", GitConfigOptions: []string{"receive.MaxInputSize=1"}} - response := doPush(t, stream, firstRequest, push.body) + _, _, request := createPushRequest(t, cfg) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "user-123", + GlRepository: "project-123", + GitConfigOptions: []string{"receive.MaxInputSize=1"}, + }, request) - expectedResponse := "002e\x02fatal: pack exceeds maximum allowed size\n0081\x010028unpack unpack-objects abnormal exit\n0028ng refs/heads/master unpacker error\n0028ng refs/heads/branch unpacker error\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "002e\x02fatal: pack exceeds maximum allowed size\n", + "0081\x010028unpack unpack-objects abnormal exit\n0028ng refs/heads/master unpacker error\n0028ng refs/heads/branch unpacker error\n0000", + }, response) } -func TestFailedReceivePackRequestDueToHooksFailure(t *testing.T) { +func TestPostReceivePack_rejectViaHooks(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) gitCmdFactory := gittest.NewCommandFactory(t, cfg, git.WithHooksPath(testhelper.TempDir(t))) - ctx := testhelper.Context(t) - hookContent := []byte("#!/bin/sh\nexit 1") - require.NoError(t, os.WriteFile(filepath.Join(gitCmdFactory.HooksPath(ctx), "pre-receive"), hookContent, 0o755)) + testhelper.WriteExecutable(t, filepath.Join(gitCmdFactory.HooksPath(ctx), "pre-receive"), []byte("#!/bin/sh\nexit 1")) server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ testserver.WithGitCommandFactory(gitCmdFactory), @@ -258,102 +340,19 @@ func TestFailedReceivePackRequestDueToHooksFailure(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, cfg, nil) - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123"} - response := doPush(t, stream, firstRequest, push.body) + _, _, request := createPushRequest(t, cfg) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "user-123", + GlRepository: "project-123", + }, request) - expectedResponse := "007d\x01000eunpack ok\n0033ng refs/heads/master pre-receive hook declined\n0033ng refs/heads/branch pre-receive hook declined\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "007d\x01000eunpack ok\n0033ng refs/heads/master pre-receive hook declined\n0033ng refs/heads/branch pre-receive hook declined\n0000", + }, response) } -func doPush(t *testing.T, stream gitalypb.SmartHTTPService_PostReceivePackClient, firstRequest *gitalypb.PostReceivePackRequest, body io.Reader) []byte { - require.NoError(t, stream.Send(firstRequest)) - - sw := streamio.NewWriter(func(p []byte) error { - return stream.Send(&gitalypb.PostReceivePackRequest{Data: p}) - }) - _, err := io.Copy(sw, body) - require.NoError(t, err) - - require.NoError(t, stream.CloseSend()) - - responseBuffer := bytes.Buffer{} - rr := streamio.NewReader(func() ([]byte, error) { - resp, err := stream.Recv() - return resp.GetData(), err - }) - _, err = io.Copy(&responseBuffer, rr) - require.NoError(t, err) - - return responseBuffer.Bytes() -} - -type pushData struct { - newHead string - body io.Reader -} - -func newTestPush(t *testing.T, cfg config.Cfg, fileContents []byte) *pushData { - _, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{ - WithWorktree: true, - }) - - oldHead, newHead := createCommit(t, cfg, repoPath, fileContents) - - // ReceivePack request is a packet line followed by a packet flush, then the pack file of the objects we want to push. - // This is explained a bit in https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#_uploading_data - // We form the packet line the same way git executable does: https://github.com/git/git/blob/d1a13d3fcb252631361a961cb5e2bf10ed467cba/send-pack.c#L524-L527 - requestBuffer := &bytes.Buffer{} - - pkt := fmt.Sprintf("%s %s refs/heads/master\x00 %s", oldHead, newHead, uploadPackCapabilities) - fmt.Fprintf(requestBuffer, "%04x%s", len(pkt)+4, pkt) - - pkt = fmt.Sprintf("%s %s refs/heads/branch", git.ZeroOID, newHead) - fmt.Fprintf(requestBuffer, "%04x%s", len(pkt)+4, pkt) - - fmt.Fprintf(requestBuffer, "%s", pktFlushStr) - - // We need to get a pack file containing the objects we want to push, so we use git pack-objects - // which expects a list of revisions passed through standard input. The list format means - // pack the objects needed if I have oldHead but not newHead (think of it from the perspective of the remote repo). - // For more info, check the man pages of both `git-pack-objects` and `git-rev-list --objects`. - stdin := strings.NewReader(fmt.Sprintf("^%s\n%s\n", oldHead, newHead)) - - // The options passed are the same ones used when doing an actual push. - pack := gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: stdin}, - "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q", - ) - requestBuffer.Write(pack) - - return &pushData{newHead: newHead, body: requestBuffer} -} - -// createCommit creates a commit on HEAD with a file containing the -// specified contents. -func createCommit(t *testing.T, cfg config.Cfg, repoPath string, fileContents []byte) (oldHead string, newHead string) { - commitMsg := fmt.Sprintf("Testing ReceivePack RPC around %d", time.Now().Unix()) - committerName := "Scrooge McDuck" - committerEmail := "scrooge@mcduck.com" - - // The latest commit ID on the remote repo - oldHead = text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "master")) - - changedFile := "README.md" - require.NoError(t, os.WriteFile(filepath.Join(repoPath, changedFile), fileContents, 0o644)) - - gittest.Exec(t, cfg, "-C", repoPath, "add", changedFile) - gittest.Exec(t, cfg, "-C", repoPath, - "-c", fmt.Sprintf("user.name=%s", committerName), - "-c", fmt.Sprintf("user.email=%s", committerEmail), - "commit", "-m", commitMsg) - - // The commit ID we want to push to the remote repo - newHead = text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "master")) - - return oldHead, newHead -} - -func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { +func TestPostReceivePack_requestValidation(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -364,9 +363,9 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { defer conn.Close() for _, tc := range []struct { - desc string - request *gitalypb.PostReceivePackRequest - code codes.Code + desc string + request *gitalypb.PostReceivePackRequest + expectedErr error }{ { desc: "Repository doesn't exist", @@ -377,12 +376,24 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { }, GlId: "user-123", }, - code: codes.InvalidArgument, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: invalid Repository") + } + + return helper.ErrInvalidArgumentf("GetStorageByName: no such storage: %q", "fake") + }(), }, { desc: "Repository is nil", request: &gitalypb.PostReceivePackRequest{Repository: nil, GlId: "user-123"}, - code: codes.InvalidArgument, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: empty Repository") + } + + return helper.ErrInvalidArgumentf("PostReceivePack: empty Repository") + }(), }, { desc: "Empty GlId", @@ -393,12 +404,12 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { }, GlId: "", }, - code: func() codes.Code { + expectedErr: func() error { if testhelper.IsPraefectEnabled() { - return codes.NotFound + return helper.ErrNotFoundf("mutator call: route repository mutator: get repository id: repository %q/%q not found", cfg.Storages[0].Name, "path/to/repo") } - return codes.InvalidArgument + return helper.ErrInvalidArgumentf("PostReceivePack: empty GlId") }(), }, { @@ -411,12 +422,12 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { GlId: "user-123", Data: []byte("Fail"), }, - code: func() codes.Code { + expectedErr: func() error { if testhelper.IsPraefectEnabled() { - return codes.NotFound + return helper.ErrNotFoundf("mutator call: route repository mutator: get repository id: repository %q/%q not found", cfg.Storages[0].Name, "path/to/repo") } - return codes.InvalidArgument + return helper.ErrInvalidArgumentf("PostReceivePack: non-empty Data") }(), }, } { @@ -429,7 +440,7 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { require.NoError(t, stream.CloseSend()) err = drainPostReceivePackResponse(stream) - testhelper.RequireGrpcCode(t, err, tc.code) + testhelper.RequireGrpcError(t, tc.expectedErr, err) }) } } @@ -437,6 +448,8 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { func TestPostReceivePack_invalidObjects(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) gitCmdFactory, _ := gittest.CaptureHookEnv(t, cfg) @@ -445,7 +458,6 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { }) cfg.SocketPath = server.Address() - ctx := testhelper.Context(t) repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -464,7 +476,7 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { for _, tc := range []struct { desc string prepareCommit func(t *testing.T, repoPath string) bytes.Buffer - expectedResponse string + expectedSideband []string expectObject bool }{ { @@ -479,8 +491,10 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { buf.WriteString("Commit message\n") return buf }, - expectedResponse: "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000", - expectObject: true, + expectedSideband: []string{ + "0030\x01000eunpack ok\n0019ok refs/heads/master\n0000", + }, + expectObject: true, }, { desc: "missing author and committer date", @@ -494,8 +508,10 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { buf.WriteString("Commit message\n") return buf }, - expectedResponse: "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000", - expectObject: true, + expectedSideband: []string{ + "0030\x01000eunpack ok\n0019ok refs/heads/master\n0000", + }, + expectObject: true, }, { desc: "zero-padded file mode", @@ -523,8 +539,10 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { buf.WriteString("Commit message\n") return buf }, - expectedResponse: "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000", - expectObject: true, + expectedSideband: []string{ + "0030\x01000eunpack ok\n0019ok refs/heads/master\n0000", + }, + expectObject: true, }, } { t.Run(tc.desc, func(t *testing.T) { @@ -547,14 +565,13 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - firstRequest := &gitalypb.PostReceivePackRequest{ + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ Repository: repoProto, GlId: "user-123", GlRepository: "project-456", - } - response := doPush(t, stream, firstRequest, body) + }, body) - require.Contains(t, string(response), tc.expectedResponse) + requireSideband(t, tc.expectedSideband, response) exists, err := repo.HasRevision(ctx, git.Revision(commitID+"^{commit}")) require.NoError(t, err) @@ -563,13 +580,14 @@ func TestPostReceivePack_invalidObjects(t *testing.T) { } } -func TestReceivePackFsck(t *testing.T) { +func TestPostReceivePack_fsck(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) @@ -587,16 +605,14 @@ func TestReceivePackFsck(t *testing.T) { ), ) - stdin := strings.NewReader(fmt.Sprintf("^%s\n%s\n", head, commit)) - pack := gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: stdin}, - "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q", - ) - var body bytes.Buffer gittest.WritePktlineString(t, &body, fmt.Sprintf("%s %s refs/heads/master\x00 %s", head, commit, "report-status side-band-64k agent=git/2.12.0")) gittest.WritePktlineFlush(t, &body) - _, err := body.Write(pack) - require.NoError(t, err) + + stdin := strings.NewReader(fmt.Sprintf("^%s\n%s\n", head, commit)) + gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: stdin, Stdout: &body}, + "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q", + ) client, conn := newSmartHTTPClient(t, cfg.SocketPath, cfg.Auth.Token) defer conn.Close() @@ -604,53 +620,46 @@ func TestReceivePackFsck(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - response := doPush(t, stream, &gitalypb.PostReceivePackRequest{ + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ Repository: repo, GlId: "user-123", GlRepository: "project-456", }, &body) - require.Contains(t, string(response), "duplicateEntries: contains duplicate file entries") + require.Contains(t, response, "duplicateEntries: contains duplicate file entries") } -func drainPostReceivePackResponse(stream gitalypb.SmartHTTPService_PostReceivePackClient) error { - var err error - for err == nil { - _, err = stream.Recv() - } - return err -} - -func TestPostReceivePackToHooks(t *testing.T) { +func TestPostReceivePack_hooks(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) - repo, testRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + testcfg.BuildGitalyHooks(t, cfg) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, }) - testcfg.BuildGitalyHooks(t, cfg) - const ( secretToken = "secret token" glRepository = "some_repo" glID = "key-123" ) - var cleanup func() cfg.GitlabShell.Dir = testhelper.TempDir(t) cfg.Auth.Token = "abc123" cfg.Gitlab.SecretFile = gitlab.WriteShellSecretFile(t, cfg.GitlabShell.Dir, secretToken) - push := newTestPush(t, cfg, nil) - oldHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", testRepoPath, "rev-parse", "HEAD")) + _, newCommitID, request := createPushRequest(t, cfg) + oldHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD")) - changes := fmt.Sprintf("%s %s refs/heads/master\n", oldHead, push.newHead) + changes := fmt.Sprintf("%s %s refs/heads/master\n", oldHead, newCommitID) + var cleanup func() cfg.Gitlab.URL, cleanup = gitlab.NewTestServer(t, gitlab.TestServerOptions{ User: "", Password: "", @@ -663,7 +672,7 @@ func TestPostReceivePackToHooks(t *testing.T) { }) defer cleanup() - gittest.WriteCheckNewObjectExistsHook(t, testRepoPath) + gittest.WriteCheckNewObjectExistsHook(t, repoPath) client, conn := newSmartHTTPClient(t, cfg.SocketPath, cfg.Auth.Token) defer conn.Close() @@ -671,21 +680,21 @@ func TestPostReceivePackToHooks(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - firstRequest := &gitalypb.PostReceivePackRequest{ + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ Repository: repo, GlId: glID, GlRepository: glRepository, - } + }, request) - response := doPush(t, stream, firstRequest, push.body) - - expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n0000", + }, response) require.Equal(t, io.EOF, drainPostReceivePackResponse(stream)) } -func TestPostReceiveWithTransactionsViaPraefect(t *testing.T) { +func TestPostReceivePack_transactionsViaPraefect(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) @@ -697,32 +706,25 @@ func TestPostReceiveWithTransactionsViaPraefect(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) - secretToken := "secret token" - glID := "key-1234" - glRepository := "some_repo" - gitlabUser := "gitlab_user-1234" - gitlabPassword := "gitlabsecret9887" - opts := gitlab.TestServerOptions{ - User: gitlabUser, - Password: gitlabPassword, - SecretToken: secretToken, - GLID: glID, - GLRepository: glRepository, + User: "gitlab_user-1234", + Password: "gitlabsecret9887", + SecretToken: "secret token", + GLID: "key-1234", + GLRepository: "some_repo", RepoPath: repoPath, } serverURL, cleanup := gitlab.NewTestServer(t, opts) defer cleanup() - gitlabShellDir := testhelper.TempDir(t) - cfg.GitlabShell.Dir = gitlabShellDir + cfg.GitlabShell.Dir = testhelper.TempDir(t) cfg.Gitlab.URL = serverURL - cfg.Gitlab.HTTPSettings.User = gitlabUser - cfg.Gitlab.HTTPSettings.Password = gitlabPassword - cfg.Gitlab.SecretFile = filepath.Join(gitlabShellDir, ".gitlab_shell_secret") + cfg.Gitlab.HTTPSettings.User = opts.User + cfg.Gitlab.HTTPSettings.Password = opts.Password + cfg.Gitlab.SecretFile = filepath.Join(cfg.GitlabShell.Dir, ".gitlab_shell_secret") - gitlab.WriteShellSecretFile(t, gitlabShellDir, secretToken) + gitlab.WriteShellSecretFile(t, cfg.GitlabShell.Dir, opts.SecretToken) client, conn := newSmartHTTPClient(t, cfg.SocketPath, cfg.Auth.Token) defer conn.Close() @@ -730,12 +732,16 @@ func TestPostReceiveWithTransactionsViaPraefect(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, cfg, nil) - request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: glID, GlRepository: glRepository} - response := doPush(t, stream, request, push.body) + _, _, pushRequest := createPushRequest(t, cfg) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: opts.GLID, + GlRepository: opts.GLRepository, + }, pushRequest) - expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n0000", + }, response) } type testTransactionServer struct { @@ -750,31 +756,26 @@ func (t *testTransactionServer) VoteTransaction(ctx context.Context, in *gitalyp }, nil } -func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { +func TestPostReceivePack_referenceTransactionHook(t *testing.T) { t.Parallel() - cfg := testcfg.Build(t) + ctxWithoutTransaction := testhelper.Context(t) + cfg := testcfg.Build(t) testcfg.BuildGitalyHooks(t, cfg) refTransactionServer := &testTransactionServer{} - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterSmartHTTPServiceServer(srv, NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - deps.GetDiskCache(), - )) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - }, testserver.WithDisablePraefect()) - ctx := testhelper.Context(t) + server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ + testserver.WithDisablePraefect(), + }) + cfg.SocketPath = server.Address() - ctx, err := txinfo.InjectTransaction(ctx, 1234, "primary", true) + ctx, err := txinfo.InjectTransaction(ctxWithoutTransaction, 1234, "primary", true) require.NoError(t, err) ctx = metadata.IncomingToOutgoing(ctx) - client := newMuxedSmartHTTPClient(t, ctx, addr, cfg.Auth.Token, func() backchannel.Server { + client := newMuxedSmartHTTPClient(t, ctx, server.Address(), cfg.Auth.Token, func() backchannel.Server { srv := grpc.NewServer() gitalypb.RegisterRefTransactionServer(srv, refTransactionServer) return srv @@ -784,13 +785,20 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, _ := gittest.CreateRepository(ctxWithoutTransaction, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) - request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "key-1234", GlRepository: "some_repo"} - response := doPush(t, stream, request, newTestPush(t, cfg, nil).body) + _, _, pushRequest := createPushRequest(t, cfg) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "key-1234", + GlRepository: "some_repo", + }, pushRequest) - expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n0000", + }, response) require.Equal(t, 5, refTransactionServer.called) }) @@ -800,7 +808,10 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, repoPath := gittest.CreateRepository(ctxWithoutTransaction, t, cfg, + gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) // Create a new branch which we're about to delete. We also pack references because // this used to generate two transactions: one for the packed-refs file and one for @@ -811,19 +822,23 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { branchOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/delete-me")) uploadPackData := &bytes.Buffer{} - gittest.WritePktlineString(t, uploadPackData, fmt.Sprintf("%s %s refs/heads/delete-me\x00 %s", branchOID, git.ZeroOID.String(), uploadPackCapabilities)) + gittest.WritePktlineString(t, uploadPackData, fmt.Sprintf("%s %s refs/heads/delete-me\x00 %s", branchOID, git.ObjectHashSHA1.ZeroOID.String(), uploadPackCapabilities)) gittest.WritePktlineFlush(t, uploadPackData) - request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "key-1234", GlRepository: "some_repo"} - response := doPush(t, stream, request, uploadPackData) + response := performPush(t, stream, &gitalypb.PostReceivePackRequest{ + Repository: repo, + GlId: "key-1234", + GlRepository: "some_repo", + }, uploadPackData) - expectedResponse := "0033\x01000eunpack ok\n001cok refs/heads/delete-me\n00000000" - require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + requireSideband(t, []string{ + "0033\x01000eunpack ok\n001cok refs/heads/delete-me\n0000", + }, response) require.Equal(t, 3, refTransactionServer.called) }) } -func TestPostReceive_allRejected(t *testing.T) { +func TestPostReceivePack_notAllowed(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -839,28 +854,26 @@ func TestPostReceive_allRejected(t *testing.T) { ctx context.Context, repo *gitalypb.Repository, pushOptions, env []string, - stdin io.Reader, stdout, stderr io.Writer) error { + stdin io.Reader, stdout, stderr io.Writer, + ) error { return errors.New("not allowed") }, gitalyhook.NopPostReceive, gitalyhook.NopUpdate, gitalyhook.NopReferenceTransaction, ) - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterSmartHTTPServiceServer(srv, NewServer( - deps.GetLocator(), - deps.GetGitCmdFactory(), - deps.GetTxManager(), - deps.GetDiskCache(), - )) - gitalypb.RegisterHookServiceServer(srv, hook.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) - }, testserver.WithDisablePraefect(), testserver.WithHookManager(hookManager)) - ctx, err := txinfo.InjectTransaction(testhelper.Context(t), 1234, "primary", true) + server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ + testserver.WithDisablePraefect(), testserver.WithHookManager(hookManager), + }) + cfg.SocketPath = server.Address() + + ctxWithoutTransaction := testhelper.Context(t) + ctx, err := txinfo.InjectTransaction(ctxWithoutTransaction, 1234, "primary", true) require.NoError(t, err) ctx = metadata.IncomingToOutgoing(ctx) - client := newMuxedSmartHTTPClient(t, ctx, addr, cfg.Auth.Token, func() backchannel.Server { + client := newMuxedSmartHTTPClient(t, ctx, server.Address(), cfg.Auth.Token, func() backchannel.Server { srv := grpc.NewServer() gitalypb.RegisterRefTransactionServer(srv, refTransactionServer) return srv @@ -869,10 +882,106 @@ func TestPostReceive_allRejected(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - repo, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + repo, _ := gittest.CreateRepository(ctxWithoutTransaction, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + _, _, pushRequest := createPushRequest(t, cfg) request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "key-1234", GlRepository: "some_repo"} - doPush(t, stream, request, newTestPush(t, cfg, nil).body) + performPush(t, stream, request, pushRequest) require.Equal(t, 1, refTransactionServer.called) } + +func createPushRequest(t *testing.T, cfg config.Cfg) (git.ObjectID, git.ObjectID, io.Reader) { + ctx := testhelper.Context(t) + + _, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + oldCommitID := git.ObjectID(text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD"))) + newCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(oldCommitID)) + + // ReceivePack request is a packet line followed by a packet flush, then the pack file of the objects we want to push. + // This is explained a bit in https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#_uploading_data + // We form the packet line the same way git executable does: https://github.com/git/git/blob/d1a13d3fcb252631361a961cb5e2bf10ed467cba/send-pack.c#L524-L527 + var request bytes.Buffer + gittest.WritePktlinef(t, &request, "%s %s refs/heads/master\x00 %s", oldCommitID, newCommitID, uploadPackCapabilities) + gittest.WritePktlinef(t, &request, "%s %s refs/heads/branch", git.ObjectHashSHA1.ZeroOID, newCommitID) + gittest.WritePktlineFlush(t, &request) + + // We need to get a pack file containing the objects we want to push, so we use git pack-objects + // which expects a list of revisions passed through standard input. The list format means + // pack the objects needed if I have oldHead but not newHead (think of it from the perspective of the remote repo). + // For more info, check the man pages of both `git-pack-objects` and `git-rev-list --objects`. + stdin := strings.NewReader(fmt.Sprintf("^%s\n%s\n", oldCommitID, newCommitID)) + + // The options passed are the same ones used when doing an actual push. + gittest.ExecOpts(t, cfg, gittest.ExecConfig{Stdin: stdin, Stdout: &request}, + "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q", + ) + + return oldCommitID, newCommitID, &request +} + +func performPush(t *testing.T, stream gitalypb.SmartHTTPService_PostReceivePackClient, firstRequest *gitalypb.PostReceivePackRequest, body io.Reader) string { + require.NoError(t, stream.Send(firstRequest)) + + sw := streamio.NewWriter(func(p []byte) error { + return stream.Send(&gitalypb.PostReceivePackRequest{Data: p}) + }) + _, err := io.Copy(sw, body) + require.NoError(t, err) + require.NoError(t, stream.CloseSend()) + + var response bytes.Buffer + rr := streamio.NewReader(func() ([]byte, error) { + resp, err := stream.Recv() + return resp.GetData(), err + }) + _, err = io.Copy(&response, rr) + require.NoError(t, err) + + return response.String() +} + +func drainPostReceivePackResponse(stream gitalypb.SmartHTTPService_PostReceivePackClient) error { + var err error + for err == nil { + _, err = stream.Recv() + } + return err +} + +// requireSideband compares the actual sideband data to expected sideband data. This function is +// required to filter out any keep-alive packets which Git may send over the sideband and which are +// kind of unpredictable for us. +func requireSideband(tb testing.TB, expectedSidebandMessages []string, actualInput string) { + tb.Helper() + + scanner := pktline.NewScanner(strings.NewReader(actualInput)) + + var actualSidebandMessages []string + for scanner.Scan() { + payload := scanner.Bytes() + + // Flush packets terminate the communication via side-channels, so we expect them to + // come. + if pktline.IsFlush(payload) { + require.Equal(tb, expectedSidebandMessages, actualSidebandMessages) + return + } + + // git-receive-pack(1) by default sends keep-alive packets every 5 seconds after it + // has received the full packfile. We must filter out these keep-alive packets to + // not break tests on machines which are really slow to execute. + if string(payload) == "0005\x01" { + continue + } + + actualSidebandMessages = append(actualSidebandMessages, string(payload)) + } + + require.FailNow(tb, "expected to receive a flush to terminate the protocol") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/server.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/server.go index 0145d54d99..c22609c915 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/server.go @@ -2,11 +2,11 @@ package smarthttp import ( "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { @@ -47,7 +47,7 @@ func NewServer( // ServerOpt is a self referential option for server type ServerOpt func(s *server) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func WithPackfileNegotiationMetrics(c *prometheus.CounterVec) ServerOpt { return func(s *server) { s.packfileNegotiationMetrics = c diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/testhelper_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/testhelper_test.go index 321cfed878..db0d9a1b3b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package smarthttp import ( @@ -5,17 +7,18 @@ import ( "testing" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - hookservice "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) const ( @@ -46,7 +49,7 @@ func startSmartHTTPServerWithOptions(t *testing.T, cfg config.Cfg, opts []Server deps.GetGit2goExecutor(), deps.GetHousekeepingManager(), )) - gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache())) + gitalypb.RegisterHookServiceServer(srv, hookservice.NewServer(deps.GetHookManager(), deps.GetGitCmdFactory(), deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) }, serverOpts...) } @@ -63,7 +66,7 @@ func newSmartHTTPClient(t *testing.T, serverSocketPath, token string) (gitalypb. t.Helper() connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(token)), } conn, err := grpc.Dial(serverSocketPath, connOpts...) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack.go index 73e8825d89..b0353da195 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack.go @@ -7,13 +7,13 @@ import ( "io" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -136,7 +136,7 @@ func (s *server) runUploadPack(ctx context.Context, req basicPostUploadPackReque git.WithStdin(stdin), git.WithGitProtocol(req), git.WithConfig(gitConfig...), - git.WithPackObjectsHookEnv(req.GetRepository()), + git.WithPackObjectsHookEnv(req.GetRepository(), "http"), } cmd, err := s.gitCmdFactory.NewWithoutRepo(ctx, git.SubCmd{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack_test.go index 123b0a8168..02ca6296e7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/smarthttp/upload_pack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/smarthttp/upload_pack_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package smarthttp import ( @@ -14,16 +16,16 @@ import ( promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -81,7 +83,7 @@ func testServerPostUpload(t *testing.T, ctx context.Context, makeRequest request testcfg.BuildGitalyHooks(t, cfg) - oldCommit, err := git.NewObjectIDFromHex("1e292f8fedd741b75372e19097c76d327140c312") // refs/heads/master + oldCommit, err := git.ObjectHashSHA1.FromHex("1e292f8fedd741b75372e19097c76d327140c312") // refs/heads/master require.NoError(t, err) newCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master"), gittest.WithParents(oldCommit)) @@ -137,7 +139,6 @@ func testServerPostUploadPackGitConfigOptions(t *testing.T, ctx context.Context, // the gitconfig indeed is applied because we should not be able to fetch the hidden ref. baseID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("base commit"), - gittest.WithParents(), gittest.WithBranch("main"), ) hiddenID := gittest.WriteCommit(t, cfg, repoPath, @@ -193,9 +194,9 @@ func TestServer_PostUploadPackWithSidechannel_gitProtocol(t *testing.T) { func testServerPostUploadPackGitProtocol(t *testing.T, ctx context.Context, makeRequest requestMaker, opts ...testcfg.Option) { cfg := testcfg.Build(t, opts...) - gitCmdFactory, readProto := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) server := startSmartHTTPServerWithOptions(t, cfg, nil, []testserver.GitalyServerOpt{ - testserver.WithGitCommandFactory(gitCmdFactory), + testserver.WithGitCommandFactory(protocolDetectingFactory), }) cfg.SocketPath = server.Address() @@ -219,7 +220,7 @@ func testServerPostUploadPackGitProtocol(t *testing.T, ctx context.Context, make _, err := makeRequest(ctx, t, server.Address(), cfg.Auth.Token, rpcRequest, requestBody) require.NoError(t, err) - envData := readProto() + envData := protocolDetectingFactory.ReadProtocol(t) require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) } @@ -287,7 +288,7 @@ func testServerPostUploadPackUsesPackObjectsHook(t *testing.T, ctx context.Conte // out. In the best case we'd have just printed the error to stderr and // check the return error message. But it's unfortunately not // transferred back. - testhelper.WriteExecutable(t, filepath.Join(cfg.BinDir, "gitaly-hooks"), []byte(hookScript)) + testhelper.WriteExecutable(t, cfg.BinaryPath("gitaly-hooks"), []byte(hookScript)) cfg.SocketPath = runSmartHTTPServer(t, cfg) @@ -452,7 +453,7 @@ func testServerPostUploadPackPartialClone(t *testing.T, ctx context.Context, mak testcfg.BuildGitalyHooks(t, cfg) - oldCommit, err := git.NewObjectIDFromHex("1e292f8fedd741b75372e19097c76d327140c312") // refs/heads/master + oldCommit, err := git.ObjectHashSHA1.FromHex("1e292f8fedd741b75372e19097c76d327140c312") // refs/heads/master require.NoError(t, err) newCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master"), gittest.WithParents(oldCommit)) @@ -477,7 +478,7 @@ func testServerPostUploadPackPartialClone(t *testing.T, ctx context.Context, mak // a4a132b1b0d6720ca9254440a7ba8a6b9bbd69ec is README.md, which is a small file blobLessThanLimit := git.ObjectID("a4a132b1b0d6720ca9254440a7ba8a6b9bbd69ec") - // c1788657b95998a2f177a4f86d68a60f2a80117f is CONTRIBUTING.md, which is > 200 bytese + // c1788657b95998a2f177a4f86d68a60f2a80117f is CONTRIBUTING.md, which is > 200 bytes blobGreaterThanLimit := git.ObjectID("c1788657b95998a2f177a4f86d68a60f2a80117f") gittest.RequireObjectExists(t, cfg, localRepoPath, blobLessThanLimit) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/monitor_stdin_command.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/monitor_stdin_command.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/monitor_stdin_command.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/monitor_stdin_command.go index 31f54bed0e..5bad1df278 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/monitor_stdin_command.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/monitor_stdin_command.go @@ -5,22 +5,26 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) func monitorStdinCommand(ctx context.Context, gitCmdFactory git.CommandFactory, stdin io.Reader, stdout, stderr io.Writer, sc git.SubCmd, opts ...git.CmdOpt) (*command.Command, *pktline.ReadMonitor, error) { - stdinPipe, monitor, err := pktline.NewReadMonitor(ctx, stdin) + stdinPipe, monitor, cleanup, err := pktline.NewReadMonitor(ctx, stdin) if err != nil { return nil, nil, fmt.Errorf("create monitor: %v", err) } cmd, err := gitCmdFactory.NewWithoutRepo(ctx, sc, append([]git.CmdOpt{ - git.WithStdin(stdinPipe), git.WithStdout(stdout), git.WithStderr(stderr), + git.WithStdin(stdinPipe), + git.WithStdout(stdout), + git.WithStderr(stderr), + git.WithFinalizer(func(*command.Command) { cleanup() }), }, opts...)...) stdinPipe.Close() // this now belongs to cmd if err != nil { + cleanup() return nil, nil, fmt.Errorf("start cmd: %v", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack.go index 8501525d7e..1dbddee99c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack.go @@ -3,17 +3,19 @@ package ssh import ( "errors" "fmt" + "io" + "strings" "sync" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -55,9 +57,15 @@ func (s *server) sshReceivePack(stream gitalypb.SSHService_SSHReceivePackServer, stdout := streamio.NewSyncWriter(&m, func(p []byte) error { return stream.Send(&gitalypb.SSHReceivePackResponse{Stdout: p}) }) + + // We both need to listen in on the stderr stream in order to be able to judge what exactly + // is happening, but also relay the output to the client. We thus create a MultiWriter to + // enable both at the same time. + var stderrBuilder strings.Builder stderr := streamio.NewSyncWriter(&m, func(p []byte) error { return stream.Send(&gitalypb.SSHReceivePackResponse{Stderr: p}) }) + stderr = io.MultiWriter(&stderrBuilder, stderr) repoPath, err := s.locator.GetRepoPath(req.Repository) if err != nil { @@ -86,10 +94,25 @@ func (s *server) sshReceivePack(stream gitalypb.SSHService_SSHReceivePackServer, } if err := cmd.Wait(); err != nil { - if status, ok := command.ExitStatus(err); ok { - return stream.Send(&gitalypb.SSHReceivePackResponse{ - ExitStatus: &gitalypb.ExitStatus{Value: int32(status)}, - }) + status, ok := command.ExitStatus(err) + if !ok { + return fmt.Errorf("extracting exit status: %w", err) + } + + // When the command has failed we both want to send its exit status as well as + // return an error from this RPC call. Otherwise we'd fail the RPC, but return with + // an `OK` error code to the client. + if errSend := stream.Send(&gitalypb.SSHReceivePackResponse{ + ExitStatus: &gitalypb.ExitStatus{Value: int32(status)}, + }); errSend != nil { + ctxlogrus.Extract(ctx).WithError(errSend).Error("send final status code") + } + + // Detect the case where the user has cancelled the push and log it with a proper + // gRPC error code. We can't do anything about this error anyway and it is a totally + // valid outcome. + if stderrBuilder.String() == "fatal: the remote end hung up unexpectedly\n" { + return helper.ErrCanceledf("user canceled the push") } return fmt.Errorf("cmd wait: %v", err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack_test.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack_test.go index 6439446bd1..0f9317696c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/receive_pack_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/receive_pack_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ssh import ( @@ -13,103 +15,125 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" - "google.golang.org/grpc/codes" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" "google.golang.org/protobuf/encoding/protojson" ) -func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { +func TestReceivePack_validation(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - cfg.SocketPath = runSSHServer(t, cfg) - repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, _ := gittest.CreateRepository(ctx, t, cfg) - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() + client := newSSHClient(t, cfg.SocketPath) - tests := []struct { - Desc string - Req *gitalypb.SSHReceivePackRequest - Code codes.Code + for _, tc := range []struct { + desc string + request *gitalypb.SSHReceivePackRequest + expectedErr error }{ { - Desc: "Repository.RelativePath is empty", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: ""}, GlId: "user-123"}, - Code: codes.InvalidArgument, - }, - { - Desc: "Repository is nil", - Req: &gitalypb.SSHReceivePackRequest{Repository: nil, GlId: "user-123"}, - Code: codes.InvalidArgument, - }, - { - Desc: "Empty GlId", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: repo.GetRelativePath()}, GlId: ""}, - Code: codes.InvalidArgument, - }, - { - Desc: "Data exists on first request", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: repo.GetRelativePath()}, GlId: "user-123", Stdin: []byte("Fail")}, - Code: codes.InvalidArgument, - }, - } + desc: "empty relative path", + request: &gitalypb.SSHReceivePackRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: "", + }, + GlId: "user-123", + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: invalid Repository") + } - for _, test := range tests { - t.Run(test.Desc, func(t *testing.T) { - ctx := testhelper.Context(t) + return helper.ErrInvalidArgumentf("GetPath: relative path missing from storage_name:\"default\"") + }(), + }, + { + desc: "missing repository", + request: &gitalypb.SSHReceivePackRequest{ + Repository: nil, + GlId: "user-123", + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: empty Repository") + } + return helper.ErrInvalidArgumentf("repository is empty") + }(), + }, + { + desc: "missing GlId", + request: &gitalypb.SSHReceivePackRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: repo.GetRelativePath(), + }, + GlId: "", + }, + expectedErr: helper.ErrInvalidArgumentf("empty GlId"), + }, + { + desc: "stdin on first request", + request: &gitalypb.SSHReceivePackRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: repo.GetRelativePath(), + }, + GlId: "user-123", + Stdin: []byte("Fail"), + }, + expectedErr: helper.ErrInvalidArgumentf("non-empty data in first request"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { stream, err := client.SSHReceivePack(ctx) require.NoError(t, err) - require.NoError(t, stream.Send(test.Req)) + require.NoError(t, stream.Send(tc.request)) require.NoError(t, stream.CloseSend()) - err = drainPostReceivePackResponse(stream) - testhelper.RequireGrpcCode(t, err, test.Code) + testhelper.RequireGrpcError(t, tc.expectedErr, drainPostReceivePackResponse(stream)) }) } } -func TestReceivePackPushSuccess(t *testing.T) { +func TestReceivePack_success(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - cfg.GitlabShell.Dir = "/foo/bar/gitlab-shell" gitCmdFactory, hookOutputFile := gittest.CaptureHookEnv(t, cfg) - testcfg.BuildGitalySSH(t, cfg) cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - ctx := testhelper.Context(t) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - RelativePath: "gitlab-test-ssh-receive-pack.git", - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) glRepository := "project-456" glProjectPath := "project/path" @@ -120,7 +144,7 @@ func TestReceivePackPushSuccess(t *testing.T) { // when deserializing the HooksPayload. By setting all flags to `true` explicitly, we both // verify that gitaly-ssh picks up feature flags correctly and fix the test to behave the // same with and without Praefect. - for _, featureFlag := range featureflag.All { + for _, featureFlag := range featureflag.DefinedFlags() { ctx = featureflag.ContextWithFeatureFlag(ctx, featureFlag, true) } @@ -152,26 +176,115 @@ func TestReceivePackPushSuccess(t *testing.T) { // figuring out their actual contents. So let's just remove it, too. payload.Transaction = nil - expectedFeatureFlags := featureflag.Raw{} - for _, feature := range featureflag.All { - expectedFeatureFlags[feature.MetadataKey()] = "true" + var expectedFeatureFlags []git.FeatureFlagWithValue + for _, feature := range featureflag.DefinedFlags() { + expectedFeatureFlags = append(expectedFeatureFlags, git.FeatureFlagWithValue{ + Flag: feature, Enabled: true, + }) } + // Compare here without paying attention to the order given that flags aren't sorted and + // unset the struct member afterwards. + require.ElementsMatch(t, expectedFeatureFlags, payload.FeatureFlagsWithValue) + payload.FeatureFlagsWithValue = nil + require.Equal(t, git.HooksPayload{ RuntimeDir: cfg.RuntimeDir, - InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, - ReceiveHooksPayload: &git.ReceiveHooksPayload{ + UserDetails: &git.UserDetails{ UserID: "123", Username: "user", Protocol: "ssh", }, RequestedHooks: git.ReceivePackHooks, - FeatureFlags: expectedFeatureFlags, }, payload) } -func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { +func TestReceivePack_client(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) + + for _, tc := range []struct { + desc string + writeRequest func(*testing.T, io.Writer) + expectedErr error + expectedErrorCode int32 + expectedStderr string + }{ + { + desc: "no commands", + writeRequest: func(t *testing.T, stdin io.Writer) { + gittest.WritePktlineFlush(t, stdin) + }, + }, + { + desc: "garbage", + writeRequest: func(t *testing.T, stdin io.Writer) { + gittest.WritePktlineString(t, stdin, "garbage") + }, + expectedErr: helper.ErrInternalf("cmd wait: exit status 128"), + expectedErrorCode: 128, + expectedStderr: "fatal: protocol error: expected old/new/ref, got 'garbage'\n", + }, + { + desc: "command without flush", + writeRequest: func(t *testing.T, stdin io.Writer) { + gittest.WritePktlinef(t, stdin, "%[1]s %[1]s refs/heads/main", gittest.DefaultObjectHash.ZeroOID) + }, + expectedErr: helper.ErrCanceledf("user canceled the push"), + expectedErrorCode: 128, + expectedStderr: "fatal: the remote end hung up unexpectedly\n", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) + + stream, err := newSSHClient(t, cfg.SocketPath).SSHReceivePack(ctx) + require.NoError(t, err) + + var observedErrorCode int32 + var stderr bytes.Buffer + errCh := make(chan error, 1) + go func() { + stdout := streamio.NewReader(func() ([]byte, error) { + msg, err := stream.Recv() + if errorCode := msg.GetExitStatus().GetValue(); errorCode != 0 { + require.Zero(t, observedErrorCode, "must not receive multiple messages with non-zero exit code") + observedErrorCode = errorCode + } + + // Write stderr so we can verify what git-receive-pack(1) + // complains about. + _, writeErr := stderr.Write(msg.GetStderr()) + require.NoError(t, writeErr) + + return msg.GetStdout(), err + }) + + _, err := io.Copy(io.Discard, stdout) + errCh <- err + }() + + require.NoError(t, stream.Send(&gitalypb.SSHReceivePackRequest{Repository: repoProto, GlId: "user-123"})) + + stdin := streamio.NewWriter(func(b []byte) error { + return stream.Send(&gitalypb.SSHReceivePackRequest{Stdin: b}) + }) + tc.writeRequest(t, stdin) + require.NoError(t, stream.CloseSend()) + + testhelper.RequireGrpcError(t, <-errCh, tc.expectedErr) + require.Equal(t, tc.expectedErrorCode, observedErrorCode) + require.Equal(t, tc.expectedStderr, stderr.String()) + }) + } +} + +func TestReceive_gitProtocol(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -180,13 +293,12 @@ func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) ctx := testhelper.Context(t) - gitCmdFactory, readProto := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) - cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) + cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(protocolDetectingFactory)) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) lHead, rHead, err := testCloneAndPush(ctx, t, cfg, cfg.SocketPath, repo, repoPath, pushParams{ storageName: testhelper.DefaultStorageName, @@ -195,43 +307,56 @@ func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { gitProtocol: git.ProtocolV2, }) require.NoError(t, err) + require.Equal(t, lHead, rHead) - require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") - - envData := readProto() + envData := protocolDetectingFactory.ReadProtocol(t) require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) } -func TestReceivePackPushFailure(t *testing.T) { +func TestReceivePack_failure(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) - cfg, repo, repoPath := testcfg.BuildWithRepo(t) + testcfg.BuildGitalySSH(t, cfg) - serverSocketPath := runSSHServer(t, cfg) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) - _, _, err := testCloneAndPush(ctx, t, cfg, serverSocketPath, repo, repoPath, pushParams{storageName: "foobar", glID: "1"}) - require.Error(t, err, "local and remote head equal. push did not fail") + t.Run("clone with invalid storage name", func(t *testing.T) { + _, _, err := testCloneAndPush(ctx, t, cfg, cfg.SocketPath, repo, repoPath, pushParams{ + storageName: "foobar", + glID: "1", + }) + require.Error(t, err) - _, _, err = testCloneAndPush(ctx, t, cfg, serverSocketPath, repo, repoPath, pushParams{storageName: cfg.Storages[0].Name, glID: ""}) - require.Error(t, err, "local and remote head equal. push did not fail") + if testhelper.IsPraefectEnabled() { + require.Contains(t, err.Error(), helper.ErrInvalidArgumentf("repo scoped: invalid Repository").Error()) + } else { + require.Contains(t, err.Error(), helper.ErrInvalidArgumentf("GetStorageByName: no such storage: \\\"foobar\\\"\\n").Error()) + } + }) + + t.Run("clone with invalid GlId", func(t *testing.T) { + _, _, err := testCloneAndPush(ctx, t, cfg, cfg.SocketPath, repo, repoPath, pushParams{storageName: cfg.Storages[0].Name, glID: ""}) + require.Error(t, err) + require.Contains(t, err.Error(), helper.ErrInvalidArgumentf("empty GlId").Error()) + }) } -func TestReceivePackPushHookFailure(t *testing.T) { +func TestReceivePack_hookFailure(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) gitCmdFactory := gittest.NewCommandFactory(t, cfg, git.WithHooksPath(testhelper.TempDir(t))) testcfg.BuildGitalySSH(t, cfg) cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - ctx := testhelper.Context(t) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) hookContent := []byte("#!/bin/sh\nexit 1") require.NoError(t, os.WriteFile(filepath.Join(gitCmdFactory.HooksPath(ctx), "pre-receive"), hookContent, 0o755)) @@ -241,21 +366,17 @@ func TestReceivePackPushHookFailure(t *testing.T) { require.Contains(t, err.Error(), "(pre-receive hook declined)") } -func TestReceivePackPushHookFailureWithCustomHook(t *testing.T) { +func TestReceivePack_customHookFailure(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - gitCmdFactory := gittest.NewCommandFactory(t, cfg) + cfg.SocketPath = runSSHServer(t, cfg) testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) - cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - ctx := testhelper.Context(t) - - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) cloneDetails, cleanup := setupSSHClone(t, cfg, repo, repoPath) defer cleanup() @@ -274,7 +395,6 @@ func TestReceivePackPushHookFailureWithCustomHook(t *testing.T) { require.NoError(t, err) stderr, err := cmd.StderrPipe() require.NoError(t, err) - require.NoError(t, cmd.Start()) c, err := io.Copy(io.Discard, stdout) @@ -288,28 +408,23 @@ func TestReceivePackPushHookFailureWithCustomHook(t *testing.T) { require.Contains(t, string(slurpErr), "remote: this is wrong") require.Contains(t, string(slurpErr), "(pre-receive hook declined)") - require.NotContains(t, string(slurpErr), "final transactional vote: transaction was stopped") } -func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { +func TestReceivePack_hidesObjectPoolReferences(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) testcfg.BuildGitalyHooks(t, cfg) - cfg.SocketPath = runSSHServer(t, cfg) - - ctx := testhelper.Context(t) - repoProto, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repoProto, _ := gittest.CreateRepository(ctx, t, cfg) repo := localrepo.NewTestRepo(t, cfg, repoProto) txManager := transaction.NewManager(cfg, backchannel.NewRegistry()) - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() + client := newSSHClient(t, cfg.SocketPath) stream, err := client.SSHReceivePack(ctx) require.NoError(t, err) @@ -324,16 +439,13 @@ func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { gittest.NewObjectPoolName(t), ) require.NoError(t, err) - require.NoError(t, pool.Create(ctx, repo)) - require.NoError(t, pool.Link(ctx, repo)) commitID := gittest.WriteCommit(t, cfg, pool.FullPath(), gittest.WithBranch(t.Name())) // First request require.NoError(t, stream.Send(&gitalypb.SSHReceivePackRequest{Repository: repoProto, GlId: "user-123"})) - require.NoError(t, stream.Send(&gitalypb.SSHReceivePackRequest{Stdin: []byte("0000")})) require.NoError(t, stream.CloseSend()) @@ -348,44 +460,40 @@ func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { require.NotContains(t, b.String(), commitID+" .have") } -func TestReceivePackTransactional(t *testing.T) { +func TestReceivePack_transactional(t *testing.T) { t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) - testcfg.BuildGitalyHooks(t, cfg) - txManager := transaction.NewTrackingManager() cfg.SocketPath = runSSHServer(t, cfg, testserver.WithTransactionManager(txManager)) - ctx := testhelper.Context(t) - repoProto, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) - repo := localrepo.NewTestRepo(t, cfg, repoProto) + testcfg.BuildGitalyHooks(t, cfg) + + client := newSSHClient(t, cfg.SocketPath) - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() ctx, err := txinfo.InjectTransaction(ctx, 1, "node", true) require.NoError(t, err) ctx = metadata.IncomingToOutgoing(ctx) - masterOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, - "rev-parse", "refs/heads/master")) - masterParentOID := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "refs/heads/master~")) + repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg) + repo := localrepo.NewTestRepo(t, cfg, repoProto) + parentCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents(parentCommitID)) type command struct { ref string - oldOID string - newOID string + oldOID git.ObjectID + newOID git.ObjectID } for _, tc := range []struct { desc string writePackfile bool commands []command - expectedRefs map[string]string + expectedRefs map[string]git.ObjectID expectedVotes int }{ { @@ -393,13 +501,13 @@ func TestReceivePackTransactional(t *testing.T) { writePackfile: true, commands: []command{ { - ref: "refs/heads/master", - oldOID: masterOID, - newOID: masterOID, + ref: "refs/heads/main", + oldOID: commitID, + newOID: commitID, }, }, - expectedRefs: map[string]string{ - "refs/heads/master": masterOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/main": commitID, }, expectedVotes: 3, }, @@ -408,13 +516,13 @@ func TestReceivePackTransactional(t *testing.T) { writePackfile: true, commands: []command{ { - ref: "refs/heads/master", - oldOID: masterOID, - newOID: masterParentOID, + ref: "refs/heads/main", + oldOID: commitID, + newOID: parentCommitID, }, }, - expectedRefs: map[string]string{ - "refs/heads/master": masterParentOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/main": parentCommitID, }, expectedVotes: 3, }, @@ -424,12 +532,12 @@ func TestReceivePackTransactional(t *testing.T) { commands: []command{ { ref: "refs/heads/other", - oldOID: git.ZeroOID.String(), - newOID: masterOID, + oldOID: gittest.DefaultObjectHash.ZeroOID, + newOID: commitID, }, }, - expectedRefs: map[string]string{ - "refs/heads/other": masterOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/other": commitID, }, expectedVotes: 3, }, @@ -438,12 +546,12 @@ func TestReceivePackTransactional(t *testing.T) { commands: []command{ { ref: "refs/heads/other", - oldOID: masterOID, - newOID: git.ZeroOID.String(), + oldOID: commitID, + newOID: gittest.DefaultObjectHash.ZeroOID, }, }, - expectedRefs: map[string]string{ - "refs/heads/other": git.ZeroOID.String(), + expectedRefs: map[string]git.ObjectID{ + "refs/heads/other": gittest.DefaultObjectHash.ZeroOID, }, expectedVotes: 3, }, @@ -453,18 +561,18 @@ func TestReceivePackTransactional(t *testing.T) { commands: []command{ { ref: "refs/heads/a", - oldOID: git.ZeroOID.String(), - newOID: masterOID, + oldOID: gittest.DefaultObjectHash.ZeroOID, + newOID: commitID, }, { ref: "refs/heads/b", - oldOID: git.ZeroOID.String(), - newOID: masterOID, + oldOID: gittest.DefaultObjectHash.ZeroOID, + newOID: commitID, }, }, - expectedRefs: map[string]string{ - "refs/heads/a": masterOID, - "refs/heads/b": masterOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/a": commitID, + "refs/heads/b": commitID, }, expectedVotes: 5, }, @@ -474,12 +582,12 @@ func TestReceivePackTransactional(t *testing.T) { commands: []command{ { ref: "refs/heads/a", - oldOID: git.ZeroOID.String(), - newOID: masterParentOID, + oldOID: gittest.DefaultObjectHash.ZeroOID, + newOID: parentCommitID, }, }, - expectedRefs: map[string]string{ - "refs/heads/a": masterOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/a": commitID, }, expectedVotes: 1, }, @@ -489,17 +597,17 @@ func TestReceivePackTransactional(t *testing.T) { commands: []command{ { ref: "refs/heads/a", - oldOID: git.ZeroOID.String(), - newOID: masterParentOID, + oldOID: gittest.DefaultObjectHash.ZeroOID, + newOID: parentCommitID, }, { ref: "refs/heads/b", - oldOID: masterOID, - newOID: git.ZeroOID.String(), + oldOID: commitID, + newOID: gittest.DefaultObjectHash.ZeroOID, }, }, - expectedRefs: map[string]string{ - "refs/heads/a": masterOID, + expectedRefs: map[string]git.ObjectID{ + "refs/heads/a": commitID, }, expectedVotes: 3, }, @@ -543,11 +651,11 @@ func TestReceivePackTransactional(t *testing.T) { for expectedRef, expectedOID := range tc.expectedRefs { actualOID, err := repo.ResolveRevision(ctx, git.Revision(expectedRef)) - if expectedOID == git.ZeroOID.String() { + if expectedOID == gittest.DefaultObjectHash.ZeroOID { require.Equal(t, git.ErrReferenceNotFound, err) } else { require.NoError(t, err) - require.Equal(t, expectedOID, actualOID.String()) + require.Equal(t, expectedOID, actualOID) } } require.Equal(t, tc.expectedVotes, len(txManager.Votes())) @@ -555,7 +663,7 @@ func TestReceivePackTransactional(t *testing.T) { } } -func TestSSHReceivePackToHooks(t *testing.T) { +func TestReceivePack_objectExistsHook(t *testing.T) { t.Parallel() cfg := testcfg.Build(t) @@ -570,12 +678,10 @@ func TestSSHReceivePackToHooks(t *testing.T) { ) ctx := testhelper.Context(t) - gitCmdFactory, readProto := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) - cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(protocolDetectingFactory)) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) tempGitlabShellDir := testhelper.TempDir(t) @@ -612,7 +718,7 @@ func TestSSHReceivePackToHooks(t *testing.T) { require.NoError(t, err) require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") - envData := readProto() + envData := protocolDetectingFactory.ReadProtocol(t) require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) } @@ -625,7 +731,11 @@ type SSHCloneDetails struct { // setupSSHClone sets up a test clone func setupSSHClone(t *testing.T, cfg config.Cfg, remoteRepo *gitalypb.Repository, remoteRepoPath string) (SSHCloneDetails, func()) { - _, localRepoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + ctx := testhelper.Context(t) + + _, localRepoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) oldHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", localRepoPath, "rev-parse", "HEAD")) newHead := gittest.WriteCommit(t, cfg, localRepoPath, @@ -668,13 +778,18 @@ func sshPushCommand(ctx context.Context, t *testing.T, cfg config.Cfg, cloneDeta }) require.NoError(t, err) + var flagsWithValues []string + for flag, value := range featureflag.FromContext(ctx) { + flagsWithValues = append(flagsWithValues, flag.FormatWithValue(value)) + } + cmd := gittest.NewCommand(t, cfg, "-C", cloneDetails.LocalRepoPath, "push", "-v", "git@localhost:test/test.git", "master") - cmd.Env = []string{ + cmd.Env = append(cmd.Env, fmt.Sprintf("GITALY_PAYLOAD=%s", payload), fmt.Sprintf("GITALY_ADDRESS=%s", serverSocketPath), - fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(featureflag.AllFlags(ctx), ",")), - fmt.Sprintf("GIT_SSH_COMMAND=%s receive-pack", filepath.Join(cfg.BinDir, "gitaly-ssh")), - } + fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(flagsWithValues, ",")), + fmt.Sprintf("GIT_SSH_COMMAND=%s receive-pack", cfg.BinaryPath("gitaly-ssh")), + ) return cmd } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/server.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/server.go index 98da4695e3..cddf72d37c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/server.go @@ -4,10 +4,10 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) var ( @@ -68,7 +68,7 @@ func WithArchiveRequestTimeout(d time.Duration) ServerOpt { } } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func WithPackfileNegotiationMetrics(c *prometheus.CounterVec) ServerOpt { return func(s *server) { s.packfileNegotiationMetrics = c diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/testhelper_test.go new file mode 100644 index 0000000000..194fddeb85 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/testhelper_test.go @@ -0,0 +1,68 @@ +//go:build !gitaly_test_sha256 + +package ssh + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + hookservice "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func runSSHServer(t *testing.T, cfg config.Cfg, serverOpts ...testserver.GitalyServerOpt) string { + return runSSHServerWithOptions(t, cfg, nil, serverOpts...) +} + +func runSSHServerWithOptions(t *testing.T, cfg config.Cfg, opts []ServerOpt, serverOpts ...testserver.GitalyServerOpt) string { + return startSSHServerWithOptions(t, cfg, opts, serverOpts...).Address() +} + +func startSSHServerWithOptions(t *testing.T, cfg config.Cfg, opts []ServerOpt, serverOpts ...testserver.GitalyServerOpt) testserver.GitalyServer { + return testserver.StartGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + gitalypb.RegisterSSHServiceServer(srv, NewServer( + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetTxManager(), + opts...)) + gitalypb.RegisterHookServiceServer(srv, + hookservice.NewServer( + deps.GetHookManager(), + deps.GetGitCmdFactory(), + deps.GetPackObjectsCache(), + deps.GetPackObjectsConcurrencyTracker(), + )) + gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( + cfg, + deps.GetRubyServer(), + deps.GetLocator(), + deps.GetTxManager(), + deps.GetGitCmdFactory(), + deps.GetCatfileCache(), + deps.GetConnsPool(), + deps.GetGit2goExecutor(), + deps.GetHousekeepingManager(), + )) + }, serverOpts...) +} + +func newSSHClient(t *testing.T, serverSocketPath string) gitalypb.SSHServiceClient { + conn, err := grpc.Dial(serverSocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + t.Cleanup(func() { + testhelper.MustClose(t, conn) + }) + + return gitalypb.NewSSHServiceClient(conn) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive.go index 9d7bce341c..3dc362a916 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive.go @@ -5,12 +5,12 @@ import ( "fmt" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) SSHUploadArchive(stream gitalypb.SSHService_SSHUploadArchiveServer) error { @@ -69,6 +69,18 @@ func (s *server) sshUploadArchive(stream gitalypb.SSHService_SSHUploadArchiveSer go monitor.Monitor(ctx, pktline.PktFlush(), timeoutTicker, cancelCtx) if err := cmd.Wait(); err != nil { + // When waiting for the packfile negotiation to end times out we'll cancel the local + // context, but not cancel the overall RPC's context. Our cancelhandler middleware + // thus cannot observe the fact that we're cancelling the context, and neither do we + // provide any valuable information to the caller that we do indeed kill the command + // because of our own internal timeout. + // + // We thus need to special-case the situation where we cancel our own context in + // order to provide that information and return a proper gRPC error code. + if ctx.Err() != nil && stream.Context().Err() == nil { + return helper.ErrDeadlineExceededf("waiting for packfile negotiation: %w", ctx.Err()) + } + if status, ok := command.ExitStatus(err); ok { if sendErr := stream.Send(&gitalypb.SSHUploadArchiveResponse{ ExitStatus: &gitalypb.ExitStatus{Value: int32(status)}, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive_test.go index 58bd5b6441..ea5fb77b37 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_archive_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_archive_test.go @@ -1,17 +1,19 @@ +//go:build !gitaly_test_sha256 + package ssh import ( "fmt" "os" - "path/filepath" "testing" "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/protobuf/encoding/protojson" ) @@ -28,8 +30,7 @@ func TestFailedUploadArchiveRequestDueToTimeout(t *testing.T) { Seed: gittest.SeedGitLabTest, }) - client, conn := newSSHClient(t, cfg.SocketPath) - defer conn.Close() + client := newSSHClient(t, cfg.SocketPath) stream, err := client.SSHUploadArchive(ctx) require.NoError(t, err) @@ -40,7 +41,7 @@ func TestFailedUploadArchiveRequestDueToTimeout(t *testing.T) { // Because the client says nothing, the server would block. Because of // the timeout, it won't block forever, and return with a non-zero exit // code instead. - requireFailedSSHStream(t, func() (int32, error) { + requireFailedSSHStream(t, helper.ErrDeadlineExceededf("waiting for packfile negotiation: context canceled"), func() (int32, error) { resp, err := stream.Recv() if err != nil { return 0, err @@ -62,8 +63,7 @@ func TestFailedUploadArchiveRequestDueToValidationError(t *testing.T) { serverSocketPath := runSSHServer(t, cfg) - client, conn := newSSHClient(t, serverSocketPath) - defer conn.Close() + client := newSSHClient(t, serverSocketPath) tests := []struct { Desc string @@ -136,7 +136,7 @@ func TestUploadArchiveSuccess(t *testing.T) { fmt.Sprintf("GITALY_ADDRESS=%s", cfg.SocketPath), fmt.Sprintf("GITALY_PAYLOAD=%s", payload), fmt.Sprintf("PATH=%s", ".:"+os.Getenv("PATH")), - fmt.Sprintf(`GIT_SSH_COMMAND=%s upload-archive`, filepath.Join(cfg.BinDir, "gitaly-ssh")), + fmt.Sprintf(`GIT_SSH_COMMAND=%s upload-archive`, cfg.BinaryPath("gitaly-ssh")), }, }, "archive", "master", "--remote=git@localhost:test/test.git") } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack.go index 5d23c53b06..e468c834c6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ssh/upload_pack.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack.go @@ -9,15 +9,15 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/stats" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/stream" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/stream" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) error { @@ -28,13 +28,8 @@ func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) e return helper.ErrInternal(err) } - repository := "" - if req.Repository != nil { - repository = req.Repository.GlRepository - } - ctxlogrus.Extract(ctx).WithFields(log.Fields{ - "GlRepository": repository, + "GlRepository": req.GetRepository().GetGlRepository(), "GitConfigOptions": req.GitConfigOptions, "GitProtocol": req.GitProtocol, }).Debug("SSHUploadPack") @@ -49,7 +44,7 @@ func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) e }) // gRPC doesn't allow concurrent writes to a stream, so we need to - // synchronize writing stdout and stderrr. + // synchronize writing stdout and stderr. var m sync.Mutex stdout := streamio.NewSyncWriter(&m, func(p []byte) error { return stream.Send(&gitalypb.SSHUploadPackResponse{Stdout: p}) @@ -77,8 +72,8 @@ type sshUploadPackRequest interface { GetGitProtocol() string } -func (s *server) sshUploadPack(ctx context.Context, req sshUploadPackRequest, stdin io.Reader, stdout, stderr io.Writer) (int, error) { - ctx, cancelCtx := context.WithCancel(ctx) +func (s *server) sshUploadPack(rpcContext context.Context, req sshUploadPackRequest, stdin io.Reader, stdout, stderr io.Writer) (int, error) { + ctx, cancelCtx := context.WithCancel(rpcContext) defer cancelCtx() stdoutCounter := &helper.CountingWriter{W: stdout} @@ -98,10 +93,14 @@ func (s *server) sshUploadPack(ctx context.Context, req sshUploadPackRequest, st return 0, err } + var wg sync.WaitGroup pr, pw := io.Pipe() - defer pw.Close() + defer func() { + pw.Close() + wg.Wait() + }() + stdin = io.TeeReader(stdin, pw) - wg := sync.WaitGroup{} wg.Add(1) go func() { @@ -121,7 +120,7 @@ func (s *server) sshUploadPack(ctx context.Context, req sshUploadPackRequest, st commandOpts := []git.CmdOpt{ git.WithGitProtocol(req), git.WithConfig(config...), - git.WithPackObjectsHookEnv(repo), + git.WithPackObjectsHookEnv(repo, "ssh"), } var stderrBuilder strings.Builder @@ -146,16 +145,36 @@ func (s *server) sshUploadPack(ctx context.Context, req sshUploadPackRequest, st go monitor.Monitor(ctx, pktline.PktDone(), timeoutTicker, cancelCtx) if err := cmd.Wait(); err != nil { - pw.Close() - wg.Wait() - status, _ := command.ExitStatus(err) + + // When waiting for the packfile negotiation to end times out we'll cancel the local + // context, but not cancel the overall RPC's context. Our cancelhandler middleware + // thus cannot observe the fact that we're cancelling the context, and neither do we + // provide any valuable information to the caller that we do indeed kill the command + // because of our own internal timeout. + // + // We thus need to special-case the situation where we cancel our own context in + // order to provide that information and return a proper gRPC error code. + if ctx.Err() != nil && rpcContext.Err() == nil { + return status, helper.ErrDeadlineExceededf("waiting for packfile negotiation: %w", ctx.Err()) + } + + // A common error case is that the client is terminating the request prematurely, + // e.g. by killing their git-fetch(1) process because it's taking too long. This is + // an expected failure, but we're not in a position to easily tell this error apart + // from other errors returned by git-upload-pack(1). So we have to resort to parsing + // the error message returned by Git, and if we see that it matches we return an + // error with a `Canceled` error code. + // + // Note that we're being quite strict with how we match the error for now. We may + // have to make it more lenient in case we see that this doesn't catch all cases. + if stderrBuilder.String() == "fatal: the remote end hung up unexpectedly\n" { + return status, helper.ErrCanceledf("user canceled the fetch") + } + return status, fmt.Errorf("cmd wait: %w, stderr: %q", err, stderrBuilder.String()) } - pw.Close() - wg.Wait() - ctxlogrus.Extract(ctx).WithField("response_bytes", stdoutCounter.N).Info("request details") return 0, nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack_test.go new file mode 100644 index 0000000000..4d6e9e46be --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ssh/upload_pack_test.go @@ -0,0 +1,813 @@ +//go:build !gitaly_test_sha256 + +package ssh + +import ( + "bytes" + "context" + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" + promtest "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/protobuf/encoding/protojson" +) + +func runTestWithAndWithoutConfigOptions(t *testing.T, tf func(t *testing.T, opts ...testcfg.Option), opts ...testcfg.Option) { + t.Run("no config options", func(t *testing.T) { tf(t) }) + + if len(opts) > 0 { + t.Run("with config options", func(t *testing.T) { + tf(t, opts...) + }) + } +} + +// runClone runs the given Git command with gitaly-ssh set up as its SSH command. It will thus +// invoke the Gitaly server's SSHUploadPack or SSHUploadPackWithSidechannel endpoint. +func runClone( + ctx context.Context, + t *testing.T, + cfg config.Cfg, + withSidechannel bool, + cloneCmd git.Cmd, + request *gitalypb.SSHUploadPackRequest, +) error { + payload, err := protojson.Marshal(request) + require.NoError(t, err) + + var flagsWithValues []string + for flag, value := range featureflag.FromContext(ctx) { + flagsWithValues = append(flagsWithValues, flag.FormatWithValue(value)) + } + + env := []string{ + fmt.Sprintf("GITALY_ADDRESS=%s", cfg.SocketPath), + fmt.Sprintf("GITALY_PAYLOAD=%s", payload), + fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(flagsWithValues, ",")), + fmt.Sprintf(`GIT_SSH_COMMAND=%s upload-pack`, cfg.BinaryPath("gitaly-ssh")), + } + if withSidechannel { + env = append(env, "GITALY_USE_SIDECHANNEL=1") + } + + var output bytes.Buffer + gitCommand, err := gittest.NewCommandFactory(t, cfg).NewWithoutRepo(ctx, + cloneCmd, git.WithStdout(&output), git.WithStderr(&output), git.WithEnv(env...), git.WithDisabledHooks(), + ) + require.NoError(t, err) + + if err := gitCommand.Wait(); err != nil { + return fmt.Errorf("Failed to run `git clone`: %q", output.Bytes()) + } + + return nil +} + +func requireRevisionsEqual(t *testing.T, cfg config.Cfg, repoPathA, repoPathB, revision string) { + t.Helper() + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPathA, "rev-parse", revision+"^{}")), + text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPathB, "rev-parse", revision+"^{}")), + ) +} + +func TestUploadPack_timeout(t *testing.T) { + t.Parallel() + + runTestWithAndWithoutConfigOptions(t, testUploadPackTimeout, testcfg.WithPackObjectsCacheEnabled()) +} + +func testUploadPackTimeout(t *testing.T, opts ...testcfg.Option) { + ctx := testhelper.Context(t) + cfg := testcfg.Build(t, opts...) + + cfg.SocketPath = runSSHServerWithOptions(t, cfg, []ServerOpt{WithUploadPackRequestTimeout(1)}) + + repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + + client := newSSHClient(t, cfg.SocketPath) + + stream, err := client.SSHUploadPack(ctx) + require.NoError(t, err) + + // The first request is not limited by timeout, but also not under attacker control + require.NoError(t, stream.Send(&gitalypb.SSHUploadPackRequest{Repository: repo})) + + // Because the client says nothing, the server would block. Because of + // the timeout, it won't block forever, and return with a non-zero exit + // code instead. + requireFailedSSHStream(t, helper.ErrDeadlineExceededf("waiting for packfile negotiation: context canceled"), func() (int32, error) { + resp, err := stream.Recv() + if err != nil { + return 0, err + } + + var code int32 + if status := resp.GetExitStatus(); status != nil { + code = status.Value + } + + return code, nil + }) +} + +func TestUploadPackWithSidechannel_client(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) + + repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + commitID := gittest.Exec(t, cfg, "-C", repoPath, "rev-parse", "HEAD^{commit}") + + registry := sidechannel.NewRegistry() + clientHandshaker := sidechannel.NewClientHandshaker(testhelper.NewDiscardingLogEntry(t), registry) + conn, err := grpc.Dial(cfg.SocketPath, + grpc.WithTransportCredentials(clientHandshaker.ClientHandshake(insecure.NewCredentials())), + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token)), + ) + require.NoError(t, err) + + client := gitalypb.NewSSHServiceClient(conn) + defer testhelper.MustClose(t, conn) + + for _, tc := range []struct { + desc string + request *gitalypb.SSHUploadPackWithSidechannelRequest + client func(clientConn *sidechannel.ClientConn, cancelContext func()) error + expectedErr error + expectedResponse *gitalypb.SSHUploadPackWithSidechannelResponse + }{ + { + desc: "successful clone", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "want "+text.ChompBytes(commitID)+" multi_ack\n") + gittest.WritePktlineFlush(t, clientConn) + gittest.WritePktlineString(t, clientConn, "done\n") + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedResponse: &gitalypb.SSHUploadPackWithSidechannelResponse{}, + }, + { + desc: "successful clone with protocol v2", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + gittest.WritePktlineString(t, clientConn, "agent=git/2.36.1\n") + gittest.WritePktlineString(t, clientConn, "object-format=sha1\n") + gittest.WritePktlineDelim(t, clientConn) + gittest.WritePktlineString(t, clientConn, "want "+text.ChompBytes(commitID)+"\n") + gittest.WritePktlineString(t, clientConn, "done\n") + gittest.WritePktlineFlush(t, clientConn) + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedResponse: &gitalypb.SSHUploadPackWithSidechannelResponse{}, + }, + { + desc: "client talks protocol v0 but v2 is requested", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "want "+text.ChompBytes(commitID)+" multi_ack\n") + gittest.WritePktlineFlush(t, clientConn) + gittest.WritePktlineString(t, clientConn, "done\n") + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrInternalf( + "cmd wait: exit status 128, stderr: %q", + "fatal: unknown capability 'want 1e292f8fedd741b75372e19097c76d327140c312 multi_ack'\n", + ), + }, + { + desc: "client talks protocol v2 but v0 is requested", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + gittest.WritePktlineString(t, clientConn, "agent=git/2.36.1\n") + gittest.WritePktlineString(t, clientConn, "object-format=sha1\n") + gittest.WritePktlineDelim(t, clientConn) + gittest.WritePktlineString(t, clientConn, "want "+text.ChompBytes(commitID)+"\n") + gittest.WritePktlineString(t, clientConn, "done\n") + gittest.WritePktlineFlush(t, clientConn) + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrInternalf( + "cmd wait: exit status 128, stderr: %q", + "fatal: git upload-pack: protocol error, expected to get object ID, not 'command=fetch'\n", + ), + }, + { + desc: "request missing object", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "want "+strings.Repeat("1", 40)+" multi_ack\n") + gittest.WritePktlineFlush(t, clientConn) + gittest.WritePktlineString(t, clientConn, "done\n") + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrInternalf("cmd wait: exit status 128, stderr: %q", + "fatal: git upload-pack: not our ref "+strings.Repeat("1", 40)+"\n", + ), + }, + { + desc: "request invalidly formatted object", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "want 1111 multi_ack\n") + gittest.WritePktlineFlush(t, clientConn) + gittest.WritePktlineString(t, clientConn, "done\n") + + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrInternalf("cmd wait: exit status 128, stderr: %q", + "fatal: git upload-pack: protocol error, expected to get object ID, not 'want 1111 multi_ack'\n", + ), + }, + { + desc: "missing input", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + require.NoError(t, clientConn.CloseWrite()) + return nil + }, + expectedResponse: &gitalypb.SSHUploadPackWithSidechannelResponse{}, + }, + { + desc: "short write", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + + _, err := io.WriteString(clientConn, "0011agent") + require.NoError(t, err) + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrCanceledf("user canceled the fetch"), + }, + { + desc: "garbage", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, _ func()) error { + gittest.WritePktlineString(t, clientConn, "foobar") + require.NoError(t, clientConn.CloseWrite()) + return nil + }, + expectedErr: helper.ErrInternalf("cmd wait: exit status 128, stderr: %q", "fatal: unknown capability 'foobar'\n"), + }, + { + desc: "close and cancellation", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, cancelContext func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + gittest.WritePktlineString(t, clientConn, "agent=git/2.36.1\n") + + require.NoError(t, clientConn.CloseWrite()) + cancelContext() + + return nil + }, + expectedErr: helper.ErrCanceled(context.Canceled), + }, + { + desc: "cancellation and close", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, cancelContext func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + gittest.WritePktlineString(t, clientConn, "agent=git/2.36.1\n") + + cancelContext() + require.NoError(t, clientConn.CloseWrite()) + + return nil + }, + expectedErr: helper.ErrCanceled(context.Canceled), + }, + { + desc: "cancellation without close", + request: &gitalypb.SSHUploadPackWithSidechannelRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + client: func(clientConn *sidechannel.ClientConn, cancelContext func()) error { + gittest.WritePktlineString(t, clientConn, "command=fetch\n") + gittest.WritePktlineString(t, clientConn, "agent=git/2.36.1\n") + + cancelContext() + + return nil + }, + expectedErr: helper.ErrCanceled(context.Canceled), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx, cancel := context.WithCancel(testhelper.Context(t)) + + ctx, waiter := sidechannel.RegisterSidechannel(ctx, registry, func(clientConn *sidechannel.ClientConn) (returnedErr error) { + errCh := make(chan error, 1) + go func() { + _, err := io.Copy(io.Discard, clientConn) + errCh <- err + }() + defer func() { + if err := <-errCh; err != nil && returnedErr == nil { + returnedErr = err + } + }() + + return tc.client(clientConn, cancel) + }) + defer testhelper.MustClose(t, waiter) + + response, err := client.SSHUploadPackWithSidechannel(ctx, tc.request) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + testhelper.ProtoEqual(t, tc.expectedResponse, response) + }) + } +} + +func requireFailedSSHStream(t *testing.T, expectedErr error, recv func() (int32, error)) { + done := make(chan struct{}) + var code int32 + var err error + + go func() { + for err == nil { + code, err = recv() + } + close(done) + }() + + select { + case <-done: + testhelper.RequireGrpcError(t, expectedErr, err) + require.NotEqual(t, 0, code, "exit status") + case <-time.After(10 * time.Second): + t.Fatal("timeout waiting for SSH stream") + } +} + +func TestUploadPack_validation(t *testing.T) { + t.Parallel() + + cfg := testcfg.Build(t) + + serverSocketPath := runSSHServer(t, cfg) + + client := newSSHClient(t, serverSocketPath) + + for _, tc := range []struct { + desc string + request *gitalypb.SSHUploadPackRequest + expectedErr error + }{ + { + desc: "missing relative path", + request: &gitalypb.SSHUploadPackRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: "", + }, + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: invalid Repository") + } + return helper.ErrInvalidArgumentf("GetPath: relative path missing from storage_name:%q", "default") + }(), + }, + { + desc: "missing repository", + request: &gitalypb.SSHUploadPackRequest{ + Repository: nil, + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrInvalidArgumentf("repo scoped: empty Repository") + } + return helper.ErrInvalidArgumentf("GetStorageByName: no such storage: \"\"") + }(), + }, + { + desc: "data in first request", + request: &gitalypb.SSHUploadPackRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: "path/to/repo", + }, + Stdin: []byte("Fail"), + }, + expectedErr: func() error { + if testhelper.IsPraefectEnabled() { + return helper.ErrNotFoundf("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "path/to/repo") + } + return helper.ErrInvalidArgumentf("non-empty stdin in first request") + }(), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + + stream, err := client.SSHUploadPack(ctx) + require.NoError(t, err) + require.NoError(t, stream.Send(tc.request)) + require.NoError(t, stream.CloseSend()) + + err = recvUntilError(t, stream) + testhelper.RequireGrpcError(t, tc.expectedErr, err) + }) + } +} + +func TestUploadPack_successful(t *testing.T) { + t.Parallel() + + for _, withSidechannel := range []bool{true, false} { + t.Run(fmt.Sprintf("sidechannel=%v", withSidechannel), func(t *testing.T) { + runTestWithAndWithoutConfigOptions(t, func(t *testing.T, opts ...testcfg.Option) { + testUploadPackSuccessful(t, withSidechannel, opts...) + }) + }) + } +} + +func testUploadPackSuccessful(t *testing.T, sidechannel bool, opts ...testcfg.Option) { + ctx := testhelper.Context(t) + + cfg := testcfg.Build(t, opts...) + + testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(t, cfg) + + negotiationMetrics := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"feature"}) + protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) + + cfg.SocketPath = runSSHServerWithOptions(t, cfg, []ServerOpt{ + WithPackfileNegotiationMetrics(negotiationMetrics), + }, testserver.WithGitCommandFactory(protocolDetectingFactory)) + + repo, repoPath := gittest.CreateRepository(ctx, t, cfg) + + smallBlobID := gittest.WriteBlob(t, cfg, repoPath, []byte("foobar")) + largeBlobID := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("1"), 2048)) + + // We set up the commits so that HEAD does not reference the above two blobs. If it did we'd + // fetch the blobs regardless of `--filter=blob:limit`. + rootCommitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "small", Mode: "100644", OID: smallBlobID}, + gittest.TreeEntry{Path: "large", Mode: "100644", OID: largeBlobID}, + )) + gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(rootCommitID), gittest.WithBranch("main"), gittest.WithTreeEntries( + gittest.TreeEntry{Path: "unrelated", Mode: "100644", Content: "something"}, + )) + gittest.WriteTag(t, cfg, repoPath, "v1.0.0", rootCommitID.Revision()) + + for _, tc := range []struct { + desc string + request *gitalypb.SSHUploadPackRequest + cloneFlags []git.Option + deepen float64 + verify func(t *testing.T, localRepoPath string) + expectedProtocol string + }{ + { + desc: "full clone", + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + }, + }, + { + desc: "full clone with protocol v2", + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + expectedProtocol: git.ProtocolV2, + }, + { + desc: "shallow clone", + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + }, + cloneFlags: []git.Option{ + git.ValueFlag{Name: "--depth", Value: "1"}, + }, + deepen: 1, + }, + { + desc: "shallow clone with protocol v2", + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + GitProtocol: git.ProtocolV2, + }, + cloneFlags: []git.Option{ + git.ValueFlag{Name: "--depth", Value: "1"}, + }, + deepen: 1, + expectedProtocol: git.ProtocolV2, + }, + { + desc: "partial clone", + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + }, + cloneFlags: []git.Option{ + git.ValueFlag{Name: "--filter", Value: "blob:limit=1024"}, + }, + verify: func(t *testing.T, repoPath string) { + gittest.RequireObjectNotExists(t, cfg, repoPath, largeBlobID) + gittest.RequireObjectExists(t, cfg, repoPath, smallBlobID) + }, + }, + { + desc: "hidden tags", + cloneFlags: []git.Option{ + git.Flag{Name: "--mirror"}, + }, + request: &gitalypb.SSHUploadPackRequest{ + Repository: repo, + GitConfigOptions: []string{ + "transfer.hideRefs=refs/tags", + }, + }, + verify: func(t *testing.T, localRepoPath string) { + // Assert that there is at least one tag that should've been cloned + // if refs weren't hidden as expected + require.NotEmpty(t, gittest.Exec(t, cfg, "-C", repoPath, "tag")) + + // And then verify that we did indeed hide tags as expected, which + // is demonstrated by not having fetched any tags. + require.Empty(t, gittest.Exec(t, cfg, "-C", localRepoPath, "tag")) + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + localRepoPath := testhelper.TempDir(t) + + negotiationMetrics.Reset() + protocolDetectingFactory.Reset(t) + + require.NoError(t, runClone(ctx, t, cfg, sidechannel, git.SubCmd{ + Name: "clone", + Args: []string{"git@localhost:test/test.git", localRepoPath}, + Flags: tc.cloneFlags, + }, tc.request)) + + requireRevisionsEqual(t, cfg, repoPath, localRepoPath, "refs/heads/main") + + metric, err := negotiationMetrics.GetMetricWithLabelValues("deepen") + require.NoError(t, err) + require.Equal(t, tc.deepen, promtest.ToFloat64(metric)) + + if tc.verify != nil { + tc.verify(t, localRepoPath) + } + + protocol := protocolDetectingFactory.ReadProtocol(t) + if tc.expectedProtocol != "" { + require.Contains(t, protocol, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) + } else { + require.Empty(t, protocol) + } + }) + } +} + +func TestUploadPack_packObjectsHook(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + cfg := testcfg.Build(t, testcfg.WithPackObjectsCacheEnabled()) + + filterDir := testhelper.TempDir(t) + outputPath := filepath.Join(filterDir, "output") + cfg.BinDir = filterDir + + testcfg.BuildGitalySSH(t, cfg) + + // We're using a custom pack-objects hook for git-upload-pack. In order + // to assure that it's getting executed as expected, we're writing a + // custom script which replaces the hook binary. It doesn't do anything + // special, but writes an error message and errors out and should thus + // cause the clone to fail with this error message. + testhelper.WriteExecutable(t, cfg.BinaryPath("gitaly-hooks"), []byte(fmt.Sprintf( + `#!/bin/bash + set -eo pipefail + echo 'I was invoked' >'%s' + shift + exec git "$@" + `, outputPath))) + + cfg.SocketPath = runSSHServer(t, cfg) + + repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + localRepoPath := testhelper.TempDir(t) + + err := runClone(ctx, t, cfg, false, git.SubCmd{ + Name: "clone", Args: []string{"git@localhost:test/test.git", localRepoPath}, + }, &gitalypb.SSHUploadPackRequest{ + Repository: repo, + }) + require.NoError(t, err) + + require.Equal(t, []byte("I was invoked\n"), testhelper.MustReadFile(t, outputPath)) +} + +func TestUploadPack_withoutSideband(t *testing.T) { + t.Parallel() + + runTestWithAndWithoutConfigOptions(t, testUploadPackWithoutSideband, testcfg.WithPackObjectsCacheEnabled()) +} + +func testUploadPackWithoutSideband(t *testing.T, opts ...testcfg.Option) { + cfg := testcfg.Build(t, opts...) + + testcfg.BuildGitalySSH(t, cfg) + testcfg.BuildGitalyHooks(t, cfg) + + cfg.SocketPath = runSSHServer(t, cfg) + + repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + // While Git knows the side-band-64 capability, some other clients don't. There is no way + // though to have Git not use that capability, so we're instead manually crafting a packfile + // negotiation without that capability and send it along. + negotiation := bytes.NewBuffer([]byte{}) + gittest.WritePktlineString(t, negotiation, "want 1e292f8fedd741b75372e19097c76d327140c312 multi_ack_detailed thin-pack include-tag ofs-delta agent=git/2.29.1") + gittest.WritePktlineString(t, negotiation, "want 1e292f8fedd741b75372e19097c76d327140c312") + gittest.WritePktlineFlush(t, negotiation) + gittest.WritePktlineString(t, negotiation, "done") + + request := &gitalypb.SSHUploadPackRequest{ + Repository: repo, + } + payload, err := protojson.Marshal(request) + require.NoError(t, err) + + // As we're not using the sideband, the remote process will write both to stdout and stderr. + // Those simultaneous writes to both stdout and stderr created a race as we could've invoked + // two concurrent `SendMsg`s on the gRPC stream. And given that `SendMsg` is not thread-safe + // a deadlock would result. + uploadPack := exec.Command(cfg.BinaryPath("gitaly-ssh"), "upload-pack", "dontcare", "dontcare") + uploadPack.Env = []string{ + fmt.Sprintf("GITALY_ADDRESS=%s", cfg.SocketPath), + fmt.Sprintf("GITALY_PAYLOAD=%s", payload), + } + uploadPack.Stdin = negotiation + + out, err := uploadPack.CombinedOutput() + require.NoError(t, err) + require.True(t, uploadPack.ProcessState.Success()) + require.Contains(t, string(out), "refs/heads/master") + require.Contains(t, string(out), "Counting objects") + require.Contains(t, string(out), "PACK") +} + +func TestUploadPack_invalidStorage(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) + + testcfg.BuildGitalySSH(t, cfg) + + repo, _ := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + localRepoPath := testhelper.TempDir(t) + + err := runClone(ctx, t, cfg, false, git.SubCmd{ + Name: "clone", + Args: []string{ + "git@localhost:test/test.git", localRepoPath, + }, + }, &gitalypb.SSHUploadPackRequest{ + Repository: &gitalypb.Repository{ + StorageName: "foobar", + RelativePath: repo.GetRelativePath(), + }, + }) + require.Error(t, err) + + if testhelper.IsPraefectEnabled() { + require.Contains(t, err.Error(), "rpc error: code = InvalidArgument desc = repo scoped: invalid Repository") + } else { + require.Contains(t, err.Error(), "rpc error: code = InvalidArgument desc = GetStorageByName: no such storage: \\\"foobar\\\"") + } +} + +func TestUploadPack_gitFailure(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + cfg.SocketPath = runSSHServer(t, cfg) + + repo, repoPath := gittest.CreateRepository(testhelper.Context(t), t, cfg, gittest.CreateRepositoryConfig{ + Seed: gittest.SeedGitLabTest, + }) + + client := newSSHClient(t, cfg.SocketPath) + + // Writing an invalid config will allow repo to pass the `IsGitDirectory` check but still + // trigger an error when git tries to access the repo. + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("Not a valid gitconfig"), 0o644)) + + stream, err := client.SSHUploadPack(ctx) + require.NoError(t, err) + require.NoError(t, stream.Send(&gitalypb.SSHUploadPackRequest{Repository: repo})) + require.NoError(t, stream.CloseSend()) + + err = recvUntilError(t, stream) + testhelper.RequireGrpcError(t, helper.ErrInternalf(`cmd wait: exit status 128, stderr: "fatal: bad config line 1 in file ./config\n"`), err) +} + +func recvUntilError(t *testing.T, stream gitalypb.SSHService_SSHUploadPackClient) error { + for { + response, err := stream.Recv() + require.Nil(t, response.GetStdout()) + if err != nil { + return err + } + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page.go index c3a6a0d24a..ef88be76f6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page.go @@ -3,9 +3,9 @@ package wiki import ( "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page_test.go index 2e00f66cf4..b1e59e295e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/find_page_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/find_page_test.go @@ -1,18 +1,18 @@ +//go:build !gitaly_test_sha256 + package wiki import ( - "fmt" "io" - "path/filepath" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -469,21 +469,16 @@ func testSuccessfulWikiFindPageRequestWithTrailers(t *testing.T, cfg config.Cfg, gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), - gittest.WithParents(), gittest.WithMessage("main branch, empty commit"), ) + // Include UTF-8 to ensure encoding is handled. page1Name := "Home Pagé" - createTestWikiPage(t, cfg, client, wikiRepo, repoPath, createWikiPageOpts{title: page1Name}) - - gittest.AddWorktree(t, cfg, repoPath, "worktree") - worktreePath := filepath.Join(repoPath, "worktree") - gittest.Exec(t, cfg, "-C", worktreePath, "checkout", "main") - gittest.Exec(t, cfg, "-C", worktreePath, - // Include UTF-8 to ensure encoding is handled - "-c", fmt.Sprintf("user.name=%s", "Scróoge McDuck"), - "-c", fmt.Sprintf("user.email=%s", "scrooge@mcduck.com"), - "commit", "--amend", "-m", "Empty commit", "-s") + author := "Scróoge McDuck" + createTestWikiPage(t, cfg, client, wikiRepo, repoPath, createWikiPageOpts{ + title: page1Name, + authorName: author, + }) request := &gitalypb.WikiFindPageRequest{ Repository: wikiRepo, @@ -496,6 +491,7 @@ func testSuccessfulWikiFindPageRequestWithTrailers(t *testing.T, cfg config.Cfg, receivedPage := readFullWikiPageFromWikiFindPageClient(t, c) require.Equal(t, page1Name, string(receivedPage.Name)) - receivedContent := receivedPage.GetRawData() - require.NotNil(t, receivedContent) + require.NotNil(t, receivedPage.GetRawData()) + require.Equal(t, author, string(receivedPage.GetVersion().GetCommit().GetAuthor().GetName())) + require.Equal(t, author, string(receivedPage.GetVersion().GetCommit().GetCommitter().GetName())) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages.go index 17cbe8c947..22b26ce8c6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages.go @@ -1,8 +1,8 @@ package wiki import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) WikiGetAllPages(request *gitalypb.WikiGetAllPagesRequest, stream gitalypb.WikiService_WikiGetAllPagesServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages_test.go index 89df11d306..d2a376c41d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/get_all_pages_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/get_all_pages_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package wiki import ( @@ -5,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages.go index f2460b8374..314243c418 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages.go @@ -1,8 +1,8 @@ package wiki import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func (s *server) WikiListPages(request *gitalypb.WikiListPagesRequest, stream gitalypb.WikiService_WikiListPagesServer) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages_test.go index 805457a320..cbe8277724 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/list_pages_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/list_pages_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package wiki import ( @@ -5,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func testSuccessfulWikiListPagesRequest(t *testing.T, cfg config.Cfg, client gitalypb.WikiServiceClient, rubySrv *rubyserver.Server) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/server.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/server.go index 32719e25d4..20c82eb03e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/server.go @@ -1,9 +1,9 @@ package wiki import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type server struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/testdata/clouds.png b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/testdata/clouds.png similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/testdata/clouds.png rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/testdata/clouds.png diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/testhelper_test.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/testhelper_test.go index 72f287c628..0dda852a75 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/testhelper_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package wiki import ( @@ -8,19 +10,20 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) type createWikiPageOpts struct { @@ -28,6 +31,7 @@ type createWikiPageOpts struct { content []byte format string forceContentEmpty bool + authorName string } var mockPageContent = bytes.Repeat([]byte("Mock wiki page content"), 10000) @@ -69,13 +73,12 @@ func TestWithRubySidecar(t *testing.T) { } } -func setupWikiService(t testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server) (gitalypb.WikiServiceClient, string) { - addr := testserver.RunGitalyServer(t, cfg, rubySrv, func(srv *grpc.Server, deps *service.Dependencies) { +func setupWikiService(tb testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server) (gitalypb.WikiServiceClient, string) { + addr := testserver.RunGitalyServer(tb, cfg, rubySrv, func(srv *grpc.Server, deps *service.Dependencies) { gitalypb.RegisterHookServiceServer(srv, hook.NewServer( deps.GetHookManager(), deps.GetGitCmdFactory(), - deps.GetPackObjectsCache(), - )) + deps.GetPackObjectsCache(), deps.GetPackObjectsConcurrencyTracker())) gitalypb.RegisterWikiServiceServer(srv, NewServer(deps.GetRubyServer(), deps.GetLocator())) gitalypb.RegisterRepositoryServiceServer(srv, repository.NewServer( cfg, @@ -89,17 +92,17 @@ func setupWikiService(t testing.TB, cfg config.Cfg, rubySrv *rubyserver.Server) deps.GetHousekeepingManager(), )) }) - testcfg.BuildGitalyHooks(t, cfg) - client := newWikiClient(t, addr) + testcfg.BuildGitalyHooks(tb, cfg) + client := newWikiClient(tb, addr) return client, addr } -func newWikiClient(t testing.TB, serverSocketPath string) gitalypb.WikiServiceClient { - t.Helper() +func newWikiClient(tb testing.TB, serverSocketPath string) gitalypb.WikiServiceClient { + tb.Helper() - conn, err := grpc.Dial(serverSocketPath, grpc.WithInsecure()) - require.NoError(t, err) - t.Cleanup(func() { conn.Close() }) + conn, err := grpc.Dial(serverSocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(tb, err) + tb.Cleanup(func() { conn.Close() }) return gitalypb.NewWikiServiceClient(conn) } @@ -120,8 +123,13 @@ func writeWikiPage(t *testing.T, client gitalypb.WikiServiceClient, wikiRepo *gi format = opts.format } + authorName := opts.authorName + if authorName == "" { + authorName = "Ahmad Sherif" + } + commitDetails := &gitalypb.WikiCommitDetails{ - Name: []byte("Ahmad Sherif"), + Name: []byte(authorName), Email: []byte("ahmad@gitlab.com"), Message: []byte("Add " + opts.title), UserId: int32(1), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page.go index 1db771b91e..8849a477aa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page.go @@ -3,8 +3,8 @@ package wiki import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page_test.go index f62ea65316..d3a64350f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/update_page_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/update_page_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package wiki import ( @@ -5,13 +7,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/util.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/util.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/util.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/util.go index 7c86f07aee..d9786040f1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/util.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/util.go @@ -3,7 +3,7 @@ package wiki import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type requestWithCommitDetails interface { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page.go index d851ce1021..db1318e2b7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page.go @@ -3,8 +3,8 @@ package wiki import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page_test.go index 8a46f50cb8..c7ebd049ce 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/wiki/write_page_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/wiki/write_page_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package wiki import ( @@ -5,14 +7,14 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator.go index a7d5f60dae..acc41013ff 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // Locator allows to get info about location of the repository or storage at the local file system. @@ -34,7 +34,7 @@ type Locator interface { StateDir(storageName string) (string, error) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. var ErrRelativePathEscapesRoot = errors.New("relative path escapes root directory") // ValidateRelativePath validates a relative path by joining it with rootDir and verifying the result diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator_test.go index 80e53d131d..1f53770e38 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/locator_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/locator_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package storage import ( @@ -5,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestValidateRelativePath(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata.go index 8368d93e7a..1af49493ca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata.go @@ -6,7 +6,7 @@ import ( "path/filepath" "github.com/google/uuid" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata_test.go index 6284805926..52f4ea8d41 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/metadata_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/metadata_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package storage import ( @@ -8,7 +10,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func readFilesystemID(t *testing.T, path string) string { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/servers.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/servers.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/servers.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/servers.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/servers_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/servers_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/servers_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/servers_test.go index 11373d2e9c..6aa0034471 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/servers_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/servers_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package storage_test import ( @@ -8,8 +10,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/testdata/.gitaly-metadata b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/testdata/.gitaly-metadata similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/testdata/.gitaly-metadata rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/testdata/.gitaly-metadata diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/testhelper_test.go index 61b45bdb5b..c4cb43fbe4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package storage import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager.go index d7e2a09931..1a80bd4347 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager.go @@ -9,12 +9,13 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) const ( @@ -66,7 +67,11 @@ type PoolManager struct { func NewManager(cfg config.Cfg, backchannels *backchannel.Registry) *PoolManager { return &PoolManager{ backchannels: backchannels, - conns: client.NewPoolWithOptions(client.WithDialOptions(client.FailOnNonTempDialError()...)), + conns: client.NewPoolWithOptions(client.WithDialOptions(append( + client.FailOnNonTempDialError(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor())..., + )), votingDelayMetric: prometheus.NewHistogram( prometheus.HistogramOpts{ Name: "gitaly_hook_transaction_voting_delay_seconds", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager_test.go index 4d6536c50c..8bc3661379 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/manager_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/manager_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package transaction_test import ( @@ -6,17 +8,17 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/mock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/mock.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/mock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/mock.go index 10ad6efdf0..4eccbbcb35 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/mock.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/mock.go @@ -5,8 +5,8 @@ import ( "errors" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) // MockManager is a mock Manager for use in tests. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/testhelper_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/testhelper_test.go index 3e17bd91e3..df233a9dc1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package transaction import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting.go index d5ed0683f1..09e6000d65 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting.go @@ -7,9 +7,9 @@ import ( "io" "os" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) // RunOnContext runs the given function if the context identifies a transaction. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting_test.go index fe4ada9260..20b1f6f81a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction/voting_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction/voting_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package transaction import ( @@ -8,11 +10,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" "google.golang.org/grpc/peer" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/client.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/client.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/gitlabnet.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/gitlabnet.go new file mode 100644 index 0000000000..da4da1c930 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/gitlabnet.go @@ -0,0 +1,192 @@ +package client + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + "time" + + "github.com/golang-jwt/jwt/v4" + "gitlab.com/gitlab-org/labkit/log" +) + +const ( + internalAPIPath = "/api/v4/internal" + secretHeaderName = "Gitlab-Shared-Secret" + apiSecretHeaderName = "Gitlab-Shell-Api-Request" + defaultUserAgent = "GitLab-Shell" + jwtTTL = time.Minute + jwtIssuer = "gitlab-shell" +) + +type ErrorResponse struct { + Message string `json:"message"` +} + +type GitlabNetClient struct { + httpClient *HTTPClient + user string + password string + secret string + userAgent string +} + +type APIError struct { + Msg string +} + +// OriginalRemoteIPContextKey is to be used as the key in a Context +// to set an X-Forwarded-For header in a request +type OriginalRemoteIPContextKey struct{} + +func (e *APIError) Error() string { + return e.Msg +} + +func NewGitlabNetClient( + user, + password, + secret string, + httpClient *HTTPClient, +) (*GitlabNetClient, error) { + if httpClient == nil { + return nil, fmt.Errorf("unsupported protocol") + } + + return &GitlabNetClient{ + httpClient: httpClient, + user: user, + password: password, + secret: secret, + userAgent: defaultUserAgent, + }, nil +} + +// SetUserAgent overrides the default user agent for the User-Agent header field +// for subsequent requests for the GitlabNetClient +func (c *GitlabNetClient) SetUserAgent(ua string) { + c.userAgent = ua +} + +func normalizePath(path string) string { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + + if !strings.HasPrefix(path, internalAPIPath) { + path = internalAPIPath + path + } + return path +} + +func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { + var jsonReader io.Reader + if data != nil { + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + + jsonReader = bytes.NewReader(jsonData) + } + + request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) + if err != nil { + return nil, err + } + + return request, nil +} + +func parseError(resp *http.Response) error { + if resp.StatusCode >= 200 && resp.StatusCode <= 399 { + return nil + } + defer resp.Body.Close() + parsedResponse := &ErrorResponse{} + + if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { + return &APIError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)} + } else { + return &APIError{parsedResponse.Message} + } +} + +func (c *GitlabNetClient) Get(ctx context.Context, path string) (*http.Response, error) { + return c.DoRequest(ctx, http.MethodGet, normalizePath(path), nil) +} + +func (c *GitlabNetClient) Post(ctx context.Context, path string, data interface{}) (*http.Response, error) { + return c.DoRequest(ctx, http.MethodPost, normalizePath(path), data) +} + +func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) { + request, err := newRequest(ctx, method, c.httpClient.Host, path, data) + if err != nil { + return nil, err + } + + user, password := c.user, c.password + if user != "" && password != "" { + request.SetBasicAuth(user, password) + } + secretBytes := []byte(c.secret) + + encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) + request.Header.Set(secretHeaderName, encodedSecret) + + claims := jwt.RegisteredClaims{ + Issuer: jwtIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), + } + tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) + if err != nil { + return nil, err + } + request.Header.Set(apiSecretHeaderName, tokenString) + + originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string) + if ok { + request.Header.Add("X-Forwarded-For", originalRemoteIP) + } + + request.Header.Add("Content-Type", "application/json") + request.Header.Add("User-Agent", c.userAgent) + request.Close = true + + start := time.Now() + response, err := c.httpClient.Do(request) + fields := log.Fields{ + "method": method, + "url": request.URL.String(), + "duration_ms": time.Since(start) / time.Millisecond, + } + logger := log.WithContextFields(ctx, fields) + + if err != nil { + logger.WithError(err).Error("Internal API unreachable") + return nil, &APIError{"Internal API unreachable"} + } + + if response != nil { + logger = logger.WithField("status", response.StatusCode) + } + if err := parseError(response); err != nil { + logger.WithError(err).Error("Internal API error") + return nil, err + } + + if response.ContentLength >= 0 { + logger = logger.WithField("content_length_bytes", response.ContentLength) + } + + logger.Info("Finished HTTP request") + + return response, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/httpclient.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/httpclient.go new file mode 100644 index 0000000000..dcf83b8c1d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client/httpclient.go @@ -0,0 +1,188 @@ +package client + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "strings" + "time" + + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/tracing" +) + +const ( + socketBaseURL = "http://unix" + unixSocketProtocol = "http+unix://" + httpProtocol = "http://" + httpsProtocol = "https://" + defaultReadTimeoutSeconds = 300 +) + +var ErrCafileNotFound = errors.New("cafile not found") + +type HTTPClient struct { + *http.Client + Host string +} + +type httpClientCfg struct { + keyPath, certPath string + caFile, caPath string +} + +func (hcc httpClientCfg) HaveCertAndKey() bool { return hcc.keyPath != "" && hcc.certPath != "" } + +// HTTPClientOpt provides options for configuring an HttpClient +type HTTPClientOpt func(*httpClientCfg) + +// WithClientCert will configure the HttpClient to provide client certificates +// when connecting to a server. +func WithClientCert(certPath, keyPath string) HTTPClientOpt { + return func(hcc *httpClientCfg) { + hcc.keyPath = keyPath + hcc.certPath = certPath + } +} + +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + +// NewHTTPClientWithOpts builds an HTTP client using the provided options +func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HTTPClient, error) { + var transport *http.Transport + var host string + var err error + if strings.HasPrefix(gitlabURL, unixSocketProtocol) { + transport, host = buildSocketTransport(gitlabURL, gitlabRelativeURLRoot) + } else if strings.HasPrefix(gitlabURL, httpProtocol) { + transport, host = buildHTTPTransport(gitlabURL) + } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + err = validateCaFile(caFile) + if err != nil { + return nil, err + } + + hcc := &httpClientCfg{ + caFile: caFile, + caPath: caPath, + } + + for _, opt := range opts { + opt(hcc) + } + + transport, host, err = buildHTTPSTransport(*hcc, gitlabURL) + if err != nil { + return nil, err + } + } else { + return nil, errors.New("unknown GitLab URL prefix") + } + + c := &http.Client{ + Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)), + Timeout: readTimeout(readTimeoutSeconds), + } + + client := &HTTPClient{Client: c, Host: host} + + return client, nil +} + +func buildSocketTransport(gitlabURL, gitlabRelativeURLRoot string) (*http.Transport, string) { + socketPath := strings.TrimPrefix(gitlabURL, unixSocketProtocol) + + transport := &http.Transport{ + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + dialer := net.Dialer{} + return dialer.DialContext(ctx, "unix", socketPath) + }, + } + + host := socketBaseURL + gitlabRelativeURLRoot = strings.Trim(gitlabRelativeURLRoot, "/") + if gitlabRelativeURLRoot != "" { + host = host + "/" + gitlabRelativeURLRoot + } + + return transport, host +} + +func buildHTTPSTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) { + certPool, err := x509.SystemCertPool() + if err != nil { + certPool = x509.NewCertPool() + } + + if hcc.caFile != "" { + addCertToPool(certPool, hcc.caFile) + } + + if hcc.caPath != "" { + fis, _ := os.ReadDir(hcc.caPath) + for _, fi := range fis { + if fi.IsDir() { + continue + } + + addCertToPool(certPool, filepath.Join(hcc.caPath, fi.Name())) + } + } + tlsConfig := &tls.Config{ + RootCAs: certPool, + MinVersion: tls.VersionTLS12, + } + + if hcc.HaveCertAndKey() { + cert, err := tls.LoadX509KeyPair(hcc.certPath, hcc.keyPath) + if err != nil { + return nil, "", err + } + tlsConfig.Certificates = []tls.Certificate{cert} + } + + transport := &http.Transport{ + TLSClientConfig: tlsConfig, + } + + return transport, gitlabURL, err +} + +func addCertToPool(certPool *x509.CertPool, fileName string) { + cert, err := os.ReadFile(fileName) + if err == nil { + certPool.AppendCertsFromPEM(cert) + } +} + +func buildHTTPTransport(gitlabURL string) (*http.Transport, string) { + return &http.Transport{}, gitlabURL +} + +func readTimeout(timeoutSeconds uint64) time.Duration { + if timeoutSeconds == 0 { + timeoutSeconds = defaultReadTimeoutSeconds + } + + return time.Duration(timeoutSeconds) * time.Second +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client.go index 9193654531..2f02a3d3f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client.go @@ -14,11 +14,11 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - gitalycfgprom "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + gitalycfgprom "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" ) var glIDRegex = regexp.MustCompile(`\A[0-9]+\z`) @@ -52,7 +52,6 @@ func NewHTTPClient( gitlabCfg.RelativeURLRoot, gitlabCfg.HTTPSettings.CAFile, gitlabCfg.HTTPSettings.CAPath, - gitlabCfg.HTTPSettings.SelfSigned, uint64(gitlabCfg.HTTPSettings.ReadTimeout), opts, ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client_test.go index a2125baa90..4f6bf150ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/http_client_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/http_client_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package gitlab import ( @@ -9,12 +11,12 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/mock_client.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/mock_client.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/mock_client.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/mock_client.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/test_server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/test_server.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/test_server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/test_server.go index 7de3fc7ae4..b23e4b2519 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/test_server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/test_server.go @@ -17,7 +17,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) var changeLineRegex = regexp.MustCompile("^[a-f0-9]{40} [a-f0-9]{40} refs/[^ ]+$") @@ -25,12 +25,12 @@ var changeLineRegex = regexp.MustCompile("^[a-f0-9]{40} [a-f0-9]{40} refs/[^ ]+$ const secretHeaderName = "Gitlab-Shared-Secret" // WriteShellSecretFile writes a .gitlab_shell_secret file in the specified directory -func WriteShellSecretFile(t testing.TB, dir, secretToken string) string { - t.Helper() +func WriteShellSecretFile(tb testing.TB, dir, secretToken string) string { + tb.Helper() - require.NoError(t, os.MkdirAll(dir, os.ModeDir)) + require.NoError(tb, os.MkdirAll(dir, os.ModeDir)) filePath := filepath.Join(dir, ".gitlab_shell_secret") - require.NoError(t, os.WriteFile(filePath, []byte(secretToken), 0o644)) + require.NoError(tb, os.WriteFile(filePath, []byte(secretToken), 0o644)) return filePath } @@ -60,27 +60,27 @@ type TestServerOptions struct { } // NewTestServer returns a mock gitlab server that responds to the hook api endpoints -func NewTestServer(t testing.TB, options TestServerOptions) (url string, cleanup func()) { - t.Helper() +func NewTestServer(tb testing.TB, options TestServerOptions) (url string, cleanup func()) { + tb.Helper() mux := http.NewServeMux() prefix := strings.TrimRight(options.RelativeURLRoot, "/") + "/api/v4/internal" - mux.Handle(prefix+"/allowed", http.HandlerFunc(handleAllowed(t, options))) - mux.Handle(prefix+"/pre_receive", http.HandlerFunc(handlePreReceive(t, options))) + mux.Handle(prefix+"/allowed", http.HandlerFunc(handleAllowed(tb, options))) + mux.Handle(prefix+"/pre_receive", http.HandlerFunc(handlePreReceive(tb, options))) mux.Handle(prefix+"/post_receive", http.HandlerFunc(handlePostReceive(options))) - mux.Handle(prefix+"/check", http.HandlerFunc(handleCheck(t, options))) - mux.Handle(prefix+"/lfs", http.HandlerFunc(handleLfs(t, options))) + mux.Handle(prefix+"/check", http.HandlerFunc(handleCheck(tb, options))) + mux.Handle(prefix+"/lfs", http.HandlerFunc(handleLfs(tb, options))) var tlsCfg *tls.Config if options.ClientCACertPath != "" { caCertPEM, err := os.ReadFile(options.ClientCACertPath) - require.NoError(t, err) + require.NoError(tb, err) certPool := x509.NewCertPool() - require.True(t, certPool.AppendCertsFromPEM(caCertPEM)) + require.True(tb, certPool.AppendCertsFromPEM(caCertPEM)) serverCert, err := tls.LoadX509KeyPair(options.ServerCertPath, options.ServerKeyPath) - require.NoError(t, err) + require.NoError(tb, err) tlsCfg = &tls.Config{ ClientCAs: certPool, @@ -91,7 +91,7 @@ func NewTestServer(t testing.TB, options TestServerOptions) (url string, cleanup } if options.UnixSocket { - return startSocketHTTPServer(t, mux, tlsCfg) + return startSocketHTTPServer(tb, mux, tlsCfg) } var server *httptest.Server @@ -137,7 +137,7 @@ func parsePostReceiveForm(u url.Values) postReceiveForm { } } -func handleAllowed(t testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { +func handleAllowed(tb testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "could not parse form", http.StatusBadRequest) @@ -260,7 +260,7 @@ func handleAllowed(t testing.TB, options TestServerOptions) func(w http.Response } if relObjectDir != gitVars.GitObjectDirRel { _, err := w.Write([]byte(`{"status":false}`)) - require.NoError(t, err) + require.NoError(tb, err) return } } @@ -280,7 +280,7 @@ func handleAllowed(t testing.TB, options TestServerOptions) func(w http.Response if relAltObjectDir != gitVars.GitAlternateObjectDirsRel[i] { _, err := w.Write([]byte(`{"status":false}`)) - require.NoError(t, err) + require.NoError(tb, err) return } } @@ -300,17 +300,17 @@ func handleAllowed(t testing.TB, options TestServerOptions) func(w http.Response if authenticated { _, err := w.Write([]byte(`{"status":true}`)) - require.NoError(t, err) + require.NoError(tb, err) return } w.WriteHeader(http.StatusUnauthorized) _, err = w.Write([]byte(`{"message":"401 Unauthorized\n"}`)) - require.NoError(t, err) + require.NoError(tb, err) } } -func handlePreReceive(t testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { +func handlePreReceive(tb testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "could not parse form", http.StatusBadRequest) @@ -387,7 +387,7 @@ func handlePreReceive(t testing.TB, options TestServerOptions) func(w http.Respo w.WriteHeader(http.StatusOK) _, err = w.Write([]byte(`{"reference_counter_increased": true}`)) - require.NoError(t, err) + require.NoError(tb, err) } } @@ -502,12 +502,12 @@ func handlePostReceive(options TestServerOptions) func(w http.ResponseWriter, r } } -func handleCheck(t testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { +func handleCheck(tb testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { u, p, ok := r.BasicAuth() if !ok || u != options.User || p != options.Password { w.WriteHeader(http.StatusUnauthorized) - require.NoError(t, json.NewEncoder(w).Encode(struct { + require.NoError(tb, json.NewEncoder(w).Encode(struct { Message string `json:"message"` }{Message: "authorization failed"})) return @@ -518,7 +518,7 @@ func handleCheck(t testing.TB, options TestServerOptions) func(w http.ResponseWr } } -func handleLfs(t testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { +func handleLfs(tb testing.TB, options TestServerOptions) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "couldn't parse form", http.StatusBadRequest) @@ -552,17 +552,17 @@ func handleLfs(t testing.TB, options TestServerOptions) func(w http.ResponseWrit if options.LfsBody != "" { _, err := w.Write([]byte(options.LfsBody)) - require.NoError(t, err) + require.NoError(tb, err) } } } -func startSocketHTTPServer(t testing.TB, mux *http.ServeMux, tlsCfg *tls.Config) (string, func()) { - tempDir := testhelper.TempDir(t) +func startSocketHTTPServer(tb testing.TB, mux *http.ServeMux, tlsCfg *tls.Config) (string, func()) { + tempDir := testhelper.TempDir(tb) filename := filepath.Join(tempDir, "http-test-server") socketListener, err := net.Listen("unix", filename) - require.NoError(t, err) + require.NoError(tb, err) server := http.Server{ Handler: mux, @@ -573,7 +573,7 @@ func startSocketHTTPServer(t testing.TB, mux *http.ServeMux, tlsCfg *tls.Config) url := "http+unix://" + filename cleanup := func() { - require.NoError(t, server.Close()) + require.NoError(tb, server.Close()) } return url, cleanup @@ -581,10 +581,10 @@ func startSocketHTTPServer(t testing.TB, mux *http.ServeMux, tlsCfg *tls.Config) // SetupAndStartGitlabServer creates a new GitlabTestServer, starts it and sets // up the gitlab-shell secret. -func SetupAndStartGitlabServer(t testing.TB, shellDir string, c *TestServerOptions) (string, func()) { - url, cleanup := NewTestServer(t, *c) +func SetupAndStartGitlabServer(tb testing.TB, shellDir string, c *TestServerOptions) (string, func()) { + url, cleanup := NewTestServer(tb, *c) - WriteShellSecretFile(t, shellDir, c.SecretToken) + WriteShellSecretFile(tb, shellDir, c.SecretToken) return url, cleanup } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testdata/certs/server.crt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testdata/certs/server.crt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testdata/certs/server.crt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testdata/certs/server.crt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testdata/certs/server.key b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testdata/certs/server.key similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testdata/certs/server.key rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testdata/certs/server.key diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testhelper_test.go index 69a859a864..ed10359529 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/gitlab/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/gitlab/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package gitlab import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/stats.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/stats.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/stats.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/stats_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/stats_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/stats_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/stats_test.go index 64171e33cc..d86dbb0384 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/stats_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/stats_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package grpcstats import ( @@ -5,7 +7,7 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc/stats" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/testhelper_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/testhelper_test.go index b41bdc29ea..bd4058b0bd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package grpcstats_test import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/byte.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/byte.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/byte.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/byte.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/chunker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/chunker.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/chunker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/chunker.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/chunker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/chunker_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/chunker_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/chunker_test.go index 2ef5f63eb9..ea759312e3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/chunker_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/chunker_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package chunk import ( @@ -6,9 +8,10 @@ import ( "testing" "github.com/stretchr/testify/require" - test "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + test "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -89,7 +92,7 @@ func runServer(t *testing.T, s *server, opt ...grpc.ServerOption) (*grpc.Server, func newClient(t *testing.T, serverSocketPath string) (test.TestClient, *grpc.ClientConn) { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.pb.go index 68affd44b8..46aa350072 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: helper/chunk/testdata/test.proto package testdata @@ -134,7 +134,7 @@ var file_helper_chunk_testdata_test_proto_rawDesc = []byte{ 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x2f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.proto similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.proto index 11952a3972..887cf202ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package test.chunk; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata"; service Test { rpc StreamOutput(StreamOutputRequest) returns (stream StreamOutputResponse) {} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test_grpc.pb.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test_grpc.pb.go index 8fb81eba7f..a337a4f37f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/chunk/testdata/test_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk/testdata/test_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: helper/chunk/testdata/test.proto package testdata diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/clock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/clock.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/clock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/clock.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/count.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/count.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/count.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/count.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration.go new file mode 100644 index 0000000000..5d1e5b87d1 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration.go @@ -0,0 +1,28 @@ +package duration + +import "time" + +// Duration is a trick to let our TOML library parse durations from strings. +type Duration time.Duration + +// Duration converts the duration.Duration to a time.Duration +func (d *Duration) Duration() time.Duration { + if d != nil { + return time.Duration(*d) + } + return 0 +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface +func (d *Duration) UnmarshalText(text []byte) error { + td, err := time.ParseDuration(string(text)) + if err == nil { + *d = Duration(td) + } + return err +} + +// MarshalText implements the encoding.TextMarshaler interface +func (d Duration) MarshalText() ([]byte, error) { + return []byte(time.Duration(d).String()), nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration_test.go new file mode 100644 index 0000000000..9ca1830dcc --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration/duration_test.go @@ -0,0 +1,15 @@ +package duration + +import ( + "encoding" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestDuration(t *testing.T) { + t.Parallel() + + require.Implements(t, (*encoding.TextMarshaler)(nil), new(Duration)) + require.Implements(t, (*encoding.TextUnmarshaler)(nil), new(Duration)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env.go index e8fb5c70bd..92173d335f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/env/env.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env.go @@ -65,3 +65,18 @@ func GetString(name string, fallback string) string { return strings.TrimSpace(value) } + +// ExtractValue returns the value of the environment variable with the given key. The given key +// should not have a trailing "=". If the same key occurrs multiple times in the environment, then +// any later occurrences will override previous ones. +func ExtractValue(environment []string, key string) string { + var value string + + for _, envvar := range environment { + if strings.HasPrefix(envvar, key+"=") { + value = strings.TrimPrefix(envvar, key+"=") + } + } + + return value +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env_test.go new file mode 100644 index 0000000000..f272ea9352 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/env_test.go @@ -0,0 +1,352 @@ +//go:build !gitaly_test_sha256 + +package env_test + +import ( + "fmt" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestGetBool(t *testing.T) { + const envvar = "TEST_BOOL" + + for _, tc := range []struct { + desc string + setup func(t *testing.T) + fallback bool + expectedValue bool + expectedErr error + }{ + { + desc: "explicitly true", + setup: setupEnv(envvar, "true"), + expectedValue: true, + }, + { + desc: "explicitly false", + setup: setupEnv(envvar, "false"), + expectedValue: false, + }, + { + desc: "explicitly 1", + setup: setupEnv(envvar, "1"), + expectedValue: true, + }, + { + desc: "explicitly 0", + setup: setupEnv(envvar, "0"), + expectedValue: false, + }, + { + desc: "missing value", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + expectedValue: false, + }, + { + desc: "missing value with fallback", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + fallback: true, + expectedValue: true, + }, + { + desc: "empty value", + setup: setupEnv(envvar, ""), + expectedValue: false, + }, + { + desc: "empty value with fallback", + setup: setupEnv(envvar, ""), + fallback: true, + expectedValue: true, + }, + { + desc: "invalid value", + setup: setupEnv(envvar, "bad"), + expectedValue: false, + expectedErr: fmt.Errorf("get bool TEST_BOOL: %w", &strconv.NumError{ + Func: "ParseBool", + Num: "bad", + Err: strconv.ErrSyntax, + }), + }, + { + desc: "invalid value with fallback", + setup: setupEnv(envvar, "bad"), + fallback: true, + expectedValue: true, + expectedErr: fmt.Errorf("get bool TEST_BOOL: %w", &strconv.NumError{ + Func: "ParseBool", + Num: "bad", + Err: strconv.ErrSyntax, + }), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tc.setup(t) + + value, err := env.GetBool(envvar, tc.fallback) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedValue, value) + }) + } +} + +func TestGetInt(t *testing.T) { + const envvar = "TEST_INT" + + for _, tc := range []struct { + desc string + setup func(t *testing.T) + fallback int + expectedValue int + expectedErr error + }{ + { + desc: "valid number", + setup: setupEnv(envvar, "3"), + expectedValue: 3, + }, + { + desc: "unset value", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + expectedValue: 0, + }, + { + desc: "unset value with fallback", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + fallback: 3, + expectedValue: 3, + }, + { + desc: "empty value", + setup: setupEnv(envvar, ""), + expectedValue: 0, + }, + { + desc: "empty value with fallback", + setup: setupEnv(envvar, ""), + fallback: 3, + expectedValue: 3, + }, + { + desc: "invalid value", + setup: setupEnv(envvar, "bad"), + expectedValue: 0, + expectedErr: fmt.Errorf("get int TEST_INT: %w", &strconv.NumError{ + Func: "Atoi", + Num: "bad", + Err: strconv.ErrSyntax, + }), + }, + { + desc: "invalid value with fallback", + setup: setupEnv(envvar, "bad"), + fallback: 3, + expectedValue: 3, + expectedErr: fmt.Errorf("get int TEST_INT: %w", &strconv.NumError{ + Func: "Atoi", + Num: "bad", + Err: strconv.ErrSyntax, + }), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tc.setup(t) + + value, err := env.GetInt(envvar, tc.fallback) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedValue, value) + }) + } +} + +func TestGetDuration(t *testing.T) { + const envvar = "TEST_DURATION" + + for _, tc := range []struct { + desc string + setup func(t *testing.T) + fallback time.Duration + expectedValue time.Duration + expectedErr error + }{ + { + desc: "valid duration", + setup: setupEnv(envvar, "3m"), + fallback: 0, + expectedValue: 3 * time.Minute, + }, + { + desc: "unset value", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + expectedValue: 0, + }, + { + desc: "unset value with fallback", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + fallback: 3, + expectedValue: 3, + }, + { + desc: "empty value", + setup: setupEnv(envvar, ""), + expectedValue: 0, + }, + { + desc: "empty value with fallback", + setup: setupEnv(envvar, ""), + fallback: 3, + expectedValue: 3, + }, + { + desc: "invalid value", + setup: setupEnv(envvar, "bad"), + expectedValue: 0, + expectedErr: fmt.Errorf("get duration TEST_DURATION: %w", fmt.Errorf("time: invalid duration \"bad\"")), + }, + { + desc: "invalid value with fallback", + setup: setupEnv(envvar, "bad"), + fallback: 3, + expectedValue: 3, + expectedErr: fmt.Errorf("get duration TEST_DURATION: %w", fmt.Errorf("time: invalid duration \"bad\"")), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tc.setup(t) + + value, err := env.GetDuration(envvar, tc.fallback) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedValue, value) + }) + } +} + +func TestGetString(t *testing.T) { + const envvar = "TEST_STRING" + + for _, tc := range []struct { + desc string + setup func(t *testing.T) + fallback string + expectedValue string + }{ + { + desc: "simple string", + setup: setupEnv(envvar, "Hello"), + expectedValue: "Hello", + }, + { + desc: "string with trailing whitespace", + setup: setupEnv(envvar, "hello "), + expectedValue: "hello", + }, + { + desc: "unset value", + setup: func(t *testing.T) { + testhelper.Unsetenv(t, envvar) + }, + fallback: "fallback value", + expectedValue: "fallback value", + }, + { + desc: "empty value", + setup: setupEnv(envvar, ""), + fallback: "fallback value", + expectedValue: "fallback value", + }, + { + desc: "whitespace only", + setup: setupEnv(envvar, " "), + fallback: "fallback value", + expectedValue: "", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tc.setup(t) + + value := env.GetString(envvar, tc.fallback) + require.Equal(t, tc.expectedValue, value) + }) + } +} + +func TestExtractKey(t *testing.T) { + for _, tc := range []struct { + desc string + environment []string + key string + expectedValue string + }{ + { + desc: "nil", + environment: nil, + key: "something", + expectedValue: "", + }, + { + desc: "found", + environment: []string{ + "FOO=bar", + "BAR=qux", + }, + key: "BAR", + expectedValue: "qux", + }, + { + desc: "found with multiple matches", + environment: []string{ + "FOO=1", + "FOO=2", + }, + key: "FOO", + expectedValue: "2", + }, + { + desc: "not found", + environment: []string{ + "FOO=bar", + "BAR=qux", + }, + key: "doesnotexist", + expectedValue: "", + }, + { + desc: "prefix-match", + environment: []string{ + "FOObar=value", + }, + key: "FOO", + expectedValue: "", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + value := env.ExtractValue(tc.environment, tc.key) + require.Equal(t, tc.expectedValue, value) + }) + } +} + +func setupEnv(key, value string) func(t *testing.T) { + return func(t *testing.T) { + t.Setenv(key, value) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby.go new file mode 100644 index 0000000000..5f585238e6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby.go @@ -0,0 +1,22 @@ +package env + +import "strings" + +// AllowedRubyEnvironment filters the given set of environment variables and returns only those +// which are allowed when executing Ruby commands. +func AllowedRubyEnvironment(environmentVariables []string) []string { + var filteredEnv []string + for _, environmentVariable := range environmentVariables { + for _, prefix := range []string{ + "BUNDLE_PATH=", + "BUNDLE_APP_CONFIG=", + "BUNDLE_USER_CONFIG=", + "GEM_HOME=", + } { + if strings.HasPrefix(environmentVariable, prefix) { + filteredEnv = append(filteredEnv, environmentVariable) + } + } + } + return filteredEnv +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby_test.go new file mode 100644 index 0000000000..a0ecc10355 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/env/ruby_test.go @@ -0,0 +1,99 @@ +//go:build !gitaly_test_sha256 + +package env + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAllowedRubyEnvironment(t *testing.T) { + for _, tc := range []struct { + desc string + input []string + expected []string + }{ + { + desc: "empty", + }, + { + desc: "unrelated env", + input: []string{ + "FOO=bar", + "BAR=baz", + }, + }, + { + desc: "allowed envvars", + input: []string{ + "BUNDLE_PATH=a", + "BUNDLE_APP_CONFIG=b", + "BUNDLE_USER_CONFIG=c", + "GEM_HOME=y", + }, + expected: []string{ + "BUNDLE_PATH=a", + "BUNDLE_APP_CONFIG=b", + "BUNDLE_USER_CONFIG=c", + "GEM_HOME=y", + }, + }, + { + desc: "mixed", + input: []string{ + "FOO=bar", + "BUNDLE_PATH=a", + "FOO=bar", + "BUNDLE_APP_CONFIG=b", + "FOO=bar", + "BUNDLE_USER_CONFIG=c", + "FOO=bar", + "GEM_HOME=d", + "FOO=bar", + }, + expected: []string{ + "BUNDLE_PATH=a", + "BUNDLE_APP_CONFIG=b", + "BUNDLE_USER_CONFIG=c", + "GEM_HOME=d", + }, + }, + { + desc: "almost-prefixes", + input: []string{ + "BUNDLE_PATHx=a", + "BUNDLE_APP_CONFIGx=b", + "BUNDLE_USER_CONFIGx=c", + "GEM_HOMEx=d", + }, + }, + { + desc: "duplicate entries", + input: []string{ + "GEM_HOME=first", + "BUNDLE_APP_CONFIG=first", + "BUNDLE_USER_CONFIG=first", + "BUNDLE_PATH=first", + "BUNDLE_PATH=second", + "BUNDLE_USER_CONFIG=second", + "BUNDLE_APP_CONFIG=second", + "GEM_HOME=second", + }, + expected: []string{ + "GEM_HOME=first", + "BUNDLE_APP_CONFIG=first", + "BUNDLE_USER_CONFIG=first", + "BUNDLE_PATH=first", + "BUNDLE_PATH=second", + "BUNDLE_USER_CONFIG=second", + "BUNDLE_APP_CONFIG=second", + "GEM_HOME=second", + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.expected, AllowedRubyEnvironment(tc.input)) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error.go index 5196513e0a..dd3e17f080 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error.go @@ -26,6 +26,9 @@ func (sw statusWrapper) Unwrap() error { // ErrCanceled wraps err with codes.Canceled, unless err is already a gRPC error. func ErrCanceled(err error) error { return wrapError(codes.Canceled, err) } +// ErrDeadlineExceeded wraps err with codes.DeadlineExceeded, unless err is already a gRPC error. +func ErrDeadlineExceeded(err error) error { return wrapError(codes.DeadlineExceeded, err) } + // ErrInternal wraps err with codes.Internal, unless err is already a gRPC error. func ErrInternal(err error) error { return wrapError(codes.Internal, err) } @@ -60,6 +63,18 @@ func wrapError(code codes.Code, err error) error { return err } +// ErrCanceledf wraps a formatted error with codes.Canceled, unless the formatted error is a +// wrapped gRPC error. +func ErrCanceledf(format string, a ...interface{}) error { + return formatError(codes.Canceled, format, a...) +} + +// ErrDeadlineExceededf wraps a formatted error with codes.DeadlineExceeded, unless the formatted +// error is a wrapped gRPC error. +func ErrDeadlineExceededf(format string, a ...interface{}) error { + return formatError(codes.DeadlineExceeded, format, a...) +} + // ErrInternalf wraps a formatted error with codes.Internal, unless the formatted error is a // wrapped gRPC error. func ErrInternalf(format string, a ...interface{}) error { @@ -108,11 +123,47 @@ func ErrAbortedf(format string, a ...interface{}) error { return formatError(codes.Aborted, format, a...) } +// grpcErrorMessageWrapper is used to wrap a gRPC `status.Status`-style error such that it behaves +// like a `status.Status`, except that it generates a readable error message. +type grpcErrorMessageWrapper struct { + *status.Status +} + +func (e grpcErrorMessageWrapper) GRPCStatus() *status.Status { + return e.Status +} + +func (e grpcErrorMessageWrapper) Error() string { + return e.Message() +} + +func (e grpcErrorMessageWrapper) Unwrap() error { + return e.Status.Err() +} + // formatError will create a new error from the given format string. If the error string contains a // %w verb and its corresponding error has a gRPC error code, then the returned error will keep this // gRPC error code instead of using the one provided as an argument. func formatError(code codes.Code, format string, a ...interface{}) error { - err := fmt.Errorf(format, a...) + args := make([]interface{}, 0, len(a)) + for _, a := range a { + err, ok := a.(error) + if !ok { + args = append(args, a) + continue + } + + status, ok := status.FromError(err) + if !ok { + args = append(args, a) + continue + } + + // Wrap gRPC status errors so that the resulting error message stays readable. + args = append(args, grpcErrorMessageWrapper{status}) + } + + err := fmt.Errorf(format, args...) nestedCode := GrpcCode(errors.Unwrap(err)) if nestedCode != codes.OK && nestedCode != codes.Unknown { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error_test.go similarity index 53% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error_test.go index 3b07f15700..44df756cd0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/error_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/error_test.go @@ -1,14 +1,14 @@ +//go:build !gitaly_test_sha256 + package helper import ( "errors" - "fmt" - "strings" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -30,6 +30,11 @@ func TestError(t *testing.T) { errorf: ErrCanceled, code: codes.Canceled, }, + { + desc: "DeadlineExceeded", + errorf: ErrDeadlineExceeded, + code: codes.DeadlineExceeded, + }, { desc: "Internal", errorf: ErrInternal, @@ -92,90 +97,132 @@ func TestError(t *testing.T) { } } -func TestErrorF_withVFormat(t *testing.T) { - testErrorfFormat(t, "expected %v", "expected %v") -} - -func TestErrorF_withWFormat(t *testing.T) { - testErrorfFormat(t, "expected %w", "expected %s") -} - -func testErrorfFormat(t *testing.T, errorFormat, errorFormatEqual string) { - isFormatW := strings.Contains(errorFormat, "%w") - errorMessage := "sentinel error" - input := errors.New(errorMessage) - inputGRPCCode := codes.Unauthenticated - inputGRPC := status.Error(inputGRPCCode, errorMessage) - inputGRPCFmt := status.Errorf(inputGRPCCode, errorFormat, errorMessage) - +func TestErrorf(t *testing.T) { for _, tc := range []struct { - desc string - errorf func(format string, a ...interface{}) error - code codes.Code + desc string + errorf func(format string, a ...interface{}) error + expectedCode codes.Code }{ { - desc: "Internalf", - errorf: ErrInternalf, - code: codes.Internal, + desc: "Canceledf", + errorf: ErrCanceledf, + expectedCode: codes.Canceled, }, { - desc: "InvalidArgumentf", - errorf: ErrInvalidArgumentf, - code: codes.InvalidArgument, + desc: "DeadlineExceededf", + errorf: ErrDeadlineExceededf, + expectedCode: codes.DeadlineExceeded, }, { - desc: "FailedPreconditionf", - errorf: ErrFailedPreconditionf, - code: codes.FailedPrecondition, + desc: "Internalf", + errorf: ErrInternalf, + expectedCode: codes.Internal, }, { - desc: "NotFoundf", - errorf: ErrNotFoundf, - code: codes.NotFound, + desc: "InvalidArgumentf", + errorf: ErrInvalidArgumentf, + expectedCode: codes.InvalidArgument, }, { - desc: "ErrUnavailablef", - errorf: ErrUnavailablef, - code: codes.Unavailable, + desc: "FailedPreconditionf", + errorf: ErrFailedPreconditionf, + expectedCode: codes.FailedPrecondition, }, { - desc: "ErrAbortedf", - errorf: ErrAbortedf, - code: codes.Aborted, + desc: "NotFoundf", + errorf: ErrNotFoundf, + expectedCode: codes.NotFound, + }, + { + desc: "ErrUnavailablef", + errorf: ErrUnavailablef, + expectedCode: codes.Unavailable, + }, + { + desc: "ErrAbortedf", + errorf: ErrAbortedf, + expectedCode: codes.Aborted, }, } { t.Run(tc.desc, func(t *testing.T) { - require.NotEqual(t, tc.code, inputGRPCCode, "canary test code and tc.code may not be the same") + t.Run("with non-gRPC error", func(t *testing.T) { + err := tc.errorf("top-level: %w", errors.New("nested")) + require.EqualError(t, err, "top-level: nested") + require.Equal(t, tc.expectedCode, status.Code(err)) - // When not re-throwing an error we get the GRPC error code corresponding to - // the function's name. Just like the non-f functions. - err := tc.errorf(errorFormat, input) - require.EqualError(t, err, fmt.Sprintf(errorFormatEqual, errorMessage)) - require.False(t, errors.Is(err, inputGRPC)) - require.Equal(t, tc.code, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(tc.expectedCode, "top-level: nested"), s) + }) - // When wrapping an existing gRPC error, then the error code will stay the - // same. - err = tc.errorf(errorFormat, inputGRPCFmt) - require.False(t, errors.Is(err, input)) - if isFormatW { - require.Equal(t, inputGRPCCode, status.Code(err)) - } else { - require.Equal(t, tc.code, status.Code(err)) - } - require.NotEqual(t, tc.code, status.Code(inputGRPC)) + t.Run("with status.Errorf error and %v", func(t *testing.T) { + require.NotEqual(t, tc.expectedCode, codes.Unauthenticated) - // The same as above, except that we test with an error returned by - // `status.Error()`. - errX := tc.errorf(errorFormat, inputGRPC) - require.Equal(t, errors.Is(errX, inputGRPC), isFormatW) // .True() for non-f - require.False(t, errors.Is(errX, input)) - if isFormatW { - require.Equal(t, inputGRPCCode, status.Code(errX)) - } else { - require.Equal(t, tc.code, status.Code(errX)) - } - require.Equal(t, inputGRPCCode, status.Code(inputGRPC)) + err := tc.errorf("top-level: %v", status.Errorf(codes.Unauthenticated, "deeply: %s", "nested")) + require.EqualError(t, err, "top-level: deeply: nested") + + // The error code of the nested error should be discarded. + require.Equal(t, tc.expectedCode, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(tc.expectedCode, "top-level: deeply: nested"), s) + }) + + t.Run("with status.Errorf error and %w", func(t *testing.T) { + require.NotEqual(t, tc.expectedCode, codes.Unauthenticated) + + err := tc.errorf("top-level: %w", status.Errorf(codes.Unauthenticated, "deeply: %s", "nested")) + require.EqualError(t, err, "top-level: deeply: nested") + + // We should be reporting the error code of the nested error. + require.Equal(t, codes.Unauthenticated, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(codes.Unauthenticated, "top-level: deeply: nested"), s) + }) + + t.Run("with status.Error error and %v", func(t *testing.T) { + require.NotEqual(t, tc.expectedCode, codes.Unauthenticated) + + err := tc.errorf("top-level: %v", status.Error(codes.Unauthenticated, "nested")) + require.EqualError(t, err, "top-level: nested") + + // The error code of the nested error should be discarded. + require.Equal(t, tc.expectedCode, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(tc.expectedCode, "top-level: nested"), s) + }) + + t.Run("with status.Error error and %w", func(t *testing.T) { + require.NotEqual(t, tc.expectedCode, codes.Unauthenticated) + + err := tc.errorf("top-level: %w", status.Error(codes.Unauthenticated, "nested")) + require.EqualError(t, err, "top-level: nested") + + // We should be reporting the error code of the nested error. + require.Equal(t, codes.Unauthenticated, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(codes.Unauthenticated, "top-level: nested"), s) + }) + + t.Run("multi-nesting gRPC errors", func(t *testing.T) { + require.NotEqual(t, tc.expectedCode, codes.Unauthenticated) + + err := tc.errorf("first: %w", + ErrInternalf("second: %w", + status.Error(codes.Unauthenticated, "third"), + ), + ) + require.EqualError(t, err, "first: second: third") + + // We should be reporting the error code of the nested error. + require.Equal(t, codes.Unauthenticated, status.Code(err)) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, status.New(codes.Unauthenticated, "first: second: third"), s) + }) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors/fieldextractor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors/fieldextractor.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors/fieldextractor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors/fieldextractor.go index 2729f93b8a..ae06955033 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors/fieldextractor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors/fieldextractor.go @@ -3,7 +3,7 @@ package fieldextractors import ( "strings" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) type repositoryBasedRequest interface { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_linux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_linux.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_linux.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_linux.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_openbsd.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_openbsd.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_openbsd.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_openbsd.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_unix.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_unix.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_unix.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_unix.go index d829857890..a7e39bf178 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/detect_unix.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/detect_unix.go @@ -1,5 +1,4 @@ //go:build darwin || dragonfly || freebsd -// +build darwin dragonfly freebsd package fstype diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/fstype.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/fstype.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/fstype.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/fstype.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/fstype_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/fstype_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/fstype_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/fstype_test.go index 9ac8b43d38..3a28d38ca5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/fstype/fstype_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype/fstype_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package fstype import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines/send.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines/send.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines/send.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines/send.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines/send_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines/send_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines/send_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines/send_test.go index 2824198732..cb17eca4a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/lines/send_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/lines/send_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package lines import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/message_size.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/message_size.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/message_size.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/message_size.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo.go index 4c0964110b..c10f0eaa46 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo.go @@ -1,7 +1,7 @@ package helper import ( - "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" ) // RepoPathEqual compares if two repositories are in the same location diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo_test.go index c656651316..16534e84ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/repo_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/repo_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package helper import ( "testing" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/security.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/security.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/security.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/security.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/security_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/security_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/security_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/security_test.go index 640e36b3b7..7c8b998500 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/security_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/security_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package helper import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/suppressed_context.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/suppressed_context.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/suppressed_context.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/suppressed_context.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/suppressed_context_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/suppressed_context_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/suppressed_context_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/suppressed_context_test.go index 70c45ce4e9..fece555e49 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/suppressed_context_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/suppressed_context_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package helper import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp.go index 6ce64cafa6..bfc692a799 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp.go @@ -1,8 +1,10 @@ package text -import "strings" +import ( + "bytes" +) // ChompBytes converts b to a string with its trailing newline, if present, removed. func ChompBytes(b []byte) string { - return strings.TrimSuffix(string(b), "\n") + return string(bytes.TrimSuffix(b, []byte{'\n'})) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp_test.go index fbdb1ecbcb..04daf1e8be 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/chomp_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/chomp_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package text import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/random.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/random.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/text/random.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/text/random.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker.go index d6054422d7..4009f951e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker.go @@ -47,16 +47,16 @@ type ManualTicker struct { ResetFunc func() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mt *ManualTicker) C() <-chan time.Time { return mt.c } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mt *ManualTicker) Stop() { mt.StopFunc() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mt *ManualTicker) Reset() { mt.ResetFunc() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mt *ManualTicker) Tick() { mt.c <- time.Now() } // NewManualTicker returns a Ticker that can be manually controlled. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker_test.go index 8fcdb9c68e..dcd752cda1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/helper/ticker_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/helper/ticker_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package helper import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/listenmux/mux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/listenmux/mux.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/listenmux/mux.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/listenmux/mux.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/listenmux/mux_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/listenmux/mux_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/listenmux/mux_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/listenmux/mux_test.go index da163f01c6..8b9db22421 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/listenmux/mux_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/listenmux/mux_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package listenmux import ( @@ -13,7 +15,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -66,7 +68,7 @@ func TestMux_normalClientNoMux(t *testing.T) { addr := serverWithHandshaker(t, nil) - cc, err := grpc.Dial(addr, grpc.WithInsecure()) + cc, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer cc.Close() @@ -83,7 +85,7 @@ func TestMux_normalClientMuxIgnored(t *testing.T) { }), ) - cc, err := grpc.Dial(addr, grpc.WithInsecure()) + cc, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer cc.Close() @@ -104,7 +106,7 @@ func TestMux_muxClientPassesThrough(t *testing.T) { cc, err := grpc.Dial( "ignored", - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { c, err := net.Dial("tcp", addr) if err != nil { @@ -264,7 +266,7 @@ func TestMux_concurrency(t *testing.T) { go func() { <-start grpcHealthErrors <- func() error { - cc, err := grpc.Dial(addr, grpc.WithInsecure()) + cc, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return err } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/hook.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/hook.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/hook.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/hook.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log.go index 351e20b425..0974edde19 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log.go @@ -9,7 +9,7 @@ import ( grpcmwlogrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/stats" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log_test.go index 224ea83899..7c72064fb3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/log/log_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/log/log_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package log import ( @@ -17,8 +19,8 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/grpcstats" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/grpcstats" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/stats" @@ -491,10 +493,8 @@ func TestLogDeciderOption_logByRegexpMatch(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - require.NoError(t, os.Setenv("GITALY_LOG_REQUEST_METHOD_DENY_PATTERN", tc.skip)) - defer func() { require.NoError(t, os.Unsetenv("GITALY_LOG_REQUEST_METHOD_DENY_PATTERN")) }() - require.NoError(t, os.Setenv("GITALY_LOG_REQUEST_METHOD_ALLOW_PATTERN", tc.only)) - defer func() { require.NoError(t, os.Unsetenv("GITALY_LOG_REQUEST_METHOD_ALLOW_PATTERN")) }() + t.Setenv("GITALY_LOG_REQUEST_METHOD_DENY_PATTERN", tc.skip) + t.Setenv("GITALY_LOG_REQUEST_METHOD_ALLOW_PATTERN", tc.only) logger, hook := test.NewNullLogger() interceptor := grpcmwlogrus.UnaryServerInterceptor(logrus.NewEntry(logger), DeciderOption()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer/url.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer/url.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer/url.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer/url.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer/url_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer/url_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer/url_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer/url_test.go index ae9eee5eaf..8be57d237e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/logsanitizer/url_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/logsanitizer/url_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package logsanitizer import ( @@ -81,9 +83,9 @@ func TestUrlSanitizerHook(t *testing.T) { logFunc: func() { logger.WithFields(log.Fields{ "grpc.method": "CreateRepositoryFromURL", - }).Info("asked for: https://gitlab.com/gitlab-org/gitaly/v14") + }).Info("asked for: https://gitlab.com/gitlab-org/gitaly/v15") }, - expectedString: "asked for: https://gitlab.com/gitlab-org/gitaly/v14", + expectedString: "asked for: https://gitlab.com/gitlab-org/gitaly/v15", }, } @@ -104,7 +106,7 @@ func BenchmarkUrlSanitizerWithoutSanitization(b *testing.B) { logger.Out = io.Discard logger.Hooks.Add(urlSanitizer) - benchmarkLogging(logger, b) + benchmarkLogging(b, logger) } func BenchmarkUrlSanitizerWithSanitization(b *testing.B) { @@ -118,10 +120,10 @@ func BenchmarkUrlSanitizerWithSanitization(b *testing.B) { logger.Out = io.Discard logger.Hooks.Add(urlSanitizer) - benchmarkLogging(logger, b) + benchmarkLogging(b, logger) } -func benchmarkLogging(logger *log.Logger, b *testing.B) { +func benchmarkLogging(b *testing.B, logger *log.Logger) { for n := 0; n < b.N; n++ { logger.WithFields(log.Fields{ "grpc.method": "CreateRepositoryFromURL", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context.go index 9483abf25c..950e81c70e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context.go @@ -10,13 +10,19 @@ import ( ) const ( - // Delim is a delimiter used between a feature flag name and its value. - Delim = ":" - - // ffPrefix is the prefix used for Gitaly-scoped feature flags. - ffPrefix = "gitaly-feature-" + // explicitFeatureFlagKey is used by ContextWithExplicitFeatureFlags to mark a context as + // requiring all feature flags to have been explicitly defined. + explicitFeatureFlagKey = "require_explicit_feature_flag_checks" ) +// ContextWithExplicitFeatureFlags marks the context such that all feature flags which are checked +// must have been explicitly set in that context. If a feature flag wasn't set to an explicit value, +// then checking this feature flag will panic. This is not for use in production systems, but is +// intended for tests to verify that we test each feature flag properly. +func ContextWithExplicitFeatureFlags(ctx context.Context) context.Context { + return injectIntoIncomingAndOutgoingContext(ctx, explicitFeatureFlagKey, true) +} + // ContextWithFeatureFlag sets the feature flag in both the incoming and outgoing context. func ContextWithFeatureFlag(ctx context.Context, flag FeatureFlag, enabled bool) context.Context { return injectIntoIncomingAndOutgoingContext(ctx, flag.MetadataKey(), enabled) @@ -68,56 +74,44 @@ func incomingCtxWithFeatureFlag(ctx context.Context, key string, enabled bool) c return metadata.NewIncomingContext(ctx, md) } -// AllFlags returns all feature flags with their value that use the Gitaly metadata -// prefix. Note: results will not be sorted. -func AllFlags(ctx context.Context) []string { - featureFlagMap := RawFromContext(ctx) - featureFlagSlice := make([]string, 0, len(featureFlagMap)) - for key, value := range featureFlagMap { - featureFlagSlice = append(featureFlagSlice, - fmt.Sprintf("%s%s%s", strings.TrimPrefix(key, ffPrefix), Delim, value), - ) +func injectIntoIncomingAndOutgoingContext(ctx context.Context, key string, enabled bool) context.Context { + incomingMD, ok := metadata.FromIncomingContext(ctx) + if !ok { + incomingMD = metadata.New(map[string]string{}) } - return featureFlagSlice + incomingMD.Set(key, strconv.FormatBool(enabled)) + + ctx = metadata.NewIncomingContext(ctx, incomingMD) + + return metadata.AppendToOutgoingContext(ctx, key, strconv.FormatBool(enabled)) } -// Raw contains feature flags and their values in their raw form with header prefix in place -// and values unparsed. -type Raw map[string]string - -// RawFromContext returns a map that contains all feature flags with their values. The feature -// flags are in their raw format with the header prefix in place. If multiple values are set a -// flag, the first occurrence is used. -// -// This is mostly intended for propagating the feature flags by other means than the metadata, -// for example into the hooks through the environment. -func RawFromContext(ctx context.Context) Raw { +// FromContext returns the set of all feature flags defined in the context. This returns both +// feature flags that are currently defined by Gitaly, but may also return some that aren't defined +// by us in case they match the feature flag prefix but don't have a definition. This function also +// returns the state of the feature flag *as defined in the context*. This value may be overridden. +func FromContext(ctx context.Context) map[FeatureFlag]bool { md, ok := metadata.FromIncomingContext(ctx) if !ok { - return nil + return map[FeatureFlag]bool{} } - featureFlags := map[string]string{} - for key, values := range md { - if !strings.HasPrefix(key, ffPrefix) || len(values) == 0 { + flags := map[FeatureFlag]bool{} + for metadataName, values := range md { + if len(values) == 0 { continue } - featureFlags[key] = values[0] + flag, err := FromMetadataKey(metadataName) + if err != nil { + continue + } + + flags[flag] = values[0] == "true" } - return featureFlags -} - -// OutgoingWithRaw returns a new context with raw flags appended into the outgoing -// metadata. -func OutgoingWithRaw(ctx context.Context, flags Raw) context.Context { - for key, value := range flags { - ctx = metadata.AppendToOutgoingContext(ctx, key, value) - } - - return ctx + return flags } func rubyHeaderKey(flag string) string { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context_test.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context_test.go index 998c0f259b..934a3abfa5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag/context_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/context_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package featureflag import ( @@ -5,7 +7,7 @@ import ( "testing" "github.com/stretchr/testify/require" - gitaly_metadata "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" + gitaly_metadata "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "google.golang.org/grpc/metadata" ) @@ -119,41 +121,61 @@ func TestGRPCMetadataFeatureFlag(t *testing.T) { } } -func TestAllEnabledFlags(t *testing.T) { - flags := map[string]string{ - ffPrefix + "meow": "true", - ffPrefix + "foo": "true", - ffPrefix + "woof": "false", // not enabled - ffPrefix + "bar": "TRUE", // not enabled +func TestFromContext(t *testing.T) { + defer func(old map[string]FeatureFlag) { + flagsByName = old + }(flagsByName) + + defaultDisabledFlag := FeatureFlag{ + Name: "default_disabled", + OnByDefault: false, } - ctx := metadata.NewIncomingContext(createContext(), metadata.New(flags)) - require.ElementsMatch(t, AllFlags(ctx), []string{"meow:true", "foo:true", "woof:false", "bar:TRUE"}) -} - -func TestRaw(t *testing.T) { - enabledFlag := FeatureFlag{Name: "enabled-flag"} - disabledFlag := FeatureFlag{Name: "disabled-flag"} - - raw := Raw{ - ffPrefix + enabledFlag.Name: "true", - ffPrefix + disabledFlag.Name: "false", + defaultEnabledFlag := FeatureFlag{ + Name: "default_enabled", + OnByDefault: true, } - t.Run("RawFromContext", func(t *testing.T) { - ctx := createContext() - ctx = IncomingCtxWithFeatureFlag(ctx, enabledFlag, true) - ctx = IncomingCtxWithFeatureFlag(ctx, disabledFlag, false) + flagsByName = map[string]FeatureFlag{ + "default_disabled": defaultDisabledFlag, + "default_enabled": defaultEnabledFlag, + } - require.Equal(t, raw, RawFromContext(ctx)) + t.Run("with no defined flags", func(t *testing.T) { + require.Empty(t, FromContext(createContext())) }) - t.Run("OutgoingWithRaw", func(t *testing.T) { - outgoingMD, ok := metadata.FromOutgoingContext(OutgoingWithRaw(createContext(), raw)) - require.True(t, ok) - require.Equal(t, metadata.MD{ - ffPrefix + enabledFlag.Name: {"true"}, - ffPrefix + disabledFlag.Name: {"false"}, - }, outgoingMD) + t.Run("with single defined flag", func(t *testing.T) { + ctx := ContextWithFeatureFlag(createContext(), defaultDisabledFlag, false) + ctx = ContextWithFeatureFlag(ctx, defaultEnabledFlag, true) + + require.Equal(t, map[FeatureFlag]bool{ + defaultDisabledFlag: false, + defaultEnabledFlag: true, + }, FromContext(ctx)) + }) + + t.Run("with defined flags and non-default values", func(t *testing.T) { + ctx := ContextWithFeatureFlag(createContext(), defaultDisabledFlag, true) + ctx = ContextWithFeatureFlag(ctx, defaultEnabledFlag, false) + + require.Equal(t, map[FeatureFlag]bool{ + defaultDisabledFlag: true, + defaultEnabledFlag: false, + }, FromContext(ctx)) + }) + + t.Run("with defined and undefined flag", func(t *testing.T) { + undefinedFlag := FeatureFlag{ + Name: "undefined_flag", + } + + ctx := ContextWithFeatureFlag(createContext(), defaultDisabledFlag, false) + ctx = ContextWithFeatureFlag(ctx, undefinedFlag, false) + + require.Equal(t, map[FeatureFlag]bool{ + defaultDisabledFlag: false, + undefinedFlag: false, + }, FromContext(ctx)) }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag.go new file mode 100644 index 0000000000..24481d1082 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag.go @@ -0,0 +1,175 @@ +package featureflag + +import ( + "context" + "fmt" + "regexp" + "strconv" + "strings" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "google.golang.org/grpc/metadata" +) + +var ( + // EnableAllFeatureFlagsEnvVar will cause Gitaly to treat all feature flags as + // enabled in case its value is set to `true`. Only used for testing purposes. + EnableAllFeatureFlagsEnvVar = "GITALY_TESTING_ENABLE_ALL_FEATURE_FLAGS" + + // featureFlagsOverride allows to enable all feature flags with a + // single environment variable. If the value of + // GITALY_TESTING_ENABLE_ALL_FEATURE_FLAGS is set to "true", then all + // feature flags will be enabled. This is only used for testing + // purposes such that we can run integration tests with feature flags. + featureFlagsOverride, _ = env.GetBool(EnableAllFeatureFlagsEnvVar, false) + + flagChecks = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "gitaly_feature_flag_checks_total", + Help: "Number of enabled/disabled checks for Gitaly server side feature flags", + }, + []string{"flag", "enabled"}, + ) + + // flagsByName is the set of defined feature flags mapped by their respective name. + flagsByName = map[string]FeatureFlag{} +) + +// Feature flags must contain at least 2 characters. Can only contain lowercase letters, +// digits, and '_'. They must start with a letter, and cannot end with '_'. +// Feature flag name would be used to construct the corresponding metadata key, so: +// - Only characters allowed by grpc metadata keys can be used and uppercase letters +// would be normalized to lowercase, see +// https://pkg.go.dev/google.golang.org/grpc/metadata#New +// - It is critical that feature flags don't contain a dash, because the client converts +// dashes to underscores when converting a feature flag's name to the metadata key, +// and vice versa. The name wouldn't round-trip in case it had underscores and must +// thus use dashes instead. +var ffNameRegexp = regexp.MustCompile(`^[a-z][a-z0-9_]*[a-z0-9]$`) + +const ( + // ffPrefix is the prefix used for Gitaly-scoped feature flags. + ffPrefix = "gitaly-feature-" +) + +// DefinedFlags returns the set of feature flags that have been explicitly defined. +func DefinedFlags() []FeatureFlag { + flags := make([]FeatureFlag, 0, len(flagsByName)) + for _, flag := range flagsByName { + flags = append(flags, flag) + } + return flags +} + +// FeatureFlag gates the implementation of new or changed functionality. +type FeatureFlag struct { + // Name is the name of the feature flag. + Name string `json:"name"` + // OnByDefault is the default value if the feature flag is not explicitly set in + // the incoming context. + OnByDefault bool `json:"on_by_default"` +} + +// NewFeatureFlag creates a new feature flag and adds it to the array of all existing feature flags. +// The name must be of the format `some_feature_flag`. Accepts a version and rollout issue URL as +// input that are not used for anything but only for the sake of linking to the feature flag rollout +// issue in the Gitaly project. +func NewFeatureFlag(name, version, rolloutIssueURL string, onByDefault bool) FeatureFlag { + if !ffNameRegexp.MatchString(name) { + panic("invalid feature flag name.") + } + + featureFlag := FeatureFlag{ + Name: name, + OnByDefault: onByDefault, + } + + flagsByName[name] = featureFlag + + return featureFlag +} + +// FromMetadataKey parses the given gRPC metadata key into a Gitaly feature flag and performs the +// necessary conversions. Returns an error in case the metadata does not refer to a feature flag. +// +// This function tries to look up the default value via our set of flag definitions. In case the +// flag definition is unknown to Gitaly it assumes a default value of `false`. +func FromMetadataKey(metadataKey string) (FeatureFlag, error) { + if !strings.HasPrefix(metadataKey, ffPrefix) { + return FeatureFlag{}, fmt.Errorf("not a feature flag: %q", metadataKey) + } + + flagName := strings.TrimPrefix(metadataKey, ffPrefix) + flagName = strings.ReplaceAll(flagName, "-", "_") + + flag, ok := flagsByName[flagName] + if !ok { + flag = FeatureFlag{ + Name: flagName, + OnByDefault: false, + } + } + + return flag, nil +} + +// FormatWithValue converts the feature flag into a string with the given state. Note that this +// function uses the feature flag name and not the raw metadata key as used in gRPC metadata. +func (ff FeatureFlag) FormatWithValue(enabled bool) string { + return fmt.Sprintf("%s:%v", ff.Name, enabled) +} + +// IsEnabled checks if the feature flag is enabled for the passed context. +// Only returns true if the metadata for the feature flag is set to "true" +func (ff FeatureFlag) IsEnabled(ctx context.Context) bool { + if featureFlagsOverride { + return true + } + + val, ok := ff.valueFromContext(ctx) + if !ok { + if md, ok := metadata.FromIncomingContext(ctx); ok { + if _, ok := md[explicitFeatureFlagKey]; ok { + panic(fmt.Sprintf("checking for feature %q without use of feature sets", ff.Name)) + } + } + + return ff.OnByDefault + } + + enabled := val == "true" + + flagChecks.WithLabelValues(ff.Name, strconv.FormatBool(enabled)).Inc() + + return enabled +} + +// IsDisabled determines whether the feature flag is disabled in the incoming context. +func (ff FeatureFlag) IsDisabled(ctx context.Context) bool { + return !ff.IsEnabled(ctx) +} + +// MetadataKey returns the key of the feature flag as it is present in the metadata map. +func (ff FeatureFlag) MetadataKey() string { + return ffPrefix + strings.ReplaceAll(ff.Name, "_", "-") +} + +func (ff FeatureFlag) valueFromContext(ctx context.Context) (string, bool) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return "", false + } + + val, ok := md[ff.MetadataKey()] + if !ok { + return "", false + } + + if len(val) == 0 { + return "", false + } + + return val[0], true +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag_test.go new file mode 100644 index 0000000000..b2776d94ab --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/featureflag_test.go @@ -0,0 +1,186 @@ +//go:build !gitaly_test_sha256 + +package featureflag + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/grpc/metadata" +) + +func TestFeatureFlag_FromMetadataKey(t *testing.T) { + defer func(old map[string]FeatureFlag) { + flagsByName = old + }(flagsByName) + + defaultEnabled := FeatureFlag{ + Name: "default_enabled", + OnByDefault: true, + } + defaultDisabled := FeatureFlag{ + Name: "default_disabled", + OnByDefault: false, + } + + flagsByName = map[string]FeatureFlag{ + defaultEnabled.Name: defaultEnabled, + defaultDisabled.Name: defaultDisabled, + } + + for _, tc := range []struct { + desc string + metadataKey string + expectedErr error + expectedFlag FeatureFlag + }{ + { + desc: "empty key", + metadataKey: "", + expectedErr: fmt.Errorf("not a feature flag: \"\""), + }, + { + desc: "invalid prefix", + metadataKey: "invalid-prefix", + expectedErr: fmt.Errorf("not a feature flag: \"invalid-prefix\""), + }, + { + desc: "default enabled flag", + metadataKey: defaultEnabled.MetadataKey(), + expectedFlag: defaultEnabled, + }, + { + desc: "default disabled flag", + metadataKey: defaultDisabled.MetadataKey(), + expectedFlag: defaultDisabled, + }, + { + desc: "undefined flag", + metadataKey: "gitaly-feature-not-defined", + expectedFlag: FeatureFlag{ + Name: "not_defined", + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + flag, err := FromMetadataKey(tc.metadataKey) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedFlag, flag) + }) + } +} + +func TestFeatureFlag_enabled(t *testing.T) { + for _, tc := range []struct { + desc string + flag string + headers map[string]string + shouldPanic bool + enabled bool + onByDefault bool + }{ + { + desc: "empty name", + flag: "", + shouldPanic: true, + }, + { + desc: "flag name too short", + flag: "a", + shouldPanic: true, + }, + { + desc: "flag name start with number", + flag: "0_flag", + shouldPanic: true, + }, + { + desc: "flag name start with underscore", + flag: "_flag", + shouldPanic: true, + }, + { + desc: "flag name end with underscore", + flag: "flag_", + shouldPanic: true, + }, + { + desc: "flag name with uppercase", + flag: "Flag", + shouldPanic: true, + }, + { + desc: "flag name with dashes", + flag: "flag-with-dash", + shouldPanic: true, + }, + { + desc: "flag name with characters disallowed by grpc metadata key", + flag: "flag_with_colon:_and_slash/", + shouldPanic: true, + }, + { + desc: "flag name with underscores", + flag: "flag_under_score", + headers: map[string]string{"gitaly-feature-flag-under-score": "true"}, + shouldPanic: false, + enabled: true, + onByDefault: false, + }, + { + desc: "no headers", + flag: "flag", + headers: nil, + shouldPanic: false, + enabled: false, + onByDefault: false, + }, + { + desc: "no 'gitaly-feature' prefix in flag name", + flag: "flag", + headers: map[string]string{"flag": "true"}, + shouldPanic: false, + enabled: false, + onByDefault: false, + }, + { + desc: "not valid header value", + flag: "flag", + headers: map[string]string{"gitaly-feature-flag": "TRUE"}, + shouldPanic: false, + enabled: false, + onByDefault: false, + }, + { + desc: "flag explicitly disabled", + flag: "flag", + headers: map[string]string{"gitaly-feature-flag": "false"}, + shouldPanic: false, + enabled: false, + onByDefault: true, + }, + { + desc: "flag enabled by default but missing", + flag: "flag", + headers: map[string]string{}, + shouldPanic: false, + enabled: true, + onByDefault: true, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx := metadata.NewIncomingContext(createContext(), metadata.New(tc.headers)) + + var ff FeatureFlag + ffInitFunc := func() { ff = NewFeatureFlag(tc.flag, "", "", tc.onByDefault) } + if tc.shouldPanic { + require.PanicsWithValue(t, "invalid feature flag name.", ffInitFunc) + return + } + require.NotPanics(t, ffInitFunc) + require.Equal(t, tc.enabled, ff.IsEnabled(ctx)) + require.Equal(t, tc.enabled, !ff.IsDisabled(ctx)) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_catfile_for_repo_size.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_catfile_for_repo_size.go new file mode 100644 index 0000000000..d3f4098181 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_catfile_for_repo_size.go @@ -0,0 +1,10 @@ +package featureflag + +// CatfileRepoSize will enable the rate limiter to reject requests beyond a configured +// rate. +var CatfileRepoSize = NewFeatureFlag( + "catfile_repo_size", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4421", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_delete_refs_structured_errors.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_delete_refs_structured_errors.go new file mode 100644 index 0000000000..eca4647c78 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_delete_refs_structured_errors.go @@ -0,0 +1,9 @@ +package featureflag + +// DeleteRefsStructuredErrors turns on metrics for pack objects +var DeleteRefsStructuredErrors = NewFeatureFlag( + "delete_refs_structured_errors", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4348", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_fetch_into_object_pool_prune_refs.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_fetch_into_object_pool_prune_refs.go new file mode 100644 index 0000000000..4f0a2b41b3 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_fetch_into_object_pool_prune_refs.go @@ -0,0 +1,11 @@ +package featureflag + +// FetchIntoObjectPoolPruneRefs enables pruning of references in object pools. This is required in +// order to fix cases where updating pools doesn't work anymore due to preexisting references +// conflicting with new references in the pool member. +var FetchIntoObjectPoolPruneRefs = NewFeatureFlag( + "fetch_into_object_pool_prune_refs", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4394", + true, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_find_tag_structured_error.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_find_tag_structured_error.go new file mode 100644 index 0000000000..900f1eefc7 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_find_tag_structured_error.go @@ -0,0 +1,10 @@ +package featureflag + +// FindTagStructuredError enables the use of structured errors for the FindTag RPC in case the tag +// could not be found. +var FindTagStructuredError = NewFeatureFlag( + "find_tag_structured_error", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4398", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_git_v2371.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_git_v2371.go new file mode 100644 index 0000000000..86e665a31d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_git_v2371.go @@ -0,0 +1,9 @@ +package featureflag + +// GitV2371Gl1 will enable use of Git v2.37.1.gl1. +var GitV2371Gl1 = NewFeatureFlag( + "git_v2371gl1", + "v15.0.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4194", + true, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_find_license.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_find_license.go new file mode 100644 index 0000000000..a3c63b2c90 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_find_license.go @@ -0,0 +1,9 @@ +package featureflag + +// GoFindLicense enables Go implementation of FindLicense +var GoFindLicense = NewFeatureFlag( + "go_find_license", + "v14.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/3759", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_language_stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_language_stats.go new file mode 100644 index 0000000000..cf4626a062 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_go_language_stats.go @@ -0,0 +1,10 @@ +package featureflag + +// GoLanguageStats flag enables getting CommitLanguages statistics written in +// Go. +var GoLanguageStats = NewFeatureFlag( + "go_language_stats", + "v15.2.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4254", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_praefect_generated_paths.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_praefect_generated_paths.go new file mode 100644 index 0000000000..6e31039599 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_praefect_generated_paths.go @@ -0,0 +1,9 @@ +package featureflag + +// PraefectGeneratedReplicaPaths will enable Praefect generated replica paths for new repositories. +var PraefectGeneratedReplicaPaths = NewFeatureFlag( + "praefect_generated_replica_paths", + "v15.0.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4218", + true, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_repo_size_revlist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_repo_size_revlist.go new file mode 100644 index 0000000000..b630ccfc6d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_repo_size_revlist.go @@ -0,0 +1,10 @@ +package featureflag + +// RevlistForRepoSize enables the RepositorySize RPC to use git rev-list to +// calculate the disk usage of the repository. +var RevlistForRepoSize = NewFeatureFlag( + "revlist_for_repo_size", + "v14.10.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4317", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go new file mode 100644 index 0000000000..a92948c4e2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_run_cmd_in_cgroup.go @@ -0,0 +1,9 @@ +package featureflag + +// RunCommandsInCGroup allows all commands to be run within a cgroup +var RunCommandsInCGroup = NewFeatureFlag( + "run_cmds_in_cgroup", + "v14.10.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4102", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_simplify_find_local_branches_response.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_simplify_find_local_branches_response.go new file mode 100644 index 0000000000..04dfc9f3b8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_simplify_find_local_branches_response.go @@ -0,0 +1,10 @@ +package featureflag + +// SimplifyFindLocalBranchesResponse enables the simplification of FindLocalBranchesRespnose +// by adding the generic Branch type in the response +var SimplifyFindLocalBranchesResponse = NewFeatureFlag( + "simplify_find_local_branches_response", + "v15.4.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/1294", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go new file mode 100644 index 0000000000..c8b8d9ee29 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_transactional_restore_custom_hooks.go @@ -0,0 +1,10 @@ +package featureflag + +// TransactionalRestoreCustomHooks will use transactional voting in the +// RestoreCustomHooks RPC +var TransactionalRestoreCustomHooks = NewFeatureFlag( + "tx_restore_custom_hooks", + "v15.0.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4203", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_use_new_calculation_for_repo_size.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_use_new_calculation_for_repo_size.go new file mode 100644 index 0000000000..960e213c15 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_use_new_calculation_for_repo_size.go @@ -0,0 +1,10 @@ +package featureflag + +// UseNewRepoSize will send the new repository size values in RepositorySize to +// the client. +var UseNewRepoSize = NewFeatureFlag( + "use_new_repository_size", + "v15.4.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4448", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_branch_structured_errors.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_branch_structured_errors.go new file mode 100644 index 0000000000..f1b6e965ad --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_branch_structured_errors.go @@ -0,0 +1,9 @@ +package featureflag + +// UserCreateBranchStructuredErrors will enable the use of structured errors in the UserCreateTag RPC. +var UserCreateBranchStructuredErrors = NewFeatureFlag( + "user_create_branch_structured_errors", + "v15.4.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4227", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_tag_structured_errors.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_tag_structured_errors.go new file mode 100644 index 0000000000..69d1342b5d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag/ff_user_create_tag_structured_errors.go @@ -0,0 +1,9 @@ +package featureflag + +// UserCreateTagStructuredErrors will enable the use of structured errors in the UserCreateTag RPC. +var UserCreateTagStructuredErrors = NewFeatureFlag( + "user_create_tag_structured_errors", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4372", + false, +) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/metadata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/metadata.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/metadata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/metadata.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/metadata_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/metadata_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/metadata_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/metadata_test.go index 8f0d831be9..f84febc6c8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/metadata/metadata_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/metadata/metadata_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package metadata import ( @@ -5,8 +7,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestOutgoingToIncoming(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache.go index aed1c74e1a..5485563b70 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache.go @@ -7,8 +7,8 @@ import ( "sync" "github.com/sirupsen/logrus" - diskcache "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" + diskcache "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" "google.golang.org/grpc" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache_test.go index b23a5b2bea..1b5b782408 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/cache_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/cache_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package cache import ( @@ -9,13 +11,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - diskcache "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + diskcache "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" @@ -170,7 +173,7 @@ func (mc *mockCache) StartLease(repo *gitalypb.Repository) (diskcache.LeaseEnder return mc, nil } -func newTestSvc(t testing.TB, ctx context.Context, srvr *grpc.Server, svc testdata.TestServiceServer) (testdata.TestServiceClient, *grpc.ClientConn, func()) { +func newTestSvc(tb testing.TB, ctx context.Context, srvr *grpc.Server, svc testdata.TestServiceServer) (testdata.TestServiceClient, *grpc.ClientConn, func()) { healthSrvr := health.NewServer() grpc_health_v1.RegisterHealthServer(srvr, healthSrvr) healthSrvr.SetServingStatus("TestService", grpc_health_v1.HealthCheckResponse_SERVING) @@ -178,7 +181,7 @@ func newTestSvc(t testing.TB, ctx context.Context, srvr *grpc.Server, svc testda testdata.RegisterInterceptedServiceServer(srvr, &testdata.UnimplementedInterceptedServiceServer{}) lis, err := net.Listen("tcp", ":0") - require.NoError(t, err) + require.NoError(tb, err) errQ := make(chan error) @@ -188,16 +191,16 @@ func newTestSvc(t testing.TB, ctx context.Context, srvr *grpc.Server, svc testda cleanup := func() { srvr.Stop() - require.NoError(t, <-errQ) + require.NoError(tb, <-errQ) } cc, err := grpc.DialContext( ctx, lis.Addr().String(), grpc.WithBlock(), - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) - require.NoError(t, err) + require.NoError(tb, err) return testdata.NewTestServiceClient(cc), cc, cleanup } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/export_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/export_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/export_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/export_test.go index 48c1dab842..bc8a2378a5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/export_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/export_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package cache import "sync" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/prometheus.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/prometheus.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/prometheus.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/prometheus.go index 073402d5e8..c0cc2bb314 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/prometheus.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/prometheus.go @@ -3,7 +3,7 @@ package cache import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" ) var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.pb.go index ffaebf70a0..87e749f067 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.pb.go @@ -1,13 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: middleware/cache/testdata/stream.proto package testdata import ( - gitalypb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalypb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -155,7 +155,7 @@ var file_middleware_cache_testdata_stream_proto_rawDesc = []byte{ 0x2e, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, - 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x69, + 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x2f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.proto similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.proto index c977b0d691..f9c7cb6add 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package testdata; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata"; import "lint.proto"; import "shared.proto"; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream_grpc.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream_grpc.pb.go index 066eddc514..f84757cf62 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cache/testdata/stream_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache/testdata/stream_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: middleware/cache/testdata/stream.proto package testdata diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cancelhandler/cancelhandler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cancelhandler/cancelhandler.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cancelhandler/cancelhandler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cancelhandler/cancelhandler.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler.go index 50f251b082..94554cac90 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler.go @@ -5,7 +5,7 @@ import ( grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler_test.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler_test.go index 9289eed115..da599f0825 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/commandstatshandler/commandstatshandler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler/commandstatshandler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package commandstatshandler import ( @@ -11,18 +13,19 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/command" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" ) @@ -85,6 +88,8 @@ func TestInterceptor(t *testing.T) { require.NoError(t, err) }() + ctx := testhelper.Context(t) + tests := []struct { name string performRPC func(ctx context.Context, client gitalypb.RefServiceClient) @@ -99,7 +104,16 @@ func TestInterceptor(t *testing.T) { require.NoError(t, err) }, expectedLogData: map[string]interface{}{ - "command.count": 1, + // Until we bump our minimum required Git version to v2.36.0 we are + // forced to carry a version check whenever we spawn Git commands. + // The command count here is thus 2 because of the additional + // git-version(1) command. Note that the next command count remains + // 1 though: the version is cached, and consequentially we don't + // re-run git-version(1). + // + // This test will break again as soon as we bump the minimum Git + // version and thus remove the version check. + "command.count": 2, }, }, { @@ -126,9 +140,8 @@ func TestInterceptor(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { hook.Reset() - ctx := testhelper.Context(t) - conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(getBufDialer(listener)), grpc.WithInsecure()) + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(getBufDialer(listener)), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer conn.Close() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler.go index 4a1273a747..36e64edc94 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler.go @@ -7,7 +7,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "google.golang.org/grpc" ) @@ -26,11 +26,13 @@ func StreamInterceptor(srv interface{}, stream grpc.ServerStream, _ *grpc.Stream // track adds the list of the feature flags into the logging context. // The list is sorted by feature flag name to produce consistent output. func track(ctx context.Context) { - flags := featureflag.AllFlags(ctx) - if len(flags) != 0 { - sort.Slice(flags, func(i, j int) bool { - return flags[i][:strings.Index(flags[i], featureflag.Delim)] < flags[j][:strings.Index(flags[j], featureflag.Delim)] - }) - ctxlogrus.AddFields(ctx, logrus.Fields{"feature_flags": strings.Join(flags, " ")}) + var flagsWithValue []string + for flag, value := range featureflag.FromContext(ctx) { + flagsWithValue = append(flagsWithValue, flag.FormatWithValue(value)) + } + sort.Strings(flagsWithValue) + + if len(flagsWithValue) != 0 { + ctxlogrus.AddFields(ctx, logrus.Fields{"feature_flags": strings.Join(flagsWithValue, " ")}) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler_test.go index f3b68b0176..8d1a4ec8fe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/featureflag/featureflag_handler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag/featureflag_handler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package featureflag import ( @@ -10,7 +12,7 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "google.golang.org/grpc" ) @@ -45,7 +47,7 @@ func TestStreamInterceptor(t *testing.T) { } func callUnary(ctx context.Context) { - // nolint: errcheck + //nolint: errcheck UnaryInterceptor(ctx, nil, nil, func(context.Context, interface{}) (interface{}, error) { ctxlogrus.Extract(ctx).Info("verify") return nil, nil @@ -53,7 +55,7 @@ func callUnary(ctx context.Context) { } func callStream(ctx context.Context) { - // nolint: errcheck + //nolint: errcheck StreamInterceptor(ctx, &grpcmw.WrappedServerStream{WrappedContext: ctx}, nil, func(interface{}, grpc.ServerStream) error { ctxlogrus.Extract(ctx).Info("verify") return nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter.go index f6587554a5..e2595571b7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter.go @@ -7,10 +7,12 @@ import ( "sync" "time" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/protobuf/types/known/durationpb" ) // ErrMaxQueueTime indicates a request has reached the maximum time allowed to wait in the @@ -48,8 +50,7 @@ type semaphoreReference struct { func (sem *semaphoreReference) acquire(ctx context.Context) error { var ticker helper.Ticker - if featureflag.ConcurrencyQueueMaxWait.IsEnabled(ctx) && - sem.newTicker != nil { + if sem.newTicker != nil { ticker = sem.newTicker() } else { ticker = helper.Ticker(helper.NewManualTicker()) @@ -116,8 +117,7 @@ func (c *ConcurrencyLimiter) queueInc(ctx context.Context) error { c.mux.Lock() defer c.mux.Unlock() - if featureflag.ConcurrencyQueueEnforceMax.IsEnabled(ctx) && - c.queuedLimit > 0 && + if c.queuedLimit > 0 && c.queued >= c.queuedLimit { c.monitor.Dropped(ctx, "max_size") return ErrMaxQueueSize @@ -146,7 +146,27 @@ func (c *ConcurrencyLimiter) Limit(ctx context.Context, lockKey string, f Limite var decremented bool + log := ctxlogrus.Extract(ctx) if err := c.queueInc(ctx); err != nil { + if errors.Is(err, ErrMaxQueueSize) { + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrUnavailable(ErrMaxQueueSize), + &gitalypb.LimitError{ + ErrorMessage: err.Error(), + RetryAfter: durationpb.New(0), + }, + ) + if errGeneratingDetailedErr != nil { + log.WithField("max_queue_size_error", err). + WithError(errGeneratingDetailedErr). + Error("failed to generate detailed error") + + return nil, helper.ErrUnavailable(ErrMaxQueueSize) + } + + return nil, detailedErr + } + return nil, err } defer c.queueDec(&decremented) @@ -164,7 +184,25 @@ func (c *ConcurrencyLimiter) Limit(ctx context.Context, lockKey string, f Limite if err != nil { if errors.Is(err, ErrMaxQueueTime) { c.monitor.Dropped(ctx, "max_time") + + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrUnavailable(ErrMaxQueueTime), + &gitalypb.LimitError{ + ErrorMessage: err.Error(), + RetryAfter: durationpb.New(0), + }, + ) + if errGeneratingDetailedErr != nil { + log.WithField("max_queue_wait_error", err). + WithError(errGeneratingDetailedErr). + Error("failed to generate detailed error") + + return nil, helper.ErrUnavailable(ErrMaxQueueTime) + } + + return nil, detailedErr } + return nil, err } defer sem.release() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter_test.go similarity index 62% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter_test.go index 4a13a3cd43..01bced2bdd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/concurrency_limiter_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/concurrency_limiter_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package limithandler import ( @@ -9,9 +11,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/durationpb" ) type counter struct { @@ -241,90 +245,70 @@ func TestConcurrencyLimiter_queueLimit(t *testing.T) { queueLimit := 10 ctx := testhelper.Context(t) - testCases := []struct { - desc string - featureFlagOn bool - }{ - { - desc: "feature flag on", - featureFlagOn: true, - }, - { - desc: "feature flag off", - featureFlagOn: false, - }, - } + monitorCh := make(chan struct{}) + monitor := &blockingQueueCounter{queuedCh: monitorCh} + ch := make(chan struct{}) + limiter := NewConcurrencyLimiter(1, queueLimit, nil, monitor) - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - ctx = featureflag.IncomingCtxWithFeatureFlag( - ctx, - featureflag.ConcurrencyQueueEnforceMax, - tc.featureFlagOn, - ) - - monitorCh := make(chan struct{}) - monitor := &blockingQueueCounter{queuedCh: monitorCh} - ch := make(chan struct{}) - limiter := NewConcurrencyLimiter(1, queueLimit, nil, monitor) - - // occupied with one live request that takes a long time to complete - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - ch <- struct{}{} - <-ch - return nil, nil - }) - require.NoError(t, err) - }() - - <-monitorCh + // occupied with one live request that takes a long time to complete + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + ch <- struct{}{} <-ch - - var wg sync.WaitGroup - // fill up the queue - for i := 0; i < queueLimit; i++ { - wg.Add(1) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - require.NoError(t, err) - wg.Done() - }() - } - - var queued int - for range monitorCh { - queued++ - if queued == queueLimit { - break - } - } - - errChan := make(chan error, 1) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - errChan <- err - }() - - if tc.featureFlagOn { - err := <-errChan - assert.Error(t, err) - assert.Equal(t, "maximum queue size reached", err.Error()) - assert.Equal(t, monitor.droppedSize, 1) - } else { - <-monitorCh - assert.Equal(t, int64(queueLimit+1), limiter.queued) - assert.Equal(t, monitor.droppedSize, 0) - } - - close(ch) - wg.Wait() + return nil, nil }) + require.NoError(t, err) + }() + + <-monitorCh + <-ch + + var wg sync.WaitGroup + // fill up the queue + for i := 0; i < queueLimit; i++ { + wg.Add(1) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + return nil, nil + }) + require.NoError(t, err) + wg.Done() + }() } + + var queued int + for range monitorCh { + queued++ + if queued == queueLimit { + break + } + } + + errChan := make(chan error, 1) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + return nil, nil + }) + errChan <- err + }() + + err := <-errChan + assert.Error(t, err) + + s, ok := status.FromError(err) + require.True(t, ok) + details := s.Details() + require.Len(t, details, 1) + + limitErr, ok := details[0].(*gitalypb.LimitError) + require.True(t, ok) + + assert.Equal(t, ErrMaxQueueSize.Error(), limitErr.ErrorMessage) + assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) + assert.Equal(t, monitor.droppedSize, 1) + + close(ch) + wg.Wait() } type blockingDequeueCounter struct { @@ -343,107 +327,59 @@ func (b *blockingDequeueCounter) Dequeued(context.Context) { func TestLimitConcurrency_queueWaitTime(t *testing.T) { ctx := testhelper.Context(t) - t.Run("with feature flag", func(t *testing.T) { - ctx = featureflag.IncomingCtxWithFeatureFlag( - ctx, - featureflag.ConcurrencyQueueMaxWait, - true, - ) + ticker := helper.NewManualTicker() - ticker := helper.NewManualTicker() + dequeuedCh := make(chan struct{}) + monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} - dequeuedCh := make(chan struct{}) - monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} + limiter := NewConcurrencyLimiter( + 1, + 0, + func() helper.Ticker { + return ticker + }, + monitor, + ) - limiter := NewConcurrencyLimiter( - 1, - 0, - func() helper.Ticker { - return ticker - }, - monitor, - ) + ch := make(chan struct{}) + var wg sync.WaitGroup + wg.Add(1) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + <-ch + return nil, nil + }) + require.NoError(t, err) + wg.Done() + }() - ch := make(chan struct{}) - var wg sync.WaitGroup - wg.Add(1) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - <-ch - return nil, nil - }) - require.NoError(t, err) - wg.Done() - }() + <-dequeuedCh - <-dequeuedCh + ticker.Tick() - ticker.Tick() + errChan := make(chan error) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + return nil, nil + }) + errChan <- err + }() - errChan := make(chan error) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - errChan <- err - }() + <-dequeuedCh + err := <-errChan - <-dequeuedCh - err := <-errChan + s, ok := status.FromError(err) + require.True(t, ok) + details := s.Details() + require.Len(t, details, 1) - assert.Equal(t, ErrMaxQueueTime, err) - assert.Equal(t, monitor.droppedTime, 1) - close(ch) - wg.Wait() - }) + limitErr, ok := details[0].(*gitalypb.LimitError) + require.True(t, ok) - t.Run("without feature flag", func(t *testing.T) { - ctx = featureflag.IncomingCtxWithFeatureFlag( - ctx, - featureflag.ConcurrencyQueueMaxWait, - false, - ) + assert.Equal(t, ErrMaxQueueTime.Error(), limitErr.ErrorMessage) + assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) - ticker := helper.NewManualTicker() - - dequeuedCh := make(chan struct{}) - monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} - - limiter := NewConcurrencyLimiter( - 1, - 0, - func() helper.Ticker { - return ticker - }, - monitor, - ) - - ch := make(chan struct{}) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - <-ch - return nil, nil - }) - require.NoError(t, err) - }() - - <-dequeuedCh - - ticker.Tick() - - errChan := make(chan error) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - errChan <- err - }() - - close(ch) - <-dequeuedCh - err := <-errChan - - assert.NoError(t, err) - assert.Equal(t, monitor.droppedTime, 0) - }) + assert.Equal(t, monitor.droppedTime, 1) + close(ch) + wg.Wait() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware.go index 0d4ff6bbcb..81e91af9f1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware.go @@ -3,10 +3,9 @@ package limithandler import ( "context" - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "google.golang.org/grpc" ) @@ -146,13 +145,14 @@ func (w *wrappedStream) RecvMsg(m interface{}) error { } ready := make(chan struct{}) + errs := make(chan error) go func() { if _, err := limiter.Limit(ctx, lockKey, func() (interface{}, error) { close(ready) <-ctx.Done() return nil, nil }); err != nil { - ctxlogrus.Extract(ctx).WithError(err).Error("rate limiting streaming request") + errs <- err } }() @@ -162,5 +162,7 @@ func (w *wrappedStream) RecvMsg(m interface{}) error { case <-ready: // It's our turn! return nil + case err := <-errs: + return err } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware_test.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware_test.go index 53f0f53f28..d5aa4ee57a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/middleware_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/middleware_test.go @@ -1,8 +1,11 @@ +//go:build !gitaly_test_sha256 + package limithandler_test import ( "bytes" "context" + "io" "net" "sync" "testing" @@ -11,14 +14,18 @@ import ( promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - pb "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + pb "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/durationpb" ) func TestMain(m *testing.M) { @@ -78,49 +85,66 @@ func TestStreamLimitHandler(t *testing.T) { t.Parallel() testCases := []struct { - desc string - fullname string - f func(*testing.T, context.Context, pb.TestClient) - maxConcurrency int - expectedRequestCount int + desc string + fullname string + f func(*testing.T, context.Context, pb.TestClient, chan interface{}, chan error) + maxConcurrency int + expectedRequestCount int + expectedResponseCount int }{ + // The max queue size is set at 1, which means 1 request + // will be queued while the later ones will return with + // an error. That means that maxConcurrency number of + // requests will be processing but blocked due to blockCh. + // 1 request will be waiting to be picked up, and will be + // processed once we close the blockCh. { desc: "Single request, multiple responses", fullname: "/test.limithandler.Test/StreamOutput", - f: func(t *testing.T, ctx context.Context, client pb.TestClient) { + f: func(t *testing.T, ctx context.Context, client pb.TestClient, respCh chan interface{}, errCh chan error) { stream, err := client.StreamOutput(ctx, &pb.StreamOutputRequest{}) require.NoError(t, err) require.NotNil(t, stream) r, err := stream.Recv() - require.NoError(t, err) + if err != nil { + errCh <- err + return + } require.NotNil(t, r) require.True(t, r.Ok) + respCh <- r }, - maxConcurrency: 3, - expectedRequestCount: 3, + maxConcurrency: 3, + expectedRequestCount: 4, + expectedResponseCount: 4, }, { desc: "Multiple requests, single response", fullname: "/test.limithandler.Test/StreamInput", - f: func(t *testing.T, ctx context.Context, client pb.TestClient) { + f: func(t *testing.T, ctx context.Context, client pb.TestClient, respCh chan interface{}, errCh chan error) { stream, err := client.StreamInput(ctx) require.NoError(t, err) require.NotNil(t, stream) require.NoError(t, stream.Send(&pb.StreamInputRequest{})) r, err := stream.CloseAndRecv() - require.NoError(t, err) + if err != nil { + errCh <- err + return + } require.NotNil(t, r) require.True(t, r.Ok) + respCh <- r }, - maxConcurrency: 3, - expectedRequestCount: 3, + maxConcurrency: 3, + expectedRequestCount: 4, + expectedResponseCount: 4, }, { desc: "Multiple requests, multiple responses", fullname: "/test.limithandler.Test/Bidirectional", - f: func(t *testing.T, ctx context.Context, client pb.TestClient) { + f: func(t *testing.T, ctx context.Context, client pb.TestClient, respCh chan interface{}, errCh chan error) { stream, err := client.Bidirectional(ctx) require.NoError(t, err) require.NotNil(t, stream) @@ -129,19 +153,24 @@ func TestStreamLimitHandler(t *testing.T) { require.NoError(t, stream.CloseSend()) r, err := stream.Recv() - require.NoError(t, err) + if err != nil { + errCh <- err + return + } require.NotNil(t, r) require.True(t, r.Ok) + respCh <- r }, - maxConcurrency: 3, - expectedRequestCount: 3, + maxConcurrency: 3, + expectedRequestCount: 4, + expectedResponseCount: 4, }, { // Make sure that _streams_ are limited but that _requests_ on each // allowed stream are not limited. desc: "Multiple requests with same id, multiple responses", fullname: "/test.limithandler.Test/Bidirectional", - f: func(t *testing.T, ctx context.Context, client pb.TestClient) { + f: func(t *testing.T, ctx context.Context, client pb.TestClient, respCh chan interface{}, errCh chan error) { stream, err := client.Bidirectional(ctx) require.NoError(t, err) require.NotNil(t, stream) @@ -155,29 +184,40 @@ func TestStreamLimitHandler(t *testing.T) { require.NoError(t, stream.CloseSend()) r, err := stream.Recv() - require.NoError(t, err) + if err != nil { + errCh <- err + return + } require.NotNil(t, r) require.True(t, r.Ok) + respCh <- r }, maxConcurrency: 3, // 3 (concurrent streams allowed) * 10 (requests per stream) - expectedRequestCount: 30, + // + 1 (queued stream) * (10 requests per stream) + expectedRequestCount: 40, + expectedResponseCount: 4, }, { desc: "With a max concurrency of 0", fullname: "/test.limithandler.Test/StreamOutput", - f: func(t *testing.T, ctx context.Context, client pb.TestClient) { + f: func(t *testing.T, ctx context.Context, client pb.TestClient, respCh chan interface{}, errCh chan error) { stream, err := client.StreamOutput(ctx, &pb.StreamOutputRequest{}) require.NoError(t, err) require.NotNil(t, stream) r, err := stream.Recv() - require.NoError(t, err) + if err != nil { + errCh <- err + return + } require.NotNil(t, r) require.True(t, r.Ok) + respCh <- r }, - maxConcurrency: 0, - expectedRequestCount: 10, // Allow all + maxConcurrency: 0, + expectedRequestCount: 10, + expectedResponseCount: 10, }, } @@ -187,9 +227,14 @@ func TestStreamLimitHandler(t *testing.T) { s := &server{blockCh: make(chan struct{})} + maxQueueSize := 1 cfg := config.Cfg{ Concurrency: []config.Concurrency{ - {RPC: tc.fullname, MaxPerRepo: tc.maxConcurrency}, + { + RPC: tc.fullname, + MaxPerRepo: tc.maxConcurrency, + MaxQueueSize: maxQueueSize, + }, }, } @@ -202,25 +247,118 @@ func TestStreamLimitHandler(t *testing.T) { defer conn.Close() ctx := testhelper.Context(t) - wg := &sync.WaitGroup{} - for i := 0; i < 10; i++ { - wg.Add(1) + totalCalls := 10 + + errChan := make(chan error) + respChan := make(chan interface{}) + + for i := 0; i < totalCalls; i++ { go func() { - defer wg.Done() - tc.f(t, ctx, client) + tc.f(t, ctx, client, respChan, errChan) }() } - time.Sleep(100 * time.Millisecond) - - require.Equal(t, tc.expectedRequestCount, s.getRequestCount()) + if tc.maxConcurrency > 0 { + for i := 0; i < totalCalls-tc.maxConcurrency-maxQueueSize; i++ { + err := <-errChan + testhelper.RequireGrpcError( + t, + helper.ErrInternalf("rate limiting stream request: %w", + limithandler.ErrMaxQueueSize), err) + } + } close(s.blockCh) - wg.Wait() + + for i := 0; i < tc.expectedResponseCount; i++ { + <-respChan + } + + require.Equal(t, tc.expectedRequestCount, s.getRequestCount()) }) } } +func TestStreamLimitHandler_error(t *testing.T) { + t.Parallel() + + s := &queueTestServer{reqArrivedCh: make(chan struct{})} + s.blockCh = make(chan struct{}) + + cfg := config.Cfg{ + Concurrency: []config.Concurrency{ + {RPC: "/test.limithandler.Test/Bidirectional", MaxPerRepo: 1, MaxQueueSize: 1}, + }, + } + + lh := limithandler.New(cfg, fixedLockKey, limithandler.WithConcurrencyLimiters) + interceptor := lh.StreamInterceptor() + srv, serverSocketPath := runServer(t, s, grpc.StreamInterceptor(interceptor)) + defer srv.Stop() + + client, conn := newClient(t, serverSocketPath) + defer conn.Close() + + ctx := testhelper.Context(t) + + respChan := make(chan *pb.BidirectionalResponse) + go func() { + stream, err := client.Bidirectional(ctx) + require.NoError(t, err) + require.NoError(t, stream.Send(&pb.BidirectionalRequest{})) + require.NoError(t, stream.CloseSend()) + resp, err := stream.Recv() + require.NoError(t, err) + respChan <- resp + }() + // The first request will be blocked by blockCh. + <-s.reqArrivedCh + + // These are the second and third requests to be sent. + // The second request will be waiting in the queue. + // The third request should return with an error. + errChan := make(chan error) + for i := 0; i < 2; i++ { + go func() { + stream, err := client.Bidirectional(ctx) + require.NoError(t, err) + require.NotNil(t, stream) + require.NoError(t, stream.Send(&pb.BidirectionalRequest{})) + require.NoError(t, stream.CloseSend()) + resp, err := stream.Recv() + + if err != nil { + errChan <- err + } else { + respChan <- resp + } + }() + } + + err := <-errChan + testhelper.RequireGrpcCode(t, err, codes.Unavailable) + // ensure it is a structured error + st, ok := status.FromError(err) + require.True(t, ok) + + testhelper.ProtoEqual(t, []interface{}{&gitalypb.LimitError{ + ErrorMessage: "maximum queue size reached", + RetryAfter: &durationpb.Duration{}, + }}, st.Details()) + + // allow the first request to finish + close(s.blockCh) + + // This allows the second request to finish + <-s.reqArrivedCh + + // we expect two responses. The first request, and the second + // request. The third request returned immediately with an error + // from the limit handler. + <-respChan + <-respChan +} + type queueTestServer struct { server reqArrivedCh chan struct{} @@ -235,6 +373,25 @@ func (q *queueTestServer) Unary(ctx context.Context, in *pb.UnaryRequest) (*pb.U return &pb.UnaryResponse{Ok: true}, nil } +func (q *queueTestServer) Bidirectional(stream pb.Test_BidirectionalServer) error { + // Read all the input + for { + if _, err := stream.Recv(); err != nil { + if err != io.EOF { + return err + } + + break + } + q.reqArrivedCh <- struct{}{} + + q.registerRequest() + } + <-q.blockCh // Block to ensure concurrency + + return stream.Send(&pb.BidirectionalResponse{Ok: true}) +} + func TestConcurrencyLimitHandlerMetrics(t *testing.T) { s := &queueTestServer{reqArrivedCh: make(chan struct{})} s.blockCh = make(chan struct{}) @@ -254,11 +411,7 @@ func TestConcurrencyLimitHandlerMetrics(t *testing.T) { client, conn := newClient(t, serverSocketPath) defer conn.Close() - ctx := featureflag.IncomingCtxWithFeatureFlag( - testhelper.Context(t), - featureflag.ConcurrencyQueueEnforceMax, - true, - ) + ctx := testhelper.Context(t) respCh := make(chan *pb.UnaryResponse) go func() { @@ -285,7 +438,17 @@ func TestConcurrencyLimitHandlerMetrics(t *testing.T) { var errs int for err := range errChan { - testhelper.RequireGrpcError(t, limithandler.ErrMaxQueueSize, err) + s, ok := status.FromError(err) + require.True(t, ok) + details := s.Details() + require.Len(t, details, 1) + + limitErr, ok := details[0].(*gitalypb.LimitError) + require.True(t, ok) + + assert.Equal(t, limithandler.ErrMaxQueueSize.Error(), limitErr.ErrorMessage) + assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) + errs++ if errs == 9 { break @@ -319,14 +482,13 @@ gitaly_requests_dropped_total{grpc_method="Unary",grpc_service="test.limithandle func TestRateLimitHandler(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.RateLimit).Run(t, testRateLimitHandler) -} -func testRateLimitHandler(t *testing.T, ctx context.Context) { + ctx := testhelper.Context(t) + methodName := "/test.limithandler.Test/Unary" cfg := config.Cfg{ RateLimiting: []config.RateLimiting{ - {RPC: methodName, Interval: 1 * time.Hour, Burst: 1}, + {RPC: methodName, Interval: duration.Duration(1 * time.Hour), Burst: 1}, }, } @@ -356,11 +518,16 @@ func testRateLimitHandler(t *testing.T, ctx context.Context) { for i := 0; i < 10; i++ { _, err := client.Unary(ctx, &pb.UnaryRequest{}) - if featureflag.RateLimit.IsEnabled(ctx) { - testhelper.RequireGrpcError(t, status.Error(codes.Unavailable, "too many requests"), err) - } else { - require.NoError(t, err) - } + s, ok := status.FromError(err) + require.True(t, ok) + details := s.Details() + require.Len(t, details, 1) + + limitErr, ok := details[0].(*gitalypb.LimitError) + require.True(t, ok) + + assert.Equal(t, limithandler.ErrRateLimit.Error(), limitErr.ErrorMessage) + assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) } expectedMetrics := `# HELP gitaly_requests_dropped_total Number of requests dropped from the queue @@ -412,7 +579,7 @@ func runServer(t *testing.T, s pb.TestServer, opt ...grpc.ServerOption) (*grpc.S func newClient(t *testing.T, serverSocketPath string) (pb.TestClient, *grpc.ClientConn) { connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), } conn, err := grpc.Dial(serverSocketPath, connOpts...) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/monitor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/monitor.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/monitor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/monitor.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter.go index f47bb5409a..5f2f2d9f69 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter.go @@ -7,10 +7,12 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" "golang.org/x/time/rate" + "google.golang.org/protobuf/types/known/durationpb" ) // RateLimiter is an implementation of Limiter that puts a hard limit on the @@ -23,6 +25,10 @@ type RateLimiter struct { ticker helper.Ticker } +// ErrRateLimit is returned when RateLimiter determined a request has breached +// the rate request limit. +var ErrRateLimit = errors.New("rate limit reached") + // Limit rejects an incoming reequest if the maximum number of requests per // second has been reached func (r *RateLimiter) Limit(ctx context.Context, lockKey string, f LimitedFunc) (interface{}, error) { @@ -36,9 +42,25 @@ func (r *RateLimiter) Limit(ctx context.Context, lockKey string, f LimitedFunc) // For now, we are only emitting this metric to get an idea of the shape // of traffic. r.requestsDroppedMetric.Inc() - if featureflag.RateLimit.IsEnabled(ctx) { - return nil, helper.ErrUnavailable(errors.New("too many requests")) + + err := helper.ErrUnavailable(ErrRateLimit) + + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + err, + &gitalypb.LimitError{ + ErrorMessage: ErrRateLimit.Error(), + RetryAfter: durationpb.New(0), + }, + ) + if errGeneratingDetailedErr != nil { + log.WithField("rate_limit_error", err). + WithError(errGeneratingDetailedErr). + Error("failed to generate detailed error") + + return nil, err } + + return nil, detailedErr } return f() @@ -97,7 +119,7 @@ func WithRateLimiters(ctx context.Context) SetupFunc { if limitCfg.Burst > 0 && limitCfg.Interval > 0 { serviceName, methodName := splitMethodName(limitCfg.RPC) rateLimiter := NewRateLimiter( - limitCfg.Interval, + limitCfg.Interval.Duration(), limitCfg.Burst, helper.NewTimerTicker(5*time.Minute), middleware.requestsDroppedMetric.With(prometheus.Labels{ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter_test.go index 8ee9b64e66..3cb90431d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/rate_limiter_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/rate_limiter_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package limithandler import ( @@ -5,8 +7,8 @@ import ( "time" "github.com/stretchr/testify/assert" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestRateLimiter_pruneUnusedLimiters(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.pb.go index 166eb29b6e..2c0c39b6d8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: middleware/limithandler/testdata/test.proto package testdata @@ -408,7 +408,7 @@ var file_middleware_limithandler_testdata_test_proto_rawDesc = []byte{ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x2f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.proto similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.proto index e80c1a228c..68627d93a0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package test.limithandler; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata"; service Test { rpc Unary(UnaryRequest) returns (UnaryResponse) {} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test_grpc.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test_grpc.pb.go index ba4cdb11bc..35e4ddc47d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata/test_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata/test_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: middleware/limithandler/testdata/test.proto package testdata diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testhelper_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testhelper_test.go index 7ae5c70466..5c5a54b682 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testhelper_test.go @@ -1,10 +1,13 @@ +//go:build !gitaly_test_sha256 + package limithandler_test import ( "context" + "io" "sync/atomic" - pb "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler/testdata" + pb "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata" ) type server struct { @@ -41,6 +44,9 @@ func (s *server) StreamInput(stream pb.Test_StreamInputServer) error { // Read all the input for { if _, err := stream.Recv(); err != nil { + if err != io.EOF { + return err + } break } @@ -56,6 +62,9 @@ func (s *server) Bidirectional(stream pb.Test_BidirectionalServer) error { // Read all the input for { if _, err := stream.Recv(); err != nil { + if err != io.EOF { + return err + } break } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler.go index 8d3a0a016c..5c42cd411a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler.go @@ -8,8 +8,8 @@ import ( grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -17,12 +17,18 @@ import ( var requests = promauto.NewCounterVec( prometheus.CounterOpts{ - Namespace: "gitaly", - Subsystem: "service", - Name: "client_requests_total", - Help: "Counter of client requests received by client, call_site, auth version, response code and deadline_type", + Name: "gitaly_service_client_requests_total", + Help: "Counter of client requests received by client, call_site, auth version, response code and deadline_type", + }, + []string{ + "client_name", + "grpc_service", + "grpc_method", + "call_site", + "auth_version", + "grpc_code", + "deadline_type", }, - []string{"client_name", "grpc_service", "call_site", "auth_version", "grpc_code", "deadline_type"}, ) type metadataTags struct { @@ -149,12 +155,12 @@ func addMetadataTags(ctx context.Context, grpcMethodType string) metadataTags { return metaTags } -func extractServiceName(fullMethodName string) string { +func extractServiceAndMethodName(fullMethodName string) (string, string) { fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash if i := strings.Index(fullMethodName, "/"); i >= 0 { - return fullMethodName[:i] + return fullMethodName[:i], fullMethodName[i+1:] } - return unknownValue + return unknownValue, unknownValue } func streamRPCType(info *grpc.StreamServerInfo) string { @@ -168,11 +174,12 @@ func streamRPCType(info *grpc.StreamServerInfo) string { func reportWithPrometheusLabels(metaTags metadataTags, fullMethod string, err error) { grpcCode := helper.GrpcCode(err) - serviceName := extractServiceName(fullMethod) + serviceName, methodName := extractServiceAndMethodName(fullMethod) requests.WithLabelValues( metaTags.clientName, // client_name serviceName, // grpc_service + methodName, // grpc_method metaTags.callSite, // call_site metaTags.authVersion, // auth_version grpcCode.String(), // grpc_code diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler_test.go index 6bcfd218dd..48dc2daedf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler/metadatahandler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler/metadatahandler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package metadatahandler import ( @@ -7,8 +9,9 @@ import ( "time" grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/metadata" ) @@ -152,29 +155,40 @@ func TestGRPCTags(t *testing.T) { func Test_extractServiceName(t *testing.T) { tests := []struct { - name string - fullMethodName string - want string + name string + fullMethodName string + wantService, wantMethod string }{ { name: "blank", fullMethodName: "", - want: unknownValue, - }, { + wantService: unknownValue, + wantMethod: unknownValue, + }, + { name: "normal", fullMethodName: "/gitaly.OperationService/method", - want: "gitaly.OperationService", - }, { + wantService: "gitaly.OperationService", + wantMethod: "method", + }, + { name: "malformed", fullMethodName: "//method", - want: "", + wantService: "", + wantMethod: "method", + }, + { + name: "malformed", + fullMethodName: "/gitaly.OperationService/", + wantService: "gitaly.OperationService", + wantMethod: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := extractServiceName(tt.fullMethodName); got != tt.want { - t.Errorf("extractServiceName() = %v, want %v", got, tt.want) - } + gotService, gotMethod := extractServiceAndMethodName(tt.fullMethodName) + assert.Equal(t, tt.wantService, gotService) + assert.Equal(t, tt.wantMethod, gotMethod) }) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/LICENSE b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/LICENSE similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/LICENSE rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/LICENSE diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/panic_handler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/panic_handler.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler/panic_handler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler/panic_handler.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler.go index f6f8777367..41a040a574 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler.go @@ -10,7 +10,7 @@ import ( sentry "github.com/getsentry/sentry-go" grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler_test.go index 18df678675..342709a6e3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler/sentryhandler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler/sentryhandler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package sentryhandler import ( @@ -9,7 +11,7 @@ import ( grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/assignment.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/assignment.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/assignment.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/assignment.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/auth_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/auth_test.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/auth_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/auth_test.go index 55c2f3d11b..9f0cd90123 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/auth_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/auth_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,20 +9,21 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" ) func TestAuthFailures(t *testing.T) { @@ -53,7 +56,7 @@ func TestAuthFailures(t *testing.T) { defer srv.Stop() defer cleanup() - connOpts := append(tc.opts, grpc.WithInsecure()) + connOpts := append(tc.opts, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := dial(serverSocketPath, connOpts) require.NoError(t, err, tc.desc) defer conn.Close() @@ -102,7 +105,7 @@ func TestAuthSuccess(t *testing.T) { defer srv.Stop() defer cleanup() - connOpts := append(tc.opts, grpc.WithInsecure()) + connOpts := append(tc.opts, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := dial(serverSocketPath, connOpts) require.NoError(t, err, tc.desc) defer conn.Close() @@ -160,7 +163,7 @@ func runServer(t *testing.T, token string, required bool) (*grpc.Server, string, coordinator := NewCoordinator(queue, nil, NewNodeManagerRouter(nodeMgr, nil), txMgr, conf, registry) - srv := NewGRPCServer(conf, logEntry, registry, coordinator.StreamDirector, txMgr, nil, nil, nil, nil, nil) + srv := NewGRPCServer(conf, logEntry, registry, coordinator.StreamDirector, txMgr, nil, nil, nil, nil, nil, nil) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(t) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr/error.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr/error.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr/error.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr/error.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config.go index 7c9a2791c1..5af6eccdb6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config.go @@ -6,13 +6,14 @@ import ( "os" "time" - "github.com/pelletier/go-toml" + "github.com/pelletier/go-toml/v2" promclient "github.com/prometheus/client_golang/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) // ElectionStrategy is a Praefect primary election strategy. @@ -40,20 +41,20 @@ const ( minimalSyncRunInterval = time.Minute ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type Failover struct { Enabled bool `toml:"enabled,omitempty"` // ElectionStrategy is the strategy to use for electing primaries nodes. - ElectionStrategy ElectionStrategy `toml:"election_strategy,omitempty"` - ErrorThresholdWindow config.Duration `toml:"error_threshold_window,omitempty"` - WriteErrorThresholdCount uint32 `toml:"write_error_threshold_count,omitempty"` - ReadErrorThresholdCount uint32 `toml:"read_error_threshold_count,omitempty"` + ElectionStrategy ElectionStrategy `toml:"election_strategy,omitempty"` + ErrorThresholdWindow duration.Duration `toml:"error_threshold_window,omitempty"` + WriteErrorThresholdCount uint32 `toml:"write_error_threshold_count,omitempty"` + ReadErrorThresholdCount uint32 `toml:"read_error_threshold_count,omitempty"` // BootstrapInterval allows set a time duration that would be used on startup to make initial health check. // The default value is 1s. - BootstrapInterval config.Duration `toml:"bootstrap_interval,omitempty"` + BootstrapInterval duration.Duration `toml:"bootstrap_interval,omitempty"` // MonitorInterval allows set a time duration that would be used after bootstrap is completed to execute health checks. // The default value is 3s. - MonitorInterval config.Duration `toml:"monitor_interval,omitempty"` + MonitorInterval duration.Duration `toml:"monitor_interval,omitempty"` } // ErrorThresholdsConfigured checks whether returns whether the errors thresholds are configured. If they @@ -82,19 +83,22 @@ func (f Failover) ErrorThresholdsConfigured() (bool, error) { type BackgroundVerification struct { // VerificationInterval determines the duration after a replica due for reverification. // The feature is disabled if verification interval is 0 or below. - VerificationInterval time.Duration `toml:"verification_interval,omitempty"` + VerificationInterval duration.Duration `toml:"verification_interval,omitempty"` + // DeleteInvalidRecords controls whether the background verifier will actually delete the metadata + // records that point to non-existent replicas. + DeleteInvalidRecords bool `toml:"delete_invalid_records"` } // DefaultBackgroundVerificationConfig returns the default background verification configuration. func DefaultBackgroundVerificationConfig() BackgroundVerification { - return BackgroundVerification{} + return BackgroundVerification{VerificationInterval: duration.Duration(7 * 24 * time.Hour)} } // Reconciliation contains reconciliation specific configuration options. type Reconciliation struct { // SchedulingInterval the interval between each automatic reconciliation run. If set to 0, // automatic reconciliation is disabled. - SchedulingInterval config.Duration `toml:"scheduling_interval,omitempty"` + SchedulingInterval duration.Duration `toml:"scheduling_interval,omitempty"` // HistogramBuckets configures the reconciliation scheduling duration histogram's buckets. HistogramBuckets []float64 `toml:"histogram_buckets,omitempty"` } @@ -102,7 +106,7 @@ type Reconciliation struct { // DefaultReconciliationConfig returns the default values for reconciliation configuration. func DefaultReconciliationConfig() Reconciliation { return Reconciliation{ - SchedulingInterval: 5 * config.Duration(time.Minute), + SchedulingInterval: 5 * duration.Duration(time.Minute), HistogramBuckets: promclient.DefBuckets, } } @@ -149,7 +153,7 @@ type Config struct { // Keep for legacy reasons: remove after Omnibus has switched FailoverEnabled bool `toml:"failover_enabled,omitempty"` MemoryQueueEnabled bool `toml:"memory_queue_enabled,omitempty"` - GracefulStopTimeout config.Duration `toml:"graceful_stop_timeout,omitempty"` + GracefulStopTimeout duration.Duration `toml:"graceful_stop_timeout,omitempty"` RepositoriesCleanup RepositoriesCleanup `toml:"repositories_cleanup,omitempty"` } @@ -292,16 +296,16 @@ func (c *Config) NeedsSQL() bool { func (c *Config) setDefaults() { if c.GracefulStopTimeout.Duration() == 0 { - c.GracefulStopTimeout = config.Duration(time.Minute) + c.GracefulStopTimeout = duration.Duration(time.Minute) } if c.Failover.Enabled { if c.Failover.BootstrapInterval.Duration() == 0 { - c.Failover.BootstrapInterval = config.Duration(time.Second) + c.Failover.BootstrapInterval = duration.Duration(time.Second) } if c.Failover.MonitorInterval.Duration() == 0 { - c.Failover.MonitorInterval = config.Duration(3 * time.Second) + c.Failover.MonitorInterval = duration.Duration(3 * time.Second) } } } @@ -380,9 +384,9 @@ type RepositoriesCleanup struct { // CheckInterval is a time period used to check if operation should be executed. // It is recommended to keep it less than run_interval configuration as some // nodes may be out of service, so they can be stale for too long. - CheckInterval config.Duration `toml:"check_interval,omitempty"` + CheckInterval duration.Duration `toml:"check_interval,omitempty"` // RunInterval: the check runs if the previous operation was done at least RunInterval before. - RunInterval config.Duration `toml:"run_interval,omitempty"` + RunInterval duration.Duration `toml:"run_interval,omitempty"` // RepositoriesInBatch is the number of repositories to pass as a batch for processing. RepositoriesInBatch int `toml:"repositories_in_batch,omitempty"` } @@ -390,8 +394,8 @@ type RepositoriesCleanup struct { // DefaultRepositoriesCleanup contains default configuration values for the RepositoriesCleanup. func DefaultRepositoriesCleanup() RepositoriesCleanup { return RepositoriesCleanup{ - CheckInterval: config.Duration(30 * time.Minute), - RunInterval: config.Duration(24 * time.Hour), + CheckInterval: duration.Duration(30 * time.Minute), + RunInterval: duration.Duration(24 * time.Hour), RepositoriesInBatch: 16, } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config_test.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config_test.go index aa0d0b3c57..b0e1879f6f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/config_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/config_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package config import ( @@ -7,12 +9,13 @@ import ( "testing" "time" - "github.com/pelletier/go-toml" + "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" ) func TestConfigValidation(t *testing.T) { @@ -203,14 +206,14 @@ func TestConfigValidation(t *testing.T) { { desc: "repositories_cleanup minimal duration is too low", changeConfig: func(cfg *Config) { - cfg.RepositoriesCleanup.CheckInterval = config.Duration(minimalSyncCheckInterval - time.Nanosecond) + cfg.RepositoriesCleanup.CheckInterval = duration.Duration(minimalSyncCheckInterval - time.Nanosecond) }, errMsg: `repositories_cleanup.check_interval is less then 1m0s, which could lead to a database performance problem`, }, { desc: "repositories_cleanup minimal duration is too low", changeConfig: func(cfg *Config) { - cfg.RepositoriesCleanup.RunInterval = config.Duration(minimalSyncRunInterval - time.Nanosecond) + cfg.RepositoriesCleanup.RunInterval = duration.Duration(minimalSyncRunInterval - time.Nanosecond) }, errMsg: `repositories_cleanup.run_interval is less then 1m0s, which could lead to a database performance problem`, }, @@ -288,7 +291,7 @@ func TestConfigParsing(t *testing.T) { }, }, Prometheus: prometheus.Config{ - ScrapeTimeout: time.Second, + ScrapeTimeout: duration.Duration(time.Second), GRPCLatencyBuckets: []float64{0.1, 0.2, 0.3}, }, PrometheusExcludeDatabaseFromDefaultMetrics: true, @@ -315,28 +318,29 @@ func TestConfigParsing(t *testing.T) { }, }, MemoryQueueEnabled: true, - GracefulStopTimeout: config.Duration(30 * time.Second), + GracefulStopTimeout: duration.Duration(30 * time.Second), Reconciliation: Reconciliation{ - SchedulingInterval: config.Duration(time.Minute), + SchedulingInterval: duration.Duration(time.Minute), HistogramBuckets: []float64{1, 2, 3, 4, 5}, }, Replication: Replication{BatchSize: 1, ParallelStorageProcessingWorkers: 2}, Failover: Failover{ Enabled: true, ElectionStrategy: ElectionStrategyPerRepository, - ErrorThresholdWindow: config.Duration(20 * time.Second), + ErrorThresholdWindow: duration.Duration(20 * time.Second), WriteErrorThresholdCount: 1500, ReadErrorThresholdCount: 100, - BootstrapInterval: config.Duration(1 * time.Second), - MonitorInterval: config.Duration(3 * time.Second), + BootstrapInterval: duration.Duration(1 * time.Second), + MonitorInterval: duration.Duration(3 * time.Second), }, RepositoriesCleanup: RepositoriesCleanup{ - CheckInterval: config.Duration(time.Second), - RunInterval: config.Duration(3 * time.Second), + CheckInterval: duration.Duration(time.Second), + RunInterval: duration.Duration(3 * time.Second), RepositoriesInBatch: 10, }, BackgroundVerification: BackgroundVerification{ - VerificationInterval: 24 * time.Hour, + VerificationInterval: duration.Duration(24 * time.Hour), + DeleteInvalidRecords: true, }, }, }, @@ -344,7 +348,7 @@ func TestConfigParsing(t *testing.T) { desc: "overwriting default values in the config", filePath: "testdata/config.overwritedefaults.toml", expected: Config{ - GracefulStopTimeout: config.Duration(time.Minute), + GracefulStopTimeout: duration.Duration(time.Minute), Reconciliation: Reconciliation{ SchedulingInterval: 0, HistogramBuckets: []float64{1, 2, 3, 4, 5}, @@ -355,12 +359,12 @@ func TestConfigParsing(t *testing.T) { Failover: Failover{ Enabled: false, ElectionStrategy: "local", - BootstrapInterval: config.Duration(5 * time.Second), - MonitorInterval: config.Duration(10 * time.Second), + BootstrapInterval: duration.Duration(5 * time.Second), + MonitorInterval: duration.Duration(10 * time.Second), }, RepositoriesCleanup: RepositoriesCleanup{ - CheckInterval: config.Duration(time.Second), - RunInterval: config.Duration(4 * time.Second), + CheckInterval: duration.Duration(time.Second), + RunInterval: duration.Duration(4 * time.Second), RepositoriesInBatch: 11, }, BackgroundVerification: DefaultBackgroundVerificationConfig(), @@ -370,7 +374,7 @@ func TestConfigParsing(t *testing.T) { desc: "empty config yields default values", filePath: "testdata/config.empty.toml", expected: Config{ - GracefulStopTimeout: config.Duration(time.Minute), + GracefulStopTimeout: duration.Duration(time.Minute), Prometheus: prometheus.DefaultConfig(), PrometheusExcludeDatabaseFromDefaultMetrics: true, Reconciliation: DefaultReconciliationConfig(), @@ -378,12 +382,12 @@ func TestConfigParsing(t *testing.T) { Failover: Failover{ Enabled: true, ElectionStrategy: ElectionStrategyPerRepository, - BootstrapInterval: config.Duration(time.Second), - MonitorInterval: config.Duration(3 * time.Second), + BootstrapInterval: duration.Duration(time.Second), + MonitorInterval: duration.Duration(3 * time.Second), }, RepositoriesCleanup: RepositoriesCleanup{ - CheckInterval: config.Duration(30 * time.Minute), - RunInterval: config.Duration(24 * time.Hour), + CheckInterval: duration.Duration(30 * time.Minute), + RunInterval: duration.Duration(24 * time.Hour), RepositoriesInBatch: 16, }, BackgroundVerification: DefaultBackgroundVerificationConfig(), @@ -518,6 +522,6 @@ func TestSerialization(t *testing.T) { t.Run("partially set", func(t *testing.T) { out.Reset() require.NoError(t, encoder.Encode(Config{ListenAddr: "localhost:5640"})) - require.Equal(t, "listen_addr = \"localhost:5640\"\n", out.String()) + require.Equal(t, "listen_addr = 'localhost:5640'\n", out.String()) }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/log.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/log.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/log.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/log.go index 10a27f8d0b..6c55e38cd7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/log.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/log.go @@ -2,7 +2,7 @@ package config import ( "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) // ConfigureLogger applies the settings from the configuration file to the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node.go index 6347eb8d94..7ed25e9551 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node.go @@ -12,7 +12,7 @@ type Node struct { Token string `toml:"token,omitempty"` } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (n Node) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "storage": n.Storage, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node_test.go index 31756fa09a..56bac085cb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/node_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/node_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package config import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.empty.toml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.empty.toml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.empty.toml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.empty.toml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.overwritedefaults.toml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.overwritedefaults.toml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.overwritedefaults.toml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.overwritedefaults.toml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.toml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.toml similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.toml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.toml index 3f2a370e28..f7d591eee0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config/testdata/config.toml +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config/testdata/config.toml @@ -8,6 +8,7 @@ graceful_stop_timeout = "30s" [background_verification] verification_interval = "24h" +delete_invalid_records = true [replication] batch_size = 1 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator.go index 82c32fcd00..5099a23917 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator.go @@ -4,28 +4,27 @@ import ( "context" "errors" "fmt" - "strconv" "sync" "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - gitalyerrors "gitlab.com/gitlab-org/gitaly/v14/internal/errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "golang.org/x/sync/errgroup" grpc_metadata "google.golang.org/grpc/metadata" @@ -166,65 +165,6 @@ func getReplicationDetails(methodName string, m proto.Message) (datastore.Change return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) } return datastore.RenameRepo, datastore.Params{"RelativePath": req.RelativePath}, nil - case "/gitaly.RepositoryService/GarbageCollect": - req, ok := m.(*gitalypb.GarbageCollectRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.GarbageCollect, datastore.Params{ - "CreateBitmap": req.GetCreateBitmap(), - "Prune": req.GetPrune(), - }, nil - case "/gitaly.RepositoryService/RepackFull": - req, ok := m.(*gitalypb.RepackFullRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.RepackFull, datastore.Params{"CreateBitmap": req.GetCreateBitmap()}, nil - case "/gitaly.RepositoryService/RepackIncremental": - req, ok := m.(*gitalypb.RepackIncrementalRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.RepackIncremental, nil, nil - case "/gitaly.RepositoryService/Cleanup": - req, ok := m.(*gitalypb.CleanupRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.Cleanup, nil, nil - case "/gitaly.RepositoryService/WriteCommitGraph": - req, ok := m.(*gitalypb.WriteCommitGraphRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.WriteCommitGraph, datastore.Params{ - "SplitStrategy": req.GetSplitStrategy(), - }, nil - case "/gitaly.RepositoryService/MidxRepack": - req, ok := m.(*gitalypb.MidxRepackRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.MidxRepack, nil, nil - case "/gitaly.RepositoryService/OptimizeRepository": - req, ok := m.(*gitalypb.OptimizeRepositoryRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.OptimizeRepository, nil, nil - case "/gitaly.RepositoryService/PruneUnreachableObjects": - req, ok := m.(*gitalypb.PruneUnreachableObjectsRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.PruneUnreachableObjects, nil, nil - case "/gitaly.RefService/PackRefs": - req, ok := m.(*gitalypb.PackRefsRequest) - if !ok { - return "", nil, fmt.Errorf("protocol changed: for method %q expected message type '%T', got '%T'", methodName, req, m) - } - return datastore.PackRefs, nil, nil default: return datastore.UpdateRepo, nil, nil } @@ -295,12 +235,12 @@ func NewCoordinator( return coordinator } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (c *Coordinator) Describe(descs chan<- *prometheus.Desc) { prometheus.DescribeByCollect(c, descs) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (c *Coordinator) Collect(metrics chan<- prometheus.Metric) { c.votersMetric.Collect(metrics) c.txReplicationCountMetric.Collect(metrics) @@ -371,6 +311,8 @@ func (c *Coordinator) accessorStreamParameters(ctx context.Context, call grpcCal return nil, fmt.Errorf("accessor call: route repository accessor: %w", err) } + route.addLogFields(ctx) + b, err := rewrittenRepositoryMessage(call.methodInfo, call.msg, route.Node.Storage, route.ReplicaPath, "") if err != nil { return nil, fmt.Errorf("accessor call: rewrite storage: %w", err) @@ -459,6 +401,8 @@ func (c *Coordinator) mutatorStreamParameters(ctx context.Context, call grpcCall } } + route.addLogFields(ctx) + primaryMessage, err := rewrittenRepositoryMessage(call.methodInfo, call.msg, route.Primary.Storage, route.ReplicaPath, route.AdditionalReplicaPath) if err != nil { return nil, fmt.Errorf("mutator call: rewrite storage: %w", err) @@ -543,6 +487,7 @@ func (c *Coordinator) mutatorStreamParameters(ctx context.Context, call grpcCall route.RepositoryID, virtualStorage, targetRepo, + route.ReplicaPath, route.Primary.Storage, nil, append(routerNodesToStorages(route.Secondaries), route.ReplicationTargets...), @@ -585,6 +530,8 @@ func (c *Coordinator) maintenanceStreamParameters(ctx context.Context, call grpc return nil, fmt.Errorf("routing repository maintenance: %w", err) } + route.addLogFields(ctx) + peerCtx := streamParametersContext(ctx) nodeDests := make([]proxy.Destination, 0, len(route.Nodes)) @@ -641,8 +588,6 @@ func (c *Coordinator) maintenanceStreamParameters(ctx context.Context, call grpc // streamParametersContexts converts the contexts with incoming metadata into a context that is // usable by peer Gitaly nodes. func streamParametersContext(ctx context.Context) context.Context { - outgoingCtx := metadata.IncomingToOutgoing(ctx) - // When upgrading Gitaly nodes where the upgrade contains feature flag default changes, then // there will be a window where a subset of Gitaly nodes has a different understanding of // the current default value. If the feature flag wasn't set explicitly on upgrade by @@ -666,17 +611,20 @@ func streamParametersContext(ctx context.Context) context.Context { // Praefect. But given that feature flags should be introduced with a default value of // `false` to account for zero-dodwntime upgrades, the view would also be consistent in that // case. - rawFeatureFlags := featureflag.RawFromContext(ctx) - if rawFeatureFlags == nil { - rawFeatureFlags = map[string]string{} + + explicitlySetFlags := map[string]bool{} + for flag := range featureflag.FromContext(ctx) { + explicitlySetFlags[flag.Name] = true } - for _, ff := range featureflag.All { - if _, ok := rawFeatureFlags[ff.MetadataKey()]; !ok { - rawFeatureFlags[ff.MetadataKey()] = strconv.FormatBool(ff.OnByDefault) + outgoingCtx := metadata.IncomingToOutgoing(ctx) + for _, flag := range featureflag.DefinedFlags() { + if !explicitlySetFlags[flag.Name] { + outgoingCtx = featureflag.OutgoingCtxWithFeatureFlag( + outgoingCtx, flag, flag.OnByDefault, + ) } } - outgoingCtx = featureflag.OutgoingWithRaw(outgoingCtx, rawFeatureFlags) return outgoingCtx } @@ -770,6 +718,8 @@ func (c *Coordinator) accessorStorageStreamParameters(ctx context.Context, mi pr return nil, helper.ErrInternalf("accessor storage scoped: route storage accessor %q: %w", virtualStorage, err) } + node.addLogFields(ctx) + b, err := rewrittenStorageMessage(mi, msg, node.Storage) if err != nil { return nil, helper.ErrInvalidArgument(fmt.Errorf("accessor storage scoped: %w", err)) @@ -796,6 +746,8 @@ func (c *Coordinator) mutatorStorageStreamParameters(ctx context.Context, mi pro return nil, helper.ErrInternalf("mutator storage scoped: get shard %q: %w", virtualStorage, err) } + route.addLogFields(ctx) + b, err := rewrittenStorageMessage(mi, msg, route.Primary.Storage) if err != nil { return nil, helper.ErrInvalidArgument(fmt.Errorf("mutator storage scoped: %w", err)) @@ -884,7 +836,7 @@ func (c *Coordinator) createTransactionFinalizer( } return c.newRequestFinalizer( - ctx, route.RepositoryID, virtualStorage, targetRepo, route.Primary.Storage, + ctx, route.RepositoryID, virtualStorage, targetRepo, route.ReplicaPath, route.Primary.Storage, updated, outdated, change, params, cause)() } } @@ -1037,10 +989,11 @@ func routerNodesToStorages(nodes []RouterNode) []string { } func (c *Coordinator) newRequestFinalizer( - ctx context.Context, + originalCtx context.Context, repositoryID int64, virtualStorage string, targetRepo *gitalypb.Repository, + replicaPath string, primary string, updatedSecondaries []string, outdatedSecondaries []string, @@ -1053,7 +1006,7 @@ func (c *Coordinator) newRequestFinalizer( // canceled. We need to perform the database updates regardless whether the request was canceled or not as // the primary replica could have been dirtied and secondaries become outdated. Otherwise we'd have no idea of // the possible changes performed on the disk. - ctx, cancel := context.WithTimeout(helper.SuppressCancellation(ctx), 30*time.Second) + ctx, cancel := context.WithTimeout(helper.SuppressCancellation(originalCtx), 30*time.Second) defer cancel() log := ctxlogrus.Extract(ctx).WithFields(logrus.Fields{ @@ -1097,7 +1050,7 @@ func (c *Coordinator) newRequestFinalizer( repositoryID, virtualStorage, targetRepo.GetRelativePath(), - targetRepo.GetRelativePath(), + replicaPath, primary, updatedSecondaries, outdatedSecondaries, @@ -1137,7 +1090,16 @@ func (c *Coordinator) newRequestFinalizer( return nil }) } - return g.Wait() + + if err := g.Wait(); err != nil { + return err + } + + // The cancellation signal is suppressed earlier in the function, so we'd return no error if the + // orignal context exceeded its deadline while running the request finalizer. If there were + // no other errors, return the possible error from the context so we don't return OK code for + // failed requests. + return originalCtx.Err() } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_pg_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_pg_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_pg_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_pg_test.go index e35da6b5d4..a1bc770949 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_pg_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_pg_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -10,16 +12,16 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/peer" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_test.go index 3b4d53d157..5722e8abcf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/coordinator_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/coordinator_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -17,29 +19,31 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - gitaly_metadata "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + gitaly_metadata "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -549,6 +553,293 @@ func TestStreamDirector_maintenance(t *testing.T) { } } +func TestStreamDirector_maintenanceRPCs(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + primaryStorage := "internal-gitaly-0" + primaryServer, primarySocketPath := runMockMaintenanceServer( + t, testcfg.Build(t, testcfg.WithStorages(primaryStorage)), + ) + + secondaryStorage := "internal-gitaly-1" + secondaryServer, secondarySocketPath := runMockMaintenanceServer(t, testcfg.Build( + t, testcfg.WithStorages(secondaryStorage)), + ) + + cc, _, cleanup := RunPraefectServer(t, ctx, config.Config{ + VirtualStorages: []*config.VirtualStorage{ + { + Name: "default", + Nodes: []*config.Node{ + { + Storage: primaryStorage, + Address: primarySocketPath, + }, + { + Storage: secondaryStorage, + Address: secondarySocketPath, + }, + }, + }, + }, + }, BuildOptions{}) + defer cleanup() + + repository := &gitalypb.Repository{ + StorageName: "default", + RelativePath: gittest.NewRepositoryName(t, true), + } + primaryRepository := &gitalypb.Repository{ + StorageName: primaryStorage, + RelativePath: repository.RelativePath, + } + secondaryRepository := &gitalypb.Repository{ + StorageName: secondaryStorage, + RelativePath: repository.RelativePath, + } + + repositoryClient := gitalypb.NewRepositoryServiceClient(cc) + refClient := gitalypb.NewRefServiceClient(cc) + + for _, tc := range []struct { + desc string + maintenanceFunc func(t *testing.T) + expectedPrimaryRequest proto.Message + expectedSecondaryRequest proto.Message + }{ + { + desc: "GarbageCollect", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{ + Repository: repository, + CreateBitmap: true, + Prune: true, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.GarbageCollectRequest{ + Repository: primaryRepository, + CreateBitmap: true, + Prune: true, + }, + expectedSecondaryRequest: &gitalypb.GarbageCollectRequest{ + Repository: secondaryRepository, + CreateBitmap: true, + Prune: true, + }, + }, + { + desc: "RepackFull", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.RepackFull(ctx, &gitalypb.RepackFullRequest{ + Repository: repository, + CreateBitmap: true, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.RepackFullRequest{ + Repository: primaryRepository, + CreateBitmap: true, + }, + expectedSecondaryRequest: &gitalypb.RepackFullRequest{ + Repository: secondaryRepository, + CreateBitmap: true, + }, + }, + { + desc: "RepackIncremental", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.RepackIncremental(ctx, &gitalypb.RepackIncrementalRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.RepackIncrementalRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.RepackIncrementalRequest{ + Repository: secondaryRepository, + }, + }, + { + desc: "Cleanup", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.Cleanup(ctx, &gitalypb.CleanupRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.CleanupRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.CleanupRequest{ + Repository: secondaryRepository, + }, + }, + { + desc: "WriteCommitGraph", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.WriteCommitGraph(ctx, &gitalypb.WriteCommitGraphRequest{ + Repository: repository, + // This is not a valid split strategy, but we currently only support a + // single default split strategy with value 0. So we just test with an + // invalid split strategy to check that a non-default value gets properly + // replicated. + SplitStrategy: 1, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.WriteCommitGraphRequest{ + Repository: primaryRepository, + SplitStrategy: 1, + }, + expectedSecondaryRequest: &gitalypb.WriteCommitGraphRequest{ + Repository: secondaryRepository, + SplitStrategy: 1, + }, + }, + { + desc: "MidxRepack", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := repositoryClient.MidxRepack(ctx, &gitalypb.MidxRepackRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.MidxRepackRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.MidxRepackRequest{ + Repository: secondaryRepository, + }, + }, + { + desc: "OptimizeRepository", + maintenanceFunc: func(t *testing.T) { + _, err := repositoryClient.OptimizeRepository(ctx, &gitalypb.OptimizeRepositoryRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.OptimizeRepositoryRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.OptimizeRepositoryRequest{ + Repository: secondaryRepository, + }, + }, + { + desc: "PruneUnreachableObjects", + maintenanceFunc: func(t *testing.T) { + _, err := repositoryClient.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.PruneUnreachableObjectsRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.PruneUnreachableObjectsRequest{ + Repository: secondaryRepository, + }, + }, + { + desc: "PackRefs", + maintenanceFunc: func(t *testing.T) { + //nolint:staticcheck + _, err := refClient.PackRefs(ctx, &gitalypb.PackRefsRequest{ + Repository: repository, + }) + require.NoError(t, err) + }, + expectedPrimaryRequest: &gitalypb.PackRefsRequest{ + Repository: primaryRepository, + }, + expectedSecondaryRequest: &gitalypb.PackRefsRequest{ + Repository: secondaryRepository, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tc.maintenanceFunc(t) + testhelper.ProtoEqual(t, tc.expectedPrimaryRequest, <-primaryServer.requestCh) + testhelper.ProtoEqual(t, tc.expectedSecondaryRequest, <-secondaryServer.requestCh) + }) + } +} + +type mockMaintenanceServer struct { + requestCh chan proto.Message + gitalypb.UnimplementedRepositoryServiceServer + gitalypb.UnimplementedRefServiceServer +} + +func runMockMaintenanceServer(t *testing.T, cfg gconfig.Cfg) (*mockMaintenanceServer, string) { + server := &mockMaintenanceServer{ + requestCh: make(chan proto.Message, 1), + } + + addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { + gitalypb.RegisterRepositoryServiceServer(srv, server) + gitalypb.RegisterRefServiceServer(srv, server) + }, testserver.WithDisablePraefect()) + + return server, addr +} + +func (m *mockMaintenanceServer) GarbageCollect(ctx context.Context, in *gitalypb.GarbageCollectRequest) (*gitalypb.GarbageCollectResponse, error) { + m.requestCh <- in + return &gitalypb.GarbageCollectResponse{}, nil +} + +func (m *mockMaintenanceServer) RepackFull(ctx context.Context, in *gitalypb.RepackFullRequest) (*gitalypb.RepackFullResponse, error) { + m.requestCh <- in + return &gitalypb.RepackFullResponse{}, nil +} + +func (m *mockMaintenanceServer) RepackIncremental(ctx context.Context, in *gitalypb.RepackIncrementalRequest) (*gitalypb.RepackIncrementalResponse, error) { + m.requestCh <- in + return &gitalypb.RepackIncrementalResponse{}, nil +} + +func (m *mockMaintenanceServer) Cleanup(ctx context.Context, in *gitalypb.CleanupRequest) (*gitalypb.CleanupResponse, error) { + m.requestCh <- in + return &gitalypb.CleanupResponse{}, nil +} + +func (m *mockMaintenanceServer) WriteCommitGraph(ctx context.Context, in *gitalypb.WriteCommitGraphRequest) (*gitalypb.WriteCommitGraphResponse, error) { + m.requestCh <- in + return &gitalypb.WriteCommitGraphResponse{}, nil +} + +func (m *mockMaintenanceServer) MidxRepack(ctx context.Context, in *gitalypb.MidxRepackRequest) (*gitalypb.MidxRepackResponse, error) { + m.requestCh <- in + return &gitalypb.MidxRepackResponse{}, nil +} + +func (m *mockMaintenanceServer) OptimizeRepository(ctx context.Context, in *gitalypb.OptimizeRepositoryRequest) (*gitalypb.OptimizeRepositoryResponse, error) { + m.requestCh <- in + return &gitalypb.OptimizeRepositoryResponse{}, nil +} + +func (m *mockMaintenanceServer) PruneUnreachableObjects(ctx context.Context, in *gitalypb.PruneUnreachableObjectsRequest) (*gitalypb.PruneUnreachableObjectsResponse, error) { + m.requestCh <- in + return &gitalypb.PruneUnreachableObjectsResponse{}, nil +} + +func (m *mockMaintenanceServer) PackRefs(ctx context.Context, in *gitalypb.PackRefsRequest) (*gitalypb.PackRefsResponse, error) { + m.requestCh <- in + return &gitalypb.PackRefsResponse{}, nil +} + type mockRouter struct { Router routeRepositoryAccessorFunc func(ctx context.Context, virtualStorage, relativePath string, forcePrimary bool) (RepositoryAccessorRoute, error) @@ -1278,10 +1569,10 @@ func TestCoordinatorEnqueueFailure(t *testing.T) { require.NoError(t, err) ctx := testhelper.Context(t) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withAnnotations: r, - withQueue: queueInterceptor, - withBackends: withMockBackends(t, map[string]mock.SimpleServiceServer{ + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithAnnotations: r, + WithQueue: queueInterceptor, + WithBackends: WithMockBackends(t, map[string]mock.SimpleServiceServer{ conf.VirtualStorages[0].Nodes[0].Storage: ms, conf.VirtualStorages[0].Nodes[1].Storage: ms, }), @@ -1655,10 +1946,10 @@ func TestCoordinator_grpcErrorHandling(t *testing.T) { }) } - praefectConn, _, cleanup := runPraefectServer(t, ctx, praefectConfig, buildOptions{ + praefectConn, _, cleanup := RunPraefectServer(t, ctx, praefectConfig, BuildOptions{ // Set up a mock manager which sets up primary/secondaries and pretends that all nodes are // healthy. We need fixed roles and unhealthy nodes will not take part in transactions. - withNodeMgr: &nodes.MockManager{ + WithNodeMgr: &nodes.MockManager{ Storage: testhelper.DefaultStorageName, GetShardFunc: func(shardName string) (nodes.Shard, error) { require.Equal(t, testhelper.DefaultStorageName, shardName) @@ -1673,7 +1964,7 @@ func TestCoordinator_grpcErrorHandling(t *testing.T) { }, // Set up a mock repsoitory store pretending that all nodes are consistent. Only consistent // nodes will take part in transactions. - withRepoStore: datastore.MockRepositoryStore{ + WithRepoStore: datastore.MockRepositoryStore{ GetReplicaPathFunc: func(ctx context.Context, repositoryID int64) (string, error) { return repoProto.GetRelativePath(), nil }, @@ -2319,46 +2610,55 @@ func TestNewRequestFinalizer_contextIsDisjointedFromTheRPC(t *testing.T) { ctx, cancel := context.WithDeadline(context.WithValue(ctx, ctxKey{}, "value"), parentDeadline) defer cancel() - requireSuppressedCancellation := func(t testing.TB, ctx context.Context) { + requireSuppressedCancellation := func(tb testing.TB, ctx context.Context) { deadline, ok := ctx.Deadline() - require.True(t, ok) - require.NotEqual(t, parentDeadline, deadline) - require.Equal(t, ctx.Value(ctxKey{}), "value") - require.Nil(t, ctx.Err()) + require.True(tb, ok) + require.NotEqual(tb, parentDeadline, deadline) + require.Equal(tb, ctx.Value(ctxKey{}), "value") + require.Nil(tb, ctx.Err()) select { case <-ctx.Done(): - t.Fatal("context should not be canceled if the parent is canceled") + tb.Fatal("context should not be canceled if the parent is canceled") default: - require.NotNil(t, ctx.Done()) + require.NotNil(tb, ctx.Done()) } } err := errors.New("error") for _, tc := range []struct { - change datastore.ChangeType - errMsg string + desc string + change datastore.ChangeType + errMsg string + enqueueError error }{ { + desc: "increment generation receives suppressed cancellation", change: datastore.UpdateRepo, errMsg: "increment generation: error", }, { + desc: "rename repository receives suppressed cancellation", change: datastore.RenameRepo, errMsg: "rename repository: error", }, { - change: "replication jobs only", - errMsg: "enqueue replication event: error", + desc: "enqueue receives suppressed cancellation", + errMsg: "enqueue replication event: error", + enqueueError: err, + }, + { + desc: "original context error is returned", + errMsg: context.DeadlineExceeded.Error(), }, } { - t.Run(string(tc.change), func(t *testing.T) { + t.Run(tc.desc, func(t *testing.T) { require.EqualError(t, NewCoordinator( &datastore.MockReplicationEventQueue{ EnqueueFunc: func(ctx context.Context, _ datastore.ReplicationEvent) (datastore.ReplicationEvent, error) { requireSuppressedCancellation(t, ctx) - return datastore.ReplicationEvent{}, err + return datastore.ReplicationEvent{}, tc.enqueueError }, }, datastore.MockRepositoryStore{ @@ -2384,6 +2684,7 @@ func TestNewRequestFinalizer_contextIsDisjointedFromTheRPC(t *testing.T) { 0, "virtual storage", &gitalypb.Repository{}, + "replica-path", "primary", []string{}, []string{"secondary"}, @@ -2399,8 +2700,8 @@ func TestNewRequestFinalizer_contextIsDisjointedFromTheRPC(t *testing.T) { func TestStreamParametersContext(t *testing.T) { // Because we're using NewFeatureFlag, they'll end up in the All array. - enabledFF := featureflag.NewFeatureFlag("default-enabled", true) - disabledFF := featureflag.NewFeatureFlag("default-disabled", false) + enabledFF := featureflag.NewFeatureFlag("default_enabled", "", "", true) + disabledFF := featureflag.NewFeatureFlag("default_disabled", "", "", false) type expectedFlag struct { flag featureflag.FeatureFlag @@ -2409,7 +2710,7 @@ func TestStreamParametersContext(t *testing.T) { expectedFlags := func(overrides ...expectedFlag) []expectedFlag { flagValues := map[featureflag.FeatureFlag]bool{} - for _, flag := range featureflag.All { + for _, flag := range featureflag.DefinedFlags() { flagValues[flag] = flag.OnByDefault } for _, override := range overrides { @@ -2513,10 +2814,6 @@ func TestStreamParametersContext(t *testing.T) { ), expectedOutgoingMD: metadata.Join( metadataForFlags(expectedFlags()), - metadata.Pairs( - enabledFF.MetadataKey(), "true", - disabledFF.MetadataKey(), "false", - ), ), expectedFlags: expectedFlags(), }, @@ -2537,10 +2834,6 @@ func TestStreamParametersContext(t *testing.T) { expectedFlag{flag: enabledFF, enabled: false}, expectedFlag{flag: disabledFF, enabled: true}, )), - metadata.Pairs( - enabledFF.MetadataKey(), "false", - disabledFF.MetadataKey(), "true", - ), ), expectedFlags: expectedFlags( expectedFlag{flag: enabledFF, enabled: false}, @@ -2566,7 +2859,6 @@ func TestStreamParametersContext(t *testing.T) { expectedFlag{flag: disabledFF, enabled: true}, )), metadata.Pairs( - disabledFF.MetadataKey(), "true", "incoming", "value", ), ), diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/advisorylock/const.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/advisorylock/const.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/advisorylock/const.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/advisorylock/const.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment.go index 540dff2317..9cfda0aca3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) // InvalidArgumentError tags the error as being caused by an invalid argument. @@ -37,7 +37,7 @@ func NewAssignmentStore(db glsql.Querier, configuredStorages map[string][]string return AssignmentStore{db: db, configuredStorages: configuredStorages} } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s AssignmentStore) GetHostAssignments(ctx context.Context, virtualStorage string, repositoryID int64) ([]string, error) { configuredStorages, ok := s.configuredStorages[virtualStorage] if !ok { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment_test.go index fe70cd9076..61ac24ec46 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/assignment_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/assignment_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -6,10 +8,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestAssignmentStore_GetHostAssignments(t *testing.T) { @@ -117,16 +119,16 @@ func TestAssignmentStore_SetReplicationFactor(t *testing.T) { type matcher func(testing.TB, []string) equal := func(expected []string) matcher { - return func(t testing.TB, actual []string) { - t.Helper() - require.Equal(t, expected, actual) + return func(tb testing.TB, actual []string) { + tb.Helper() + require.Equal(tb, expected, actual) } } contains := func(expecteds ...[]string) matcher { - return func(t testing.TB, actual []string) { - t.Helper() - require.Contains(t, expecteds, actual) + return func(tb testing.TB, actual []string) { + tb.Helper() + require.Contains(tb, expecteds, actual) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector.go index cd9bbfc289..5e1fdbd8e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector.go @@ -7,20 +7,10 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) var ( - // This is kept for backwards compatibility as some alerting rules depend on this. - // The unavailable repositories is a more accurate description for the metric and - // is exported below so we can migrate to it. - descReadOnlyRepositories = prometheus.NewDesc( - "gitaly_praefect_read_only_repositories", - "Number of repositories in read-only mode within a virtual storage.", - []string{"virtual_storage"}, - nil, - ) - descUnavailableRepositories = prometheus.NewDesc( "gitaly_praefect_unavailable_repositories", "Number of repositories that have no healthy, up to date replicas.", @@ -34,11 +24,6 @@ var ( []string{"virtual_storage", "target_node", "state"}, nil, ) - - descriptions = []*prometheus.Desc{ - descReadOnlyRepositories, - descUnavailableRepositories, - } ) // RepositoryStoreCollector collects metrics from the RepositoryStore. @@ -64,28 +49,24 @@ func NewRepositoryStoreCollector( } } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (c *RepositoryStoreCollector) Describe(ch chan<- *prometheus.Desc) { - for _, desc := range descriptions { - ch <- desc - } + ch <- descUnavailableRepositories } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (c *RepositoryStoreCollector) Collect(ch chan<- prometheus.Metric) { ctx, cancel := context.WithTimeout(context.TODO(), c.timeout) defer cancel() unavailableCounts, err := CountUnavailableRepositories(ctx, c.db, c.virtualStorages) if err != nil { - c.log.WithError(err).Error("failed collecting read-only repository count metric") + c.log.WithError(err).Error("failed collecting unavailable repository count metric") return } for _, vs := range c.virtualStorages { - for _, desc := range descriptions { - ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(unavailableCounts[vs]), vs) - } + ch <- prometheus.MustNewConstMetric(descUnavailableRepositories, prometheus.GaugeValue, float64(unavailableCounts[vs]), vs) } } @@ -129,7 +110,7 @@ type QueueDepthCollector struct { db glsql.Querier } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (q *QueueDepthCollector) Describe(ch chan<- *prometheus.Desc) { ch <- descReplicationQueueDepth } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector_test.go index c2e733268f..e01f6cd53c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/collector_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/collector_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -16,8 +18,8 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestRepositoryStoreCollector(t *testing.T) { @@ -204,17 +206,13 @@ func TestRepositoryStoreCollector(t *testing.T) { logger, hook := test.NewNullLogger() c := NewRepositoryStoreCollector(logger, []string{"virtual-storage-1", "virtual-storage-2"}, tx, timeout) err := testutil.CollectAndCompare(c, strings.NewReader(fmt.Sprintf(` -# HELP gitaly_praefect_read_only_repositories Number of repositories in read-only mode within a virtual storage. -# TYPE gitaly_praefect_read_only_repositories gauge -gitaly_praefect_read_only_repositories{virtual_storage="virtual-storage-1"} %d -gitaly_praefect_read_only_repositories{virtual_storage="virtual-storage-2"} 0 # HELP gitaly_praefect_unavailable_repositories Number of repositories that have no healthy, up to date replicas. # TYPE gitaly_praefect_unavailable_repositories gauge gitaly_praefect_unavailable_repositories{virtual_storage="virtual-storage-1"} %d gitaly_praefect_unavailable_repositories{virtual_storage="virtual-storage-2"} 0 - `, tc.count, tc.count))) + `, tc.count))) if tc.error != nil { - require.Equal(t, "failed collecting read-only repository count metric", hook.Entries[0].Message) + require.Equal(t, "failed collecting unavailable repository count metric", hook.Entries[0].Message) require.Equal(t, logrus.Fields{"error": tc.error, "component": "RepositoryStoreCollector"}, hook.Entries[0].Data) return } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/datastore.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/datastore.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/datastore.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/datastore.go index 2e7497e546..48e9df6487 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/datastore.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/datastore.go @@ -47,24 +47,6 @@ const ( DeleteReplica = ChangeType("delete_replica") // RenameRepo is when a replication renames repo RenameRepo = ChangeType("rename") - // GarbageCollect is when replication runs gc - GarbageCollect = ChangeType("gc") - // RepackFull is when replication runs a full repack - RepackFull = ChangeType("repack_full") - // RepackIncremental is when replication runs an incremental repack - RepackIncremental = ChangeType("repack_incremental") - // Cleanup is when replication runs a repo cleanup - Cleanup = ChangeType("cleanup") - // PackRefs is when replication optimizes references in a repo - PackRefs = ChangeType("pack_refs") - // WriteCommitGraph is when replication writes a commit graph - WriteCommitGraph = ChangeType("write_commit_graph") - // MidxRepack is when replication does a multi-pack-index repack - MidxRepack = ChangeType("midx_repack") - // OptimizeRepository is when replication optimizes a repository - OptimizeRepository = ChangeType("optimize_repository") - // PruneUnreachableObjects is when replication prunes unreachable objects in a repository - PruneUnreachableObjects = ChangeType("prune_unreachable_objects") ) func (ct ChangeType) String() string { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/doc.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/doc.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/doc.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/doc.go index 8b69c42c77..3e68b4bf29 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/doc.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/doc.go @@ -23,7 +23,7 @@ // go test \ // -v \ // -count=1 \ -// gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql \ +// gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql \ // -run=^TestOpenDB$ // // Once it is finished successfully you can be sure other tests would be able to diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres.go index 24c4093d63..3bb1362127 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres.go @@ -13,8 +13,8 @@ import ( "github.com/jackc/pgx/v4" "github.com/jackc/pgx/v4/stdlib" migrate "github.com/rubenv/sql-migrate" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" ) // OpenDB returns connection pool to the database. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres_test.go index 039145a5fd..0a8ee70042 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/postgres_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/postgres_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package glsql_test import ( @@ -11,11 +13,11 @@ import ( migrate "github.com/rubenv/sql-migrate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestOpenDB(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/testhelper_test.go index 79eda3e6e9..27e247e46c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package glsql import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener.go index 34a145b3cd..263ff45e49 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener.go @@ -10,9 +10,9 @@ import ( "github.com/jackc/pgx/v4" promclient "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener_test.go index d7274361fa..92e914d620 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/listener_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/listener_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -15,11 +17,11 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestNewListener(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory.go index 06d9eed866..b4ec871665 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory.go @@ -9,7 +9,7 @@ import ( "sync" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" ) var errDeadAckedAsFailed = errors.New("job acknowledged as failed with no attempts left, should be 'dead'") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory_test.go index 5224f79b84..af41889f0c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/memory_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/memory_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -5,8 +7,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMemoryReplicationEventQueue(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200109161404_hello_world.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200109161404_hello_world.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200109161404_hello_world.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200109161404_hello_world.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200113151438_1_test_migration.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200113151438_1_test_migration.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200113151438_1_test_migration.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200113151438_1_test_migration.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200224220728_job_queue.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200224220728_job_queue.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200224220728_job_queue.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200224220728_job_queue.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200225220728_readd_job_queue.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200225220728_readd_job_queue.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200225220728_readd_job_queue.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200225220728_readd_job_queue.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200324001604_add_sql_election_tables.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200324001604_add_sql_election_tables.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200324001604_add_sql_election_tables.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200324001604_add_sql_election_tables.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200422131451_add_shard_read_only_column.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200422131451_add_shard_read_only_column.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200422131451_add_shard_read_only_column.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200422131451_add_shard_read_only_column.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200512131219_replication_job_indexing.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200512131219_replication_job_indexing.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200512131219_replication_job_indexing.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200512131219_replication_job_indexing.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200527103816_drop_old_gitaly_tables.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200527103816_drop_old_gitaly_tables.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200527103816_drop_old_gitaly_tables.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200527103816_drop_old_gitaly_tables.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200602154246_remember_previous_writable_primary.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200602154246_remember_previous_writable_primary.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200602154246_remember_previous_writable_primary.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200602154246_remember_previous_writable_primary.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200707101830_repositories_table.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200707101830_repositories_table.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200707101830_repositories_table.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200707101830_repositories_table.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200810055650_replication_queue_cleanup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200810055650_replication_queue_cleanup.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200810055650_replication_queue_cleanup.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200810055650_replication_queue_cleanup.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200921154417_repositories_nullable_generation.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200921154417_repositories_nullable_generation.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200921154417_repositories_nullable_generation.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200921154417_repositories_nullable_generation.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200921170311_repositories_primary_column.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200921170311_repositories_primary_column.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20200921170311_repositories_primary_column.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20200921170311_repositories_primary_column.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201006125956_trigger_repository_update_generation.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201006125956_trigger_repository_update_generation.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201006125956_trigger_repository_update_generation.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201006125956_trigger_repository_update_generation.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201102115118_variable_replication_factor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201102115118_variable_replication_factor.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201102115118_variable_replication_factor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201102115118_variable_replication_factor.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201102171914_virtual_storage_configuration.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201102171914_virtual_storage_configuration.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201102171914_virtual_storage_configuration.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201102171914_virtual_storage_configuration.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201126165633_repository_assignments_table.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201126165633_repository_assignments_table.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201126165633_repository_assignments_table.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201126165633_repository_assignments_table.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201208163237_cleanup_notifiactions_payload.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201208163237_cleanup_notifiactions_payload.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201208163237_cleanup_notifiactions_payload.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201208163237_cleanup_notifiactions_payload.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201231075619_remove_unused_assigned_column.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201231075619_remove_unused_assigned_column.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20201231075619_remove_unused_assigned_column.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20201231075619_remove_unused_assigned_column.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210223130233_delete_replica_unique_index.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210223130233_delete_replica_unique_index.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210223130233_delete_replica_unique_index.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210223130233_delete_replica_unique_index.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210225101159_extend_replication_queue_target_index.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210225101159_extend_replication_queue_target_index.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210225101159_extend_replication_queue_target_index.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210225101159_extend_replication_queue_target_index.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210525143540_healthy_storages_view.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210525143540_healthy_storages_view.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210525143540_healthy_storages_view.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210525143540_healthy_storages_view.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210525173505_valid_primaries_view.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210525173505_valid_primaries_view.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210525173505_valid_primaries_view.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210525173505_valid_primaries_view.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210607124235_optimize_valid_primaries_view.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210607124235_optimize_valid_primaries_view.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210607124235_optimize_valid_primaries_view.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210607124235_optimize_valid_primaries_view.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210727085659_repository_ids.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210727085659_repository_ids.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210727085659_repository_ids.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210727085659_repository_ids.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210906130405_add_replica_path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210906130405_add_replica_path.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210906130405_add_replica_path.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210906130405_add_replica_path.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210906145021_link_repository_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210906145021_link_repository_id.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210906145021_link_repository_id.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210906145021_link_repository_id.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210914115710_storage_cleanups_table.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210914115710_storage_cleanups_table.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210914115710_storage_cleanups_table.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210914115710_storage_cleanups_table.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210921131816_backfill_replica_path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210921131816_backfill_replica_path.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210921131816_backfill_replica_path.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210921131816_backfill_replica_path.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210922091614_repository_id_primary_key_indexes.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210922091614_repository_id_primary_key_indexes.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210922091614_repository_id_primary_key_indexes.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210922091614_repository_id_primary_key_indexes.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210922143752_storage_repositories_cascade_delete.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210922143752_storage_repositories_cascade_delete.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210922143752_storage_repositories_cascade_delete.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210922143752_storage_repositories_cascade_delete.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210923155827_valid_primaries_view_repository_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210923155827_valid_primaries_view_repository_id.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210923155827_valid_primaries_view_repository_id.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210923155827_valid_primaries_view_repository_id.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210927083631_repository_path_index.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210927083631_repository_path_index.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20210927083631_repository_path_index.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20210927083631_repository_path_index.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211018142158_valid_primaries_view_join_repo_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211018142158_valid_primaries_view_join_repo_id.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211018142158_valid_primaries_view_join_repo_id.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211018142158_valid_primaries_view_join_repo_id.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211025113445_remove_cancelled_replication_events.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211025113445_remove_cancelled_replication_events.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211025113445_remove_cancelled_replication_events.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211025113445_remove_cancelled_replication_events.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211105100456_check_non_null_repository_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211105100456_check_non_null_repository_id.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211105100456_check_non_null_repository_id.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211105100456_check_non_null_repository_id.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211105100458_non_nullable_repository_id.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211105100458_non_nullable_repository_id.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20211105100458_non_nullable_repository_id.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20211105100458_non_nullable_repository_id.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220215160117_replication_queue_cleanup_again.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220215160117_replication_queue_cleanup_again.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220215160117_replication_queue_cleanup_again.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220215160117_replication_queue_cleanup_again.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220303105110_background_verification_columns.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220303105110_background_verification_columns.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220303105110_background_verification_columns.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220303105110_background_verification_columns.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220404131105_stale_verification_lease_index.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220404131105_stale_verification_lease_index.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220404131105_stale_verification_lease_index.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220404131105_stale_verification_lease_index.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220407111624_ignore_verification_in_triggers.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220407111624_ignore_verification_in_triggers.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/20220407111624_ignore_verification_in_triggers.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220407111624_ignore_verification_in_triggers.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go new file mode 100644 index 0000000000..21a95dd491 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go @@ -0,0 +1,68 @@ +package migrations + +import migrate "github.com/rubenv/sql-migrate" + +func init() { + m := &migrate.Migration{ + Id: "20220520083313_remove_maintenance_replication_events", + Up: []string{ + ` +-- Find all jobs which are maintenance-style jobs first. +WITH maintenance_job AS ( + SELECT id FROM replication_queue WHERE job->>'change' IN ( + 'gc', + 'repack_full', + 'repack_incremental', + 'cleanup', + 'pack_refs', + 'write_commit_graph', + 'midx_repack', + 'optimize_repository', + 'prune_unreachable_objects' + ) +), + +-- Now we have to prune the job locks before deleting the maintenance job +-- itself because the lock has a reference on the job. +deleted_maintenance_job_lock AS ( + DELETE FROM replication_queue_job_lock + WHERE job_id IN (SELECT id FROM maintenance_job) + RETURNING lock_id +), + +-- With job locks having been deleted we can now delete the maintenance jobs. +deleted_maintenance_job AS ( + DELETE FROM replication_queue + WHERE id IN (SELECT id FROM maintenance_job) +) + +-- Finally, we need to release replication queue locks in case we have removed +-- all jobs which kept the lock. +UPDATE replication_queue_lock +SET acquired = FALSE +WHERE id IN ( + SELECT existing.lock_id + -- We do so by unlocking all locks where the count of deleted job locks is + -- the same as the count of existing job locks. If there happen to be any + -- other jobs we haven't deleted then the lock stays acquired. This is the + -- same logic as used in AcknowledgeStale. + FROM ( + SELECT lock_id, COUNT(*) AS amount + FROM deleted_maintenance_job_lock + GROUP BY lock_id + ) AS removed + JOIN ( + SELECT lock_id, COUNT(*) AS amount + FROM replication_queue_job_lock + WHERE lock_id IN (select lock_id FROM deleted_maintenance_job_lock) + GROUP BY lock_id + ) AS existing ON removed.lock_id = existing.lock_id AND removed.amount = existing.amount +)`, + }, + Down: []string{ + // We cannot get this data back anymore. + }, + } + + allMigrations = append(allMigrations, m) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/migrations.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/migrations.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations/migrations.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations/migrations.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/mock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/mock.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/mock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/mock.go index ce63440219..4d9867ec2f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/mock.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/mock.go @@ -9,7 +9,7 @@ type MockReplicationEventQueue struct { EnqueueFunc func(context.Context, ReplicationEvent) (ReplicationEvent, error) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockReplicationEventQueue) Enqueue(ctx context.Context, event ReplicationEvent) (ReplicationEvent, error) { return m.EnqueueFunc(ctx, event) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres.go index 3b4cdd0357..dc393c260f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres.go @@ -7,9 +7,9 @@ import ( "time" migrate "github.com/rubenv/sql-migrate" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" ) // MigrationStatusRow represents an entry in the schema migrations table. @@ -24,7 +24,7 @@ type MigrationStatusRow struct { // specified in conf. This is a diagnostic for the Praefect Postgres // rollout. https://gitlab.com/gitlab-org/gitaly/issues/1755 func CheckPostgresVersion(db *sql.DB) error { - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() var serverVersion int diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres_test.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres_test.go index f1a8f72375..6147315890 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/postgres_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/postgres_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package datastore import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestMigrateStatus(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue.go index 986564b189..2943974cec 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue.go @@ -9,7 +9,7 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) // ReplicationEventQueue allows to put new events to the persistent queue and retrieve them back. @@ -66,7 +66,7 @@ type ReplicationJob struct { Params Params `json:"params"` } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (job *ReplicationJob) Scan(value interface{}) error { if value == nil { return nil @@ -80,7 +80,7 @@ func (job *ReplicationJob) Scan(value interface{}) error { return json.Unmarshal(d, job) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (job ReplicationJob) Value() (driver.Value, error) { data, err := json.Marshal(job) if err != nil { @@ -208,7 +208,7 @@ type PostgresReplicationEventQueue struct { qc glsql.Querier } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rq PostgresReplicationEventQueue) Enqueue(ctx context.Context, event ReplicationEvent) (ReplicationEvent, error) { // When `Enqueue` method is called: // 1. Insertion of the new record into `replication_queue_lock` table, so we are ensured all events have @@ -241,7 +241,7 @@ func (rq PostgresReplicationEventQueue) Enqueue(ctx context.Context, event Repli return events[0], nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rq PostgresReplicationEventQueue) Dequeue(ctx context.Context, virtualStorage, nodeStorage string, count int) ([]ReplicationEvent, error) { // When `Dequeue` method is called: // 1. Events with attempts left that are either in `ready` or `failed` state are candidates for dequeuing. @@ -322,7 +322,7 @@ func (rq PostgresReplicationEventQueue) Dequeue(ctx context.Context, virtualStor return res, nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rq PostgresReplicationEventQueue) Acknowledge(ctx context.Context, state JobState, ids []uint64) ([]uint64, error) { // When `Acknowledge` method is called: // 1. The list of event `id`s and corresponding s retrieved from `replication_queue` table as passed in by the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_bm_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_bm_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_bm_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_bm_test.go index 825c083c09..7c8bee2fcf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_bm_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_bm_test.go @@ -1,30 +1,32 @@ +//go:build !gitaly_test_sha256 + package datastore import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func BenchmarkPostgresReplicationEventQueue_Acknowledge(b *testing.B) { - // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/small -benchtime=1000x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/small -benchtime=1000x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("small", func(b *testing.B) { benchmarkPostgresReplicationEventQueueAcknowledge(b, map[JobState]int{JobStateReady: 10, JobStateInProgress: 10, JobStateFailed: 10}) }) - // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/medium -benchtime=100x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/medium -benchtime=100x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("medium", func(b *testing.B) { benchmarkPostgresReplicationEventQueueAcknowledge(b, map[JobState]int{JobStateReady: 1_000, JobStateInProgress: 100, JobStateFailed: 100}) }) - // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/big -benchtime=10x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/big -benchtime=10x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("big", func(b *testing.B) { benchmarkPostgresReplicationEventQueueAcknowledge(b, map[JobState]int{JobStateReady: 100_000, JobStateInProgress: 100, JobStateFailed: 100}) }) - // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/huge -benchtime=1x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.run=~ -test.bench=BenchmarkPostgresReplicationEventQueue_Acknowledge/huge -benchtime=1x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("huge", func(b *testing.B) { benchmarkPostgresReplicationEventQueueAcknowledge(b, map[JobState]int{JobStateReady: 1_000_000, JobStateInProgress: 100, JobStateFailed: 100}) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_test.go index 03cb27bf4c..6aac7ca4d2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/queue_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/queue_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -8,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestPostgresReplicationEventQueue_DeleteReplicaUniqueIndex(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store.go index 780073155a..d18f8c5438 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store.go @@ -9,8 +9,8 @@ import ( "strings" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) type storages map[string][]string @@ -118,6 +118,9 @@ type RepositoryStore interface { // as the storage's which is calling it. Returns RepositoryNotExistsError when trying to rename a repository // which has no record in the virtual storage or the storage. RenameRepository(ctx context.Context, virtualStorage, relativePath, storage, newRelativePath string) error + // RenameRepositoryInPlace renames the repository in the database without changing the replica path. This will replace + // RenameRepository which can be removed in a later release. + RenameRepositoryInPlace(ctx context.Context, virtualStorage, relativePath, newRelativePath string) error // GetConsistentStoragesByRepositoryID returns the replica path and the set of up to date storages for the given repository keyed by repository ID. GetConsistentStoragesByRepositoryID(ctx context.Context, repositoryID int64) (string, map[string]struct{}, error) ConsistentStoragesGetter @@ -210,7 +213,7 @@ func (rs *PostgresRepositoryStore) MarkStorageUnverified(ctx context.Context, vi return result.RowsAffected() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) GetGeneration(ctx context.Context, repositoryID int64, storage string) (int, error) { const q = ` SELECT generation @@ -231,7 +234,7 @@ AND storage = $2 return gen, nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) IncrementGeneration(ctx context.Context, repositoryID int64, primary string, secondaries []string) error { const q = ` WITH updated_replicas AS ( @@ -285,7 +288,7 @@ SELECT return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) SetGeneration(ctx context.Context, repositoryID int64, storage, relativePath string, generation int) error { const q = ` WITH repository AS ( @@ -349,7 +352,7 @@ ON CONFLICT (virtual_storage, relative_path, storage) DO UPDATE return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) GetReplicatedGeneration(ctx context.Context, repositoryID int64, source, target string) (int, error) { const q = ` SELECT storage, generation @@ -484,7 +487,7 @@ FROM ( return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) DeleteRepository(ctx context.Context, virtualStorage, relativePath string) (string, []string, error) { var ( replicaPath string @@ -535,7 +538,40 @@ AND storage = $2 return nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +// RenameRepositoryInPlace renames the repository in the database without changing the replica path. This will replace +// RenameRepository which can be removed in a later release. +func (rs *PostgresRepositoryStore) RenameRepositoryInPlace(ctx context.Context, virtualStorage, relativePath, newRelativePath string) error { + result, err := rs.db.ExecContext(ctx, ` +WITH repository AS ( + UPDATE repositories + SET relative_path = $3 + WHERE virtual_storage = $1 + AND relative_path = $2 + RETURNING repository_id +) + +UPDATE storage_repositories +SET relative_path = $3 +WHERE repository_id = (SELECT repository_id FROM repository) + `, virtualStorage, relativePath, newRelativePath) + if err != nil { + if glsql.IsUniqueViolation(err, "repository_lookup_index") { + return commonerr.ErrRepositoryAlreadyExists + } + + return fmt.Errorf("query: %w", err) + } + + if rowsAffected, err := result.RowsAffected(); err != nil { + return fmt.Errorf("rows affected: %w", err) + } else if rowsAffected == 0 { + return commonerr.ErrRepositoryNotFound + } + + return nil +} + +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) RenameRepository(ctx context.Context, virtualStorage, relativePath, storage, newRelativePath string) error { const q = ` WITH repo AS ( @@ -621,7 +657,7 @@ func (rs *PostgresRepositoryStore) getConsistentStorages(ctx context.Context, qu return replicaPath, consistentStorages, nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (rs *PostgresRepositoryStore) RepositoryExists(ctx context.Context, virtualStorage, relativePath string) (bool, error) { const q = ` SELECT true diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_bm_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_bm_test.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_bm_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_bm_test.go index 6010d2fe39..3f982e4176 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_bm_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_bm_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -5,33 +7,33 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) // The test setup takes a lot of time, so it is better to run each sub-benchmark separately with limit on number of repeats. func BenchmarkPostgresRepositoryStore_GetConsistentStorages(b *testing.B) { - // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/extra-small -benchtime=5000x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/extra-small -benchtime=5000x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("extra-small", func(b *testing.B) { benchmarkGetConsistentStorages(b, 3, 1000) }) - // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/small -benchtime=1000x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/small -benchtime=1000x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("small", func(b *testing.B) { benchmarkGetConsistentStorages(b, 3, 10_000) }) - // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/medium -benchtime=50x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/medium -benchtime=50x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("medium", func(b *testing.B) { benchmarkGetConsistentStorages(b, 3, 100_000) }) - // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/large -benchtime=10x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/large -benchtime=10x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("large", func(b *testing.B) { benchmarkGetConsistentStorages(b, 3, 1_000_000) }) - // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/huge -benchtime=1x gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore + // go test -tags=postgres -test.bench=BenchmarkPostgresRepositoryStore_GetConsistentStorages/huge -benchtime=1x gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore b.Run("huge", func(b *testing.B) { benchmarkGetConsistentStorages(b, 6, 1_000_000) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_mock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_mock.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_mock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_mock.go index 2a021661d9..b2a9f60c9b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_mock.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_mock.go @@ -14,6 +14,7 @@ type MockRepositoryStore struct { SetAuthoritativeReplicaFunc func(ctx context.Context, virtualStorage, relativePath, storage string) error DeleteRepositoryFunc func(ctx context.Context, virtualStorage, relativePath string) (string, []string, error) DeleteReplicaFunc func(ctx context.Context, repositoryID int64, storage string) error + RenameRepositoryInPlaceFunc func(ctx context.Context, virtualStorage, relativePath, newRelativePath string) error RenameRepositoryFunc func(ctx context.Context, virtualStorage, relativePath, storage, newRelativePath string) error GetConsistentStoragesByRepositoryIDFunc func(ctx context.Context, repositoryID int64) (string, map[string]struct{}, error) GetConsistentStoragesFunc func(ctx context.Context, virtualStorage, relativePath string) (string, map[string]struct{}, error) @@ -27,7 +28,7 @@ type MockRepositoryStore struct { GetRepositoryMetadataByPathFunc func(ctx context.Context, virtualStorage, relativePath string) (RepositoryMetadata, error) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) GetGeneration(ctx context.Context, repositoryID int64, storage string) (int, error) { if m.GetGenerationFunc == nil { return GenerationUnknown, nil @@ -36,7 +37,7 @@ func (m MockRepositoryStore) GetGeneration(ctx context.Context, repositoryID int return m.GetGenerationFunc(ctx, repositoryID, storage) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) IncrementGeneration(ctx context.Context, repositoryID int64, primary string, secondaries []string) error { if m.IncrementGenerationFunc == nil { return nil @@ -45,7 +46,7 @@ func (m MockRepositoryStore) IncrementGeneration(ctx context.Context, repository return m.IncrementGenerationFunc(ctx, repositoryID, primary, secondaries) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) GetReplicatedGeneration(ctx context.Context, repositoryID int64, source, target string) (int, error) { if m.GetReplicatedGenerationFunc == nil { return GenerationUnknown, nil @@ -54,7 +55,7 @@ func (m MockRepositoryStore) GetReplicatedGeneration(ctx context.Context, reposi return m.GetReplicatedGenerationFunc(ctx, repositoryID, source, target) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) SetGeneration(ctx context.Context, repositoryID int64, storage, relativePath string, generation int) error { if m.SetGenerationFunc == nil { return nil @@ -81,7 +82,7 @@ func (m MockRepositoryStore) SetAuthoritativeReplica(ctx context.Context, virtua return m.SetAuthoritativeReplicaFunc(ctx, virtualStorage, relativePath, storage) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) DeleteRepository(ctx context.Context, virtualStorage, relativePath string) (string, []string, error) { if m.DeleteRepositoryFunc == nil { return "", nil, nil @@ -99,7 +100,12 @@ func (m MockRepositoryStore) DeleteReplica(ctx context.Context, repositoryID int return m.DeleteReplicaFunc(ctx, repositoryID, storage) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +// RenameRepositoryInPlace runs the mock's RenameRepositoryInPlaceFunc. +func (m MockRepositoryStore) RenameRepositoryInPlace(ctx context.Context, virtualStorage, relativePath, newRelativePath string) error { + return m.RenameRepositoryInPlaceFunc(ctx, virtualStorage, relativePath, newRelativePath) +} + +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) RenameRepository(ctx context.Context, virtualStorage, relativePath, storage, newRelativePath string) error { if m.RenameRepositoryFunc == nil { return nil @@ -135,7 +141,7 @@ func (m MockRepositoryStore) GetPartiallyAvailableRepositories(ctx context.Conte return m.GetPartiallyAvailableRepositoriesFunc(ctx, virtualStorage) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) DeleteInvalidRepository(ctx context.Context, repositoryID int64, storage string) error { if m.DeleteInvalidRepositoryFunc == nil { return nil @@ -144,7 +150,7 @@ func (m MockRepositoryStore) DeleteInvalidRepository(ctx context.Context, reposi return m.DeleteInvalidRepositoryFunc(ctx, repositoryID, storage) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m MockRepositoryStore) RepositoryExists(ctx context.Context, virtualStorage, relativePath string) (bool, error) { if m.RepositoryExistsFunc == nil { return true, nil diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_test.go index 9c980376c5..e47d2d4315 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/repository_store_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/repository_store_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -8,10 +10,10 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) // repositoryRecord represents Praefect's records related to a repository. @@ -35,10 +37,10 @@ type replicaRecord struct { // It structured as virtual-storage->relative_path->storage->replicaRecord type storageState map[string]map[string]map[string]replicaRecord -func requireState(t testing.TB, ctx context.Context, db glsql.Querier, vss virtualStorageState, ss storageState) { - t.Helper() +func requireState(tb testing.TB, ctx context.Context, db glsql.Querier, vss virtualStorageState, ss storageState) { + tb.Helper() - requireVirtualStorageState := func(t testing.TB, ctx context.Context, exp virtualStorageState) { + requireVirtualStorageState := func(tb testing.TB, ctx context.Context, exp virtualStorageState) { rows, err := db.QueryContext(ctx, ` SELECT repository_id, virtual_storage, relative_path, replica_path, "primary", assigned_storages FROM repositories @@ -49,7 +51,7 @@ LEFT JOIN ( ) AS repository_assignments USING (repository_id, virtual_storage, relative_path) `) - require.NoError(t, err) + require.NoError(tb, err) defer rows.Close() act := make(virtualStorageState) @@ -60,7 +62,7 @@ LEFT JOIN ( primary sql.NullString assignments glsql.StringArray ) - require.NoError(t, rows.Scan(&repositoryID, &virtualStorage, &relativePath, &replicaPath, &primary, &assignments)) + require.NoError(tb, rows.Scan(&repositoryID, &virtualStorage, &relativePath, &replicaPath, &primary, &assignments)) if act[virtualStorage] == nil { act[virtualStorage] = make(map[string]repositoryRecord) } @@ -73,16 +75,16 @@ LEFT JOIN ( } } - require.NoError(t, rows.Err()) - require.Equal(t, exp, act) + require.NoError(tb, rows.Err()) + require.Equal(tb, exp, act) } - requireStorageState := func(t testing.TB, ctx context.Context, exp storageState) { + requireStorageState := func(tb testing.TB, ctx context.Context, exp storageState) { rows, err := db.QueryContext(ctx, ` SELECT repository_id, virtual_storage, relative_path, storage, generation FROM storage_repositories `) - require.NoError(t, err) + require.NoError(tb, err) defer rows.Close() act := make(storageState) @@ -90,7 +92,7 @@ FROM storage_repositories var repositoryID sql.NullInt64 var vs, rel, storage string var gen int - require.NoError(t, rows.Scan(&repositoryID, &vs, &rel, &storage, &gen)) + require.NoError(tb, rows.Scan(&repositoryID, &vs, &rel, &storage, &gen)) if act[vs] == nil { act[vs] = make(map[string]map[string]replicaRecord) @@ -102,12 +104,12 @@ FROM storage_repositories act[vs][rel][storage] = replicaRecord{repositoryID: repositoryID.Int64, generation: gen} } - require.NoError(t, rows.Err()) - require.Equal(t, exp, act) + require.NoError(tb, rows.Err()) + require.Equal(tb, exp, act) } - requireVirtualStorageState(t, ctx, vss) - requireStorageState(t, ctx, ss) + requireVirtualStorageState(tb, ctx, vss) + requireStorageState(tb, ctx, ss) } func TestRepositoryStore_Postgres(t *testing.T) { @@ -765,6 +767,50 @@ func TestRepositoryStore_Postgres(t *testing.T) { }) }) + t.Run("RenameRepositoryInPlace", func(t *testing.T) { + t.Run("rename non-existing", func(t *testing.T) { + rs := newRepositoryStore(t, nil) + + require.Equal(t, + commonerr.ErrRepositoryNotFound, + rs.RenameRepositoryInPlace(ctx, vs, repo, "new-relative-path"), + ) + }) + + t.Run("destination exists", func(t *testing.T) { + rs := newRepositoryStore(t, nil) + + require.NoError(t, rs.CreateRepository(ctx, 1, vs, "relative-path-1", "replica-path-1", "primary", nil, nil, true, false)) + require.NoError(t, rs.CreateRepository(ctx, 2, vs, "relative-path-2", "replica-path-2", "primary", nil, nil, true, false)) + + require.Equal(t, + commonerr.ErrRepositoryAlreadyExists, + rs.RenameRepositoryInPlace(ctx, vs, "relative-path-1", "relative-path-2"), + ) + }) + + t.Run("successfully renamed", func(t *testing.T) { + rs := newRepositoryStore(t, nil) + + require.NoError(t, rs.CreateRepository(ctx, 1, vs, "original-relative-path", "original-replica-path", "primary", nil, nil, false, false)) + require.NoError(t, rs.RenameRepositoryInPlace(ctx, vs, "original-relative-path", "renamed-relative-path")) + requireState(t, ctx, db, + virtualStorageState{ + vs: { + "renamed-relative-path": {repositoryID: 1, replicaPath: "original-replica-path"}, + }, + }, + storageState{ + vs: { + "renamed-relative-path": { + "primary": {repositoryID: 1}, + }, + }, + }, + ) + }) + }) + t.Run("RenameRepository", func(t *testing.T) { t.Run("rename non-existing", func(t *testing.T) { rs := newRepositoryStore(t, nil) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup.go index a9de6effd9..1936d64545 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" ) // ClusterPath represents path on the cluster to the storage. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup_test.go index a590829eb9..5681167275 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_cleanup_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_cleanup_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -6,8 +8,8 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestStorageCleanup_Populate(t *testing.T) { @@ -247,20 +249,20 @@ type storageCleanupRow struct { TriggeredAt sql.NullTime } -func getAllStoragesCleanup(t testing.TB, db testdb.DB) []storageCleanupRow { +func getAllStoragesCleanup(tb testing.TB, db testdb.DB) []storageCleanupRow { rows, err := db.Query(`SELECT * FROM storage_cleanups`) - require.NoError(t, err) + require.NoError(tb, err) defer func() { - require.NoError(t, rows.Close()) + require.NoError(tb, rows.Close()) }() var res []storageCleanupRow for rows.Next() { var dst storageCleanupRow err := rows.Scan(&dst.VirtualStorage, &dst.Storage, &dst.LastRun, &dst.TriggeredAt) - require.NoError(t, err) + require.NoError(tb, err) res = append(res, dst) } - require.NoError(t, rows.Err()) + require.NoError(tb, rows.Err()) return res } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider.go index 654209ac1c..1d0a3fb286 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider.go @@ -11,7 +11,7 @@ import ( lru "github.com/hashicorp/golang-lru" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) // ConsistentStoragesGetter returns storages which contain the latest generation of a repository. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider_test.go index 758a7a549d..399ecc48af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/storage_provider_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/storage_provider_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package datastore import ( @@ -13,10 +15,10 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestCachingStorageProvider_GetSyncedNodes(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/testhelper_test.go index ba8977ba9d..e282cff1b7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package datastore import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool.go similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool.go index b31ba40c39..c10449d428 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool.go @@ -4,12 +4,12 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - objectpoolsvc "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/objectpool" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + objectpoolsvc "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/objectpool" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" ) @@ -29,7 +29,7 @@ func DeleteObjectPoolHandler(rs datastore.RepositoryStore, conns Connections) gr return nil, err } - if !housekeeping.IsRailsPoolPath(repo.GetRelativePath()) { + if !housekeeping.IsRailsPoolRepository(repo) { return nil, helper.ErrInvalidArgument(objectpool.ErrInvalidPoolDir) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool_test.go index 2a8c46f640..db63edddf8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/delete_object_pool_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/delete_object_pool_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -8,13 +10,14 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) type mockObjectPoolService struct { @@ -61,11 +64,11 @@ func TestDeleteObjectPoolHandler(t *testing.T) { rs.CreateRepository(ctx, 1, repo.StorageName, repo.RelativePath, "replica-path", "primary", []string{"secondary", "unconfigured_storage"}, nil, true, true), ) - primaryConn, err := grpc.Dial(primaryAddr, grpc.WithInsecure()) + primaryConn, err := grpc.Dial(primaryAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer primaryConn.Close() - secondaryConn, err := grpc.Dial(secondaryAddr, grpc.WithInsecure()) + secondaryConn, err := grpc.Dial(secondaryAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer secondaryConn.Close() @@ -95,7 +98,7 @@ func TestDeleteObjectPoolHandler(t *testing.T) { defer praefectSrv.Stop() go praefectSrv.Serve(praefectLn) - praefectConn, err := grpc.Dial(praefectAddr, grpc.WithInsecure()) + praefectConn, err := grpc.Dial(praefectAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer praefectConn.Close() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/LICENSE.txt b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/LICENSE.txt similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/LICENSE.txt rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/LICENSE.txt diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/checkup.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/checkup.sh similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/checkup.sh rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/checkup.sh diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/fixup.sh b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/fixup.sh similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/fixup.sh rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/fixup.sh diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/DOC.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/DOC.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/DOC.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/DOC.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/codec.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/codec.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/codec.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/codec.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/codec_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/codec_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/codec_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/codec_test.go index 99569ac0df..b05738f1e3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/codec_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/codec_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package proxy import ( @@ -7,6 +9,8 @@ import ( ) func TestCodec_ReadYourWrites(t *testing.T) { + t.Parallel() + framePtr := &frame{} data := []byte{0xDE, 0xAD, 0xBE, 0xEF} codec := rawCodec{} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/director.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/director.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/director.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/director.go index 5f887213c3..97b5be7bad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/director.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/director.go @@ -58,12 +58,12 @@ func NewStreamParameters(primary Destination, secondaries []Destination, reqFina } } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *StreamParameters) Primary() Destination { return s.primary } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *StreamParameters) Secondaries() []Destination { return s.secondaries } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/doc.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/doc.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/doc.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/doc.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/examples_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/examples_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/examples_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/examples_test.go index 187d27e961..b8d5759bdb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/examples_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/examples_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + // Copyright 2017 Michal Witkowski. All Rights Reserved. // See LICENSE for licensing terms. @@ -7,8 +9,8 @@ import ( "context" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" "google.golang.org/grpc" "google.golang.org/grpc/codes" grpc_metadata "google.golang.org/grpc/metadata" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler.go index 58fcdc8282..82c252526a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler.go @@ -9,7 +9,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_ext_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_ext_test.go new file mode 100644 index 0000000000..7e5234fcd5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_ext_test.go @@ -0,0 +1,504 @@ +//go:build !gitaly_test_sha256 + +// Copyright 2017 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package proxy_test + +import ( + "context" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/http/httptest" + "net/url" + "path/filepath" + "testing" + + "github.com/getsentry/sentry-go" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + grpc_metadata "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/grpc_testing" +) + +const ( + rejectingMdKey = "test-reject-rpc-if-in-context" +) + +func TestHandler_carriesClientMetadata(t *testing.T) { + t.Parallel() + testHandlerCarriesClientMetadata(t) +} + +func TestHandler_carriesClientMetadataStressTest(t *testing.T) { + t.Parallel() + + for i := 0; i < 50; i++ { + testHandlerCarriesClientMetadata(t) + } +} + +func testHandlerCarriesClientMetadata(t *testing.T) { + ctx, client, backend := setupProxy(t) + + backend.unaryCall = func(ctx context.Context, request *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { + metadata, ok := grpc_metadata.FromIncomingContext(ctx) + require.True(t, ok) + + metadataValue, ok := metadata["injected_metadata"] + require.True(t, ok) + require.Equal(t, []string{"injected_value"}, metadataValue) + + return &grpc_testing.SimpleResponse{Payload: request.GetPayload()}, nil + } + + ctx = grpc_metadata.NewOutgoingContext(ctx, grpc_metadata.Pairs("injected_metadata", "injected_value")) + + response, err := client.UnaryCall(ctx, &grpc_testing.SimpleRequest{ + Payload: &grpc_testing.Payload{Body: []byte("data")}, + }) + require.NoError(t, err, "PingEmpty should succeed without errors") + testhelper.ProtoEqual(t, &grpc_testing.SimpleResponse{ + Payload: &grpc_testing.Payload{Body: []byte("data")}, + }, response) +} + +func TestHandler_carriesHeadersAndTrailers(t *testing.T) { + t.Parallel() + + ctx, client, backend := setupProxy(t) + + backend.unaryCall = func(ctx context.Context, request *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { + require.NoError(t, grpc.SendHeader(ctx, grpc_metadata.Pairs("injected_header", "header_value"))) + require.NoError(t, grpc.SetTrailer(ctx, grpc_metadata.Pairs("injected_trailer", "trailer_value"))) + return &grpc_testing.SimpleResponse{Payload: request.GetPayload()}, nil + } + + var headerMetadata, trailerMetadata grpc_metadata.MD + + response, err := client.UnaryCall(ctx, &grpc_testing.SimpleRequest{ + Payload: &grpc_testing.Payload{Body: []byte("data")}, + }, grpc.Header(&headerMetadata), grpc.Trailer(&trailerMetadata)) + require.NoError(t, err) + testhelper.ProtoEqual(t, &grpc_testing.SimpleResponse{ + Payload: &grpc_testing.Payload{Body: []byte("data")}, + }, response) + + require.Equal(t, grpc_metadata.Pairs( + "content-type", "application/grpc", + "injected_header", "header_value", + ), headerMetadata) + require.Equal(t, grpc_metadata.Pairs( + "injected_trailer", "trailer_value", + ), trailerMetadata) +} + +func TestHandler_propagatesServerError(t *testing.T) { + ctx, client, backend := setupProxy(t) + + backend.unaryCall = func(context.Context, *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { + return nil, status.Errorf(codes.ResourceExhausted, "service error") + } + + sentryTriggered := 0 + sentrySrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + sentryTriggered++ + })) + defer sentrySrv.Close() + + // minimal required sentry client configuration + sentryURL, err := url.Parse(sentrySrv.URL) + require.NoError(t, err) + sentryURL.User = url.UserPassword("stub", "stub") + sentryURL.Path = "/stub/1" + + require.NoError(t, sentry.Init(sentry.ClientOptions{ + Dsn: sentryURL.String(), + Transport: sentry.NewHTTPSyncTransport(), + })) + + // Verify that Sentry is configured correctyl to be triggered. + sentry.CaptureEvent(sentry.NewEvent()) + require.Equal(t, 1, sentryTriggered) + + _, err = client.UnaryCall(ctx, &grpc_testing.SimpleRequest{}) + testhelper.RequireGrpcError(t, status.Errorf(codes.ResourceExhausted, "service error"), err) + + // Sentry must not be triggered because errors from remote must be just propagated. + require.Equal(t, 1, sentryTriggered) +} + +func TestHandler_directorErrorIsPropagated(t *testing.T) { + t.Parallel() + + // There is no need to set up the backend given that we should reject the call before we + // even hit the server. + ctx, client, _ := setupProxy(t) + + // The proxy's director is set up so that it is rejecting requests when it sees the + // following gRPC metadata. + ctx = grpc_metadata.NewOutgoingContext(ctx, grpc_metadata.Pairs(rejectingMdKey, "true")) + + _, err := client.UnaryCall(ctx, &grpc_testing.SimpleRequest{}) + require.Error(t, err) + testhelper.RequireGrpcError(t, helper.ErrPermissionDeniedf("testing rejection"), err) +} + +func TestHandler_fullDuplex(t *testing.T) { + t.Parallel() + testHandlerFullDuplex(t) +} + +func TestHandler_fullDuplexStressTest(t *testing.T) { + t.Parallel() + + for i := 0; i < 50; i++ { + testHandlerFullDuplex(t) + } +} + +func testHandlerFullDuplex(t *testing.T) { + ctx, client, backend := setupProxy(t) + + backend.fullDuplexCall = func(stream grpc_testing.TestService_FullDuplexCallServer) error { + require.NoError(t, stream.SendHeader(grpc_metadata.Pairs("custom_header", "header_value"))) + + for i := 0; ; i++ { + request, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + + require.NoError(t, stream.Send(&grpc_testing.StreamingOutputCallResponse{ + Payload: &grpc_testing.Payload{ + Body: []byte(fmt.Sprintf("%s: %d", request.GetPayload().GetBody(), i)), + }, + })) + } + + stream.SetTrailer(grpc_metadata.Pairs("custom_trailer", "trailer_value")) + return nil + } + + stream, err := client.FullDuplexCall(ctx) + require.NoError(t, err) + + for i := 0; i < 20; i++ { + require.NoError(t, stream.Send(&grpc_testing.StreamingOutputCallRequest{ + Payload: &grpc_testing.Payload{ + Body: []byte(fmt.Sprintf("foo:%d", i)), + }, + })) + + response, err := stream.Recv() + require.NoError(t, err) + testhelper.ProtoEqual(t, &grpc_testing.StreamingOutputCallResponse{ + Payload: &grpc_testing.Payload{ + Body: []byte(fmt.Sprintf("foo:%d: %d", i, i)), + }, + }, response) + + if i == 0 { + headerMetadata, err := stream.Header() + require.NoError(t, err) + require.Equal(t, grpc_metadata.Pairs( + "content-type", "application/grpc", + "custom_header", "header_value", + ), headerMetadata) + } + } + + require.NoError(t, stream.CloseSend()) + _, err = stream.Recv() + require.Equal(t, io.EOF, err) + + require.Equal(t, grpc_metadata.Pairs( + "custom_trailer", "trailer_value", + ), stream.Trailer()) +} + +func setupProxy(t *testing.T) (context.Context, grpc_testing.TestServiceClient, *interceptPinger) { + t.Helper() + + ctx := testhelper.Context(t) + + proxy2Server, backend := newBackendPinger(t, ctx) + + director := func(ctx context.Context, _ string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { + payload, err := peeker.Peek() + if err != nil { + return nil, err + } + + md, ok := grpc_metadata.FromIncomingContext(ctx) + if ok { + if _, exists := md[rejectingMdKey]; exists { + return proxy.NewStreamParameters(proxy.Destination{Ctx: metadata.IncomingToOutgoing(ctx), Msg: payload}, nil, nil, nil), status.Errorf(codes.PermissionDenied, "testing rejection") + } + } + + // Explicitly copy the metadata, otherwise the tests will fail. + return proxy.NewStreamParameters(proxy.Destination{ + Ctx: metadata.IncomingToOutgoing(ctx), + Conn: proxy2Server, + Msg: payload, + }, nil, nil, nil), nil + } + + client2Proxy := newProxy(t, ctx, director, "mwitkow.testproto.TestService", "Ping") + + return ctx, grpc_testing.NewTestServiceClient(client2Proxy), backend +} + +func TestProxyErrorPropagation(t *testing.T) { + t.Parallel() + + errBackend := status.Error(codes.InvalidArgument, "backend error") + errDirector := status.Error(codes.FailedPrecondition, "director error") + errRequestFinalizer := status.Error(codes.Internal, "request finalizer error") + + for _, tc := range []struct { + desc string + backendError error + directorError error + requestFinalizerError error + returnedError error + errHandler func(error) error + }{ + { + desc: "backend error is propagated", + backendError: errBackend, + returnedError: errBackend, + }, + { + desc: "director error is propagated", + directorError: errDirector, + returnedError: errDirector, + }, + { + desc: "request finalizer error is propagated", + requestFinalizerError: errRequestFinalizer, + returnedError: errRequestFinalizer, + }, + { + desc: "director error cancels proxying", + backendError: errBackend, + requestFinalizerError: errRequestFinalizer, + directorError: errDirector, + returnedError: errDirector, + }, + { + desc: "backend error prioritized over request finalizer error", + backendError: errBackend, + requestFinalizerError: errRequestFinalizer, + returnedError: errBackend, + }, + { + desc: "err handler gets error", + backendError: errBackend, + requestFinalizerError: errRequestFinalizer, + returnedError: errBackend, + errHandler: func(err error) error { + testhelper.RequireGrpcError(t, errBackend, err) + return errBackend + }, + }, + { + desc: "err handler can swallow error", + backendError: errBackend, + returnedError: io.EOF, + errHandler: func(err error) error { + testhelper.RequireGrpcError(t, errBackend, err) + return nil + }, + }, + { + desc: "swallowed error surfaces request finalizer error", + backendError: errBackend, + requestFinalizerError: errRequestFinalizer, + returnedError: errRequestFinalizer, + errHandler: func(err error) error { + testhelper.RequireGrpcError(t, errBackend, err) + return nil + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + tmpDir := testhelper.TempDir(t) + + backendListener, err := net.Listen("unix", filepath.Join(tmpDir, "backend")) + require.NoError(t, err) + + backendServer := grpc.NewServer(grpc.UnknownServiceHandler(func(interface{}, grpc.ServerStream) error { + return tc.backendError + })) + go func() { backendServer.Serve(backendListener) }() + defer backendServer.Stop() + ctx := testhelper.Context(t) + + backendClientConn, err := grpc.DialContext(ctx, "unix://"+backendListener.Addr().String(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec()))) + require.NoError(t, err) + defer func() { + require.NoError(t, backendClientConn.Close()) + }() + + proxyListener, err := net.Listen("unix", filepath.Join(tmpDir, "proxy")) + require.NoError(t, err) + + proxyServer := grpc.NewServer( + grpc.ForceServerCodec(proxy.NewCodec()), + grpc.UnknownServiceHandler(proxy.TransparentHandler(func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { + return proxy.NewStreamParameters( + proxy.Destination{ + Ctx: ctx, + Conn: backendClientConn, + ErrHandler: tc.errHandler, + }, + nil, + func() error { return tc.requestFinalizerError }, + nil, + ), tc.directorError + })), + ) + + go func() { proxyServer.Serve(proxyListener) }() + defer proxyServer.Stop() + + proxyClientConn, err := grpc.DialContext(ctx, "unix://"+proxyListener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer func() { + require.NoError(t, proxyClientConn.Close()) + }() + + resp, err := grpc_testing.NewTestServiceClient(proxyClientConn).UnaryCall(ctx, &grpc_testing.SimpleRequest{}) + testhelper.RequireGrpcError(t, tc.returnedError, err) + require.Nil(t, resp) + }) + } +} + +func TestRegisterStreamHandlers(t *testing.T) { + t.Parallel() + + directorCalledError := errors.New("director was called") + + requestSent := &grpc_testing.SimpleRequest{ + Payload: &grpc_testing.Payload{ + Body: []byte("hello"), + }, + } + + unaryCallStreamHandler := func(t *testing.T, srv interface{}, stream grpc.ServerStream) { + var request grpc_testing.SimpleRequest + require.NoError(t, stream.RecvMsg(&request)) + testhelper.ProtoEqual(t, requestSent, &request) + require.NoError(t, stream.SendMsg(nil)) + } + + emptyCallStreamHandler := func(t *testing.T, srv interface{}, stream grpc.ServerStream) { + var request grpc_testing.Empty + require.NoError(t, stream.RecvMsg(&request)) + require.NoError(t, stream.SendMsg(nil)) + } + + for _, tc := range []struct { + desc string + registeredHandlers map[string]func(*testing.T, interface{}, grpc.ServerStream) + execute func(context.Context, *testing.T, grpc_testing.TestServiceClient) + expectedErr error + expectedCalls map[string]int + }{ + { + desc: "single handler", + registeredHandlers: map[string]func(*testing.T, interface{}, grpc.ServerStream){ + "UnaryCall": unaryCallStreamHandler, + }, + execute: func(ctx context.Context, t *testing.T, client grpc_testing.TestServiceClient) { + _, err := client.UnaryCall(ctx, requestSent) + require.NoError(t, err) + }, + expectedCalls: map[string]int{ + "UnaryCall": 1, + }, + }, + { + desc: "multiple handlers picks the right one", + registeredHandlers: map[string]func(*testing.T, interface{}, grpc.ServerStream){ + "UnaryCall": unaryCallStreamHandler, + "EmptyCall": emptyCallStreamHandler, + }, + execute: func(ctx context.Context, t *testing.T, client grpc_testing.TestServiceClient) { + _, err := client.EmptyCall(ctx, &grpc_testing.Empty{}) + require.NoError(t, err) + }, + expectedCalls: map[string]int{ + "EmptyCall": 1, + }, + }, + { + desc: "call to unregistered handler", + registeredHandlers: map[string]func(*testing.T, interface{}, grpc.ServerStream){ + "EmptyCall": emptyCallStreamHandler, + }, + execute: func(ctx context.Context, t *testing.T, client grpc_testing.TestServiceClient) { + _, err := client.UnaryCall(ctx, requestSent) + testhelper.RequireGrpcError(t, directorCalledError, err) + }, + expectedCalls: map[string]int{}, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx := testhelper.Context(t) + + server := grpc.NewServer( + grpc.ForceServerCodec(proxy.NewCodec()), + grpc.UnknownServiceHandler(proxy.TransparentHandler( + func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { + return nil, directorCalledError + }, + )), + ) + + calls := map[string]int{} + registeredHandlers := map[string]grpc.StreamHandler{} + for name, handler := range tc.registeredHandlers { + name, handler := name, handler + + // We wrap every handler so that we can easily count the number of + // times each of them has been invoked. + registeredHandlers[name] = func(srv interface{}, stream grpc.ServerStream) error { + calls[name]++ + handler(t, srv, stream) + return nil + } + } + proxy.RegisterStreamHandlers(server, grpc_testing.TestService_ServiceDesc.ServiceName, registeredHandlers) + + listener := newListener(t) + go server.Serve(listener) + defer server.Stop() + + conn, err := client.Dial("tcp://"+listener.Addr().String(), []grpc.DialOption{grpc.WithBlock()}) + require.NoError(t, err) + defer conn.Close() + client := grpc_testing.NewTestServiceClient(conn) + + tc.execute(ctx, t, client) + + require.Equal(t, tc.expectedCalls, calls) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_test.go index b33fcba434..a4fafab583 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/handler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/handler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package proxy import ( @@ -8,6 +10,8 @@ import ( ) func TestFailDestinationWithError(t *testing.T) { + t.Parallel() + expectedErr := errors.New("some error") t.Run("works with nil ErrHandlers", func(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/peeker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/peeker.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy/peeker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/peeker.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/peeker_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/peeker_test.go new file mode 100644 index 0000000000..9b63653e87 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/peeker_test.go @@ -0,0 +1,154 @@ +//go:build !gitaly_test_sha256 + +package proxy_test + +import ( + "context" + "io" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "google.golang.org/grpc/test/grpc_testing" + "google.golang.org/protobuf/proto" +) + +// TestStreamPeeking demonstrates that a director function is able to peek into a stream. Further +// more, it demonstrates that peeking into a stream will not disturb the stream sent from the proxy +// client to the backend. +func TestStreamPeeking(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + backendCC, backendSrvr := newBackendPinger(t, ctx) + + requestSent := &grpc_testing.StreamingOutputCallRequest{ + Payload: &grpc_testing.Payload{ + Body: []byte("hi"), + }, + } + responseSent := &grpc_testing.StreamingOutputCallResponse{ + Payload: &grpc_testing.Payload{ + Body: []byte("bye"), + }, + } + + // We create a director that's peeking into the message in order to assert that the peeked + // message will still be seen by the client. + director := func(ctx context.Context, _ string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { + peekedMessage, err := peeker.Peek() + require.NoError(t, err) + + var peekedRequest grpc_testing.StreamingOutputCallRequest + require.NoError(t, proto.Unmarshal(peekedMessage, &peekedRequest)) + testhelper.ProtoEqual(t, requestSent, &peekedRequest) + + return proxy.NewStreamParameters(proxy.Destination{ + Ctx: metadata.IncomingToOutgoing(ctx), + Conn: backendCC, + Msg: peekedMessage, + }, nil, nil, nil), nil + } + + // The backend is supposed to still receive the message as expected without any modification + // to it. + backendSrvr.fullDuplexCall = func(stream grpc_testing.TestService_FullDuplexCallServer) error { + requestReceived, err := stream.Recv() + require.NoError(t, err) + testhelper.ProtoEqual(t, requestSent, requestReceived) + + return stream.Send(responseSent) + } + + proxyConn := newProxy(t, ctx, director, "grpc_testing.TestService", "FullDuplexCall") + proxyClient := grpc_testing.NewTestServiceClient(proxyConn) + + // Send the request on the stream and close the writing side. + proxyStream, err := proxyClient.FullDuplexCall(ctx) + require.NoError(t, err) + require.NoError(t, proxyStream.Send(requestSent)) + require.NoError(t, proxyStream.CloseSend()) + + // And now verify that the response we've got in fact matches our expected response. + responseReceived, err := proxyStream.Recv() + require.NoError(t, err) + testhelper.ProtoEqual(t, responseReceived, responseSent) + + _, err = proxyStream.Recv() + require.Equal(t, io.EOF, err) +} + +func TestStreamInjecting(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + + backendCC, backendSrvr := newBackendPinger(t, ctx) + + requestSent := &grpc_testing.StreamingOutputCallRequest{ + Payload: &grpc_testing.Payload{ + Body: []byte("hi"), + }, + } + requestReplaced := &grpc_testing.StreamingOutputCallRequest{ + Payload: &grpc_testing.Payload{ + Body: []byte("replaced"), + }, + } + responseSent := &grpc_testing.StreamingOutputCallResponse{ + Payload: &grpc_testing.Payload{ + Body: []byte("bye"), + }, + } + + // We create a director that peeks the incoming request and in fact changes its values. This + // is to assert that the client receives the changed requests. + director := func(ctx context.Context, fullMethodName string, peeker proxy.StreamPeeker) (*proxy.StreamParameters, error) { + peekedMessage, err := peeker.Peek() + require.NoError(t, err) + + // Assert that we get the expected original ping request. + var peekedRequest grpc_testing.StreamingOutputCallRequest + require.NoError(t, proto.Unmarshal(peekedMessage, &peekedRequest)) + testhelper.ProtoEqual(t, requestSent, &peekedRequest) + + // Replace the value of the peeked request and send along the changed request. + replacedMessage, err := proto.Marshal(requestReplaced) + require.NoError(t, err) + + return proxy.NewStreamParameters(proxy.Destination{ + Ctx: metadata.IncomingToOutgoing(ctx), + Conn: backendCC, + Msg: replacedMessage, + }, nil, nil, nil), nil + } + + // Upon receiving the request the backend server should only ever see the changed request. + backendSrvr.fullDuplexCall = func(stream grpc_testing.TestService_FullDuplexCallServer) error { + requestReceived, err := stream.Recv() + require.NoError(t, err) + testhelper.ProtoEqual(t, requestReplaced, requestReceived) + + return stream.Send(responseSent) + } + + proxyConn := newProxy(t, ctx, director, "grpc_testing.TestService", "FullDuplexCall") + proxyClient := grpc_testing.NewTestServiceClient(proxyConn) + + proxyStream, err := proxyClient.FullDuplexCall(ctx) + require.NoError(t, err) + defer func() { + require.NoError(t, proxyStream.CloseSend()) + }() + require.NoError(t, proxyStream.Send(requestSent)) + + responseReceived, err := proxyStream.Recv() + require.NoError(t, err) + testhelper.ProtoEqual(t, responseSent, responseReceived) + + _, err = proxyStream.Recv() + require.Equal(t, io.EOF, err) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/testhelper_test.go new file mode 100644 index 0000000000..bc7ffca5e6 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy/testhelper_test.go @@ -0,0 +1,131 @@ +//go:build !gitaly_test_sha256 + +package proxy_test + +import ( + "context" + "net" + "testing" + + grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" + grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/grpc_testing" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} + +func newListener(tb testing.TB) net.Listener { + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(tb, err, "must be able to allocate a port for listener") + + return listener +} + +func newBackendPinger(tb testing.TB, ctx context.Context) (*grpc.ClientConn, *interceptPinger) { + ip := &interceptPinger{} + + srvr := grpc.NewServer() + listener := newListener(tb) + + grpc_testing.RegisterTestServiceServer(srvr, ip) + + done := make(chan struct{}) + go func() { + defer close(done) + srvr.Serve(listener) + }() + + cc, err := grpc.DialContext( + ctx, + listener.Addr().String(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + grpc.WithDefaultCallOptions( + grpc.ForceCodec(proxy.NewCodec()), + ), + ) + require.NoError(tb, err) + + tb.Cleanup(func() { + srvr.GracefulStop() + require.NoError(tb, cc.Close()) + <-done + }) + + return cc, ip +} + +func newProxy(tb testing.TB, ctx context.Context, director proxy.StreamDirector, svc, method string) *grpc.ClientConn { + proxySrvr := grpc.NewServer( + grpc.ForceServerCodec(proxy.NewCodec()), + grpc.StreamInterceptor( + grpcmw.ChainStreamServer( + // context tags usage is required by sentryhandler.StreamLogHandler + grpcmwtags.StreamServerInterceptor(grpcmwtags.WithFieldExtractorForInitialReq(fieldextractors.FieldExtractor)), + // sentry middleware to capture errors + sentryhandler.StreamLogHandler, + ), + ), + grpc.UnknownServiceHandler(proxy.TransparentHandler(director)), + ) + proxy.RegisterService(proxySrvr, director, svc, method) + + done := make(chan struct{}) + listener := newListener(tb) + go func() { + defer close(done) + proxySrvr.Serve(listener) + }() + + proxyCC, err := grpc.DialContext( + ctx, + listener.Addr().String(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + require.NoError(tb, err) + + tb.Cleanup(func() { + proxySrvr.GracefulStop() + require.NoError(tb, proxyCC.Close()) + <-done + }) + + return proxyCC +} + +// interceptPinger allows an RPC to be intercepted with a custom +// function defined in each unit test +type interceptPinger struct { + grpc_testing.UnimplementedTestServiceServer + + fullDuplexCall func(grpc_testing.TestService_FullDuplexCallServer) error + emptyCall func(context.Context, *grpc_testing.Empty) (*grpc_testing.Empty, error) + unaryCall func(context.Context, *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) + streamingOutputCall func(*grpc_testing.StreamingOutputCallRequest, grpc_testing.TestService_StreamingOutputCallServer) error +} + +func (ip *interceptPinger) FullDuplexCall(stream grpc_testing.TestService_FullDuplexCallServer) error { + return ip.fullDuplexCall(stream) +} + +func (ip *interceptPinger) EmptyCall(ctx context.Context, req *grpc_testing.Empty) (*grpc_testing.Empty, error) { + return ip.emptyCall(ctx, req) +} + +func (ip *interceptPinger) UnaryCall(ctx context.Context, req *grpc_testing.SimpleRequest) (*grpc_testing.SimpleResponse, error) { + return ip.unaryCall(ctx, req) +} + +func (ip *interceptPinger) StreamingOutputCall(req *grpc_testing.StreamingOutputCallRequest, stream grpc_testing.TestService_StreamingOutputCallServer) error { + return ip.streamingOutputCall(req, stream) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/health_checker.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/health_checker.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/health_checker.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/health_checker.go index 45ae4c0218..36193812b5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/health_checker.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/health_checker.go @@ -9,7 +9,7 @@ type HealthChecker interface { // StaticHealthChecker returns the nodes as always healthy. type StaticHealthChecker map[string][]string -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (healthyNodes StaticHealthChecker) HealthyNodes() map[string][]string { return healthyNodes } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/helper_test.go new file mode 100644 index 0000000000..a8d98da5cb --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/helper_test.go @@ -0,0 +1,54 @@ +//go:build !gitaly_test_sha256 + +package praefect + +import ( + "context" + "fmt" + + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" +) + +// generates a praefect configuration with the specified number of backend +// nodes +func testConfig(backends int) config.Config { + var nodes []*config.Node + + for i := 0; i < backends; i++ { + n := &config.Node{ + Storage: fmt.Sprintf("praefect-internal-%d", i), + Token: fmt.Sprintf("%d", i), + } + + nodes = append(nodes, n) + } + cfg := config.Config{ + VirtualStorages: []*config.VirtualStorage{ + { + Name: "praefect", + Nodes: nodes, + }, + }, + } + + return cfg +} + +type nullNodeMgr struct{} + +func (nullNodeMgr) GetShard(ctx context.Context, virtualStorageName string) (nodes.Shard, error) { + return nodes.Shard{Primary: &nodes.MockNode{}}, nil +} + +func (nullNodeMgr) GetSyncedNode(ctx context.Context, virtualStorageName, repoPath string) (nodes.Node, error) { + return nil, nil +} + +func (nullNodeMgr) HealthyNodes() map[string][]string { + return nil +} + +func (nullNodeMgr) Nodes() map[string][]nodes.Node { + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/info_service_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/info_service_test.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/info_service_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/info_service_test.go index c89654f6ab..3c9d6c2115 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/info_service_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/info_service_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -5,23 +7,23 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - gconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -98,10 +100,10 @@ func TestInfoService_RepositoryReplicas(t *testing.T) { conns := nodeSet.Connections() rs := datastore.NewPostgresRepositoryStore(db, conf.StorageNames()) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withConnections: conns, - withRepoStore: rs, - withRouter: NewPerRepositoryRouter( + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithConnections: conns, + WithRepoStore: rs, + WithRouter: NewPerRepositoryRouter( conns, elector, StaticHealthChecker{virtualStorage: storages}, @@ -111,8 +113,8 @@ func TestInfoService_RepositoryReplicas(t *testing.T) { rs, conf.DefaultReplicationFactors(), ), - withPrimaryGetter: elector, - withTxMgr: txManager, + WithPrimaryGetter: elector, + WithTxMgr: txManager, }) // use cleanup to close the connections as gittest.CreateRepository will still use the connection // for clean up after the test. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics/prometheus.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics/prometheus.go similarity index 88% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics/prometheus.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics/prometheus.go index 7fdcbca429..f0bd9abee3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics/prometheus.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics/prometheus.go @@ -3,8 +3,8 @@ package metrics import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - gitalycfgprom "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/prometheus" - "gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics" + gitalycfgprom "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus" + "gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics" ) // RegisterReplicationDelay creates and registers a prometheus histogram @@ -54,7 +54,7 @@ func RegisterNodeLatency(conf gitalycfgprom.Config, registerer prometheus.Regist return nodeLatency, registerer.Register(nodeLatency) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. var MethodTypeCounter = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: "gitaly", @@ -63,7 +63,7 @@ var MethodTypeCounter = promauto.NewCounterVec( }, []string{"method_type"}, ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. var PrimaryGauge = promauto.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "gitaly", @@ -72,7 +72,7 @@ var PrimaryGauge = promauto.NewGaugeVec( }, []string{"virtual_storage", "gitaly_storage"}, ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. var NodeLastHealthcheckGauge = promauto.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "gitaly", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics/util.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics/util.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics/util.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics/util.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler.go index 1356a8c759..e609d53133 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler.go @@ -5,8 +5,8 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler_test.go index da16898b9b..9e221e7412 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/errorhandler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/errorhandler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package middleware import ( @@ -8,14 +10,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/protobuf/types/known/emptypb" ) @@ -72,7 +75,7 @@ func TestStreamInterceptor(t *testing.T) { ) (*proxy.StreamParameters, error) { cc, err := grpc.Dial("unix://"+internalServerSocketPath, grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec())), - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStreamInterceptor(StreamErrorHandler(registry, errTracker, nodeName)), ) require.NoError(t, err) @@ -91,7 +94,7 @@ func TestStreamInterceptor(t *testing.T) { defer praefectSrv.Stop() go praefectSrv.Serve(praefectLis) - praefectCC, err := grpc.Dial("unix://"+praefectSocket, grpc.WithInsecure()) + praefectCC, err := grpc.Dial("unix://"+praefectSocket, grpc.WithTransportCredentials(insecure.NewCredentials())) defer testhelper.MustClose(t, praefectCC) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/helper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/helper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/helper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/helper_test.go index b733100c0f..191dfe7491 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/helper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/helper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package middleware import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/methodtype.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/methodtype.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/methodtype.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/methodtype.go index a3a0667b33..bafa03ed9f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware/methodtype.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware/methodtype.go @@ -4,8 +4,8 @@ import ( "context" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.pb.go index ffdd2df38a..ddff64a1b8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.pb.go @@ -5,14 +5,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: praefect/mock/mock.proto package mock import ( - gitalypb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalypb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -103,7 +103,7 @@ var file_praefect_mock_mock_proto_rawDesc = []byte{ 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, + 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, 0x2f, 0x6d, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.proto similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.proto index 748befbf64..166c9d8bd0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock.proto @@ -7,7 +7,7 @@ syntax = "proto3"; package mock; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock"; import "shared.proto"; import "lint.proto"; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock_grpc.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock_grpc.pb.go index 0f3f1522aa..089f313b86 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock/mock_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock/mock_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: praefect/mock/mock.proto package mock diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mocksvc_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mocksvc_test.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mocksvc_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mocksvc_test.go index 69aa76ca63..de6caff2e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mocksvc_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mocksvc_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package praefect import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node.go index 13539b6919..60bad97c1a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node.go @@ -4,12 +4,12 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node_test.go index eebb9ba328..b9a4bfecc3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/node_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/node_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/health" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/disabled_elector.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/disabled_elector.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/disabled_elector.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/disabled_elector.go index 047e418576..4418787bfa 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/disabled_elector.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/disabled_elector.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" ) // newDisabledElector returns a stub that always returns the same shard where the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager.go index 89ea32b29e..ca758f459c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager.go @@ -8,8 +8,8 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc/health/grpc_health_v1" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager_test.go index 2016c26a3c..92959e37f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/health_manager_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/health_manager_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package nodes import ( @@ -7,10 +9,10 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" ) @@ -602,8 +604,8 @@ func TestHealthManager_databaseTimeout(t *testing.T) { require.EqualError(t, <-blockedErr, "update checks: timeout: context canceled") } -func predateHealthChecks(t testing.TB, db testdb.DB, amount time.Duration) { - t.Helper() +func predateHealthChecks(tb testing.TB, db testdb.DB, amount time.Duration) { + tb.Helper() _, err := db.Exec(` UPDATE node_status SET @@ -611,7 +613,7 @@ func predateHealthChecks(t testing.TB, db testdb.DB, amount time.Duration) { last_seen_active_at = last_seen_active_at - INTERVAL '1 MICROSECOND' * $1 `, amount.Microseconds(), ) - require.NoError(t, err) + require.NoError(tb, err) } // This test case ensures the record updates are done in an ordered manner to avoid concurrent writes diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/init_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/init_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/init_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/init_test.go index 1475680ed7..7109a39d5c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/init_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/init_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package nodes import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector.go index 95c2c3f35d..3b3ca173ac 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector.go @@ -6,7 +6,7 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" ) // localElector relies on an in-memory datastore to track the primary diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector_test.go index 63fa84f5e0..abb0768d89 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/local_elector_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/local_elector_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package nodes import ( @@ -6,10 +8,11 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) func setupElector(t *testing.T) (*localElector, []*nodeStatus, *grpc.ClientConn) { @@ -18,7 +21,7 @@ func setupElector(t *testing.T) (*localElector, []*nodeStatus, *grpc.ClientConn) cc, err := grpc.Dial( "unix://"+socket, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) t.Cleanup(func() { testhelper.MustClose(t, cc) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager.go similarity index 91% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager.go index e57abeb0bb..422d98342f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager.go @@ -11,18 +11,18 @@ import ( grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/sirupsen/logrus" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - prommetrics "gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + prommetrics "gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" "google.golang.org/grpc" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) @@ -33,7 +33,7 @@ type Shard struct { Secondaries []Node } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s Shard) GetNode(storage string) (Node, error) { if storage == s.Primary.GetStorage() { return s.Primary, nil @@ -140,6 +140,8 @@ func Dial(ctx context.Context, node *config.Node, registry *protoregistry.Regist grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(node.Token)), grpc.WithChainStreamInterceptor(streamInterceptors...), grpc.WithChainUnaryInterceptor(unaryInterceptors...), + client.UnaryInterceptor(), + client.StreamInterceptor(), } return client.Dial(ctx, node.Address, dialOpts, handshaker) @@ -260,7 +262,7 @@ func (n *Mgr) GetPrimary(ctx context.Context, virtualStorage string, _ int64) (s return shard.Primary.GetStorage(), nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (n *Mgr) GetSyncedNode(ctx context.Context, virtualStorageName, repoPath string) (Node, error) { _, upToDateStorages, err := n.csg.GetConsistentStorages(ctx, virtualStorageName, repoPath) if err != nil && !errors.As(err, new(commonerr.RepositoryNotFoundError)) { @@ -297,7 +299,7 @@ func (n *Mgr) GetSyncedNode(ctx context.Context, virtualStorageName, repoPath st return healthyStorages[rand.Intn(len(healthyStorages))], nil } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (n *Mgr) HealthyNodes() map[string][]string { healthy := make(map[string][]string, len(n.nodes)) for vs, nodes := range n.nodes { @@ -314,7 +316,7 @@ func (n *Mgr) HealthyNodes() map[string][]string { return healthy } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (n *Mgr) Nodes() map[string][]Node { return n.nodes } func newConnectionStatus(node config.Node, cc *grpc.ClientConn, l logrus.FieldLogger, latencyHist prommetrics.HistogramVec, errorTracker tracker.ErrorTracker) *nodeStatus { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager_test.go index 9a32bf87f9..d59193d8ba 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/manager_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/manager_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package nodes import ( @@ -9,13 +11,14 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" ) @@ -61,7 +64,7 @@ func TestNodeStatus(t *testing.T) { cc, err := grpc.Dial( "unix://"+socket, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer testhelper.MustClose(t, cc) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/mock.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/mock.go similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/mock.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/mock.go index d118874624..d30ba9461b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/mock.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/mock.go @@ -14,7 +14,7 @@ type MockManager struct { Storage string } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockManager) GetShard(_ context.Context, storage string) (Shard, error) { return m.GetShardFunc(storage) } @@ -58,17 +58,17 @@ type MockNode struct { Healthy bool } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockNode) GetStorage() string { return m.GetStorageMethod() } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockNode) IsHealthy() bool { return m.Healthy } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockNode) GetConnection() *grpc.ClientConn { return m.Conn } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockNode) GetAddress() string { return "" } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockNode) GetToken() string { return "" } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository.go index da313602c0..563903947b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository.go @@ -8,8 +8,8 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) // ErrNoPrimary is returned if the repository does not have a primary. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository_test.go index a0229c5733..3a75736f8a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/per_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/per_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package nodes import ( @@ -8,10 +10,10 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestPerRepositoryElector(t *testing.T) { @@ -25,18 +27,18 @@ func TestPerRepositoryElector(t *testing.T) { type state map[string]map[string]map[string]storageRecord - type matcher func(t testing.TB, primary string) + type matcher func(tb testing.TB, primary string) any := func(expected ...string) matcher { - return func(t testing.TB, primary string) { - t.Helper() - require.Contains(t, expected, primary) + return func(tb testing.TB, primary string) { + tb.Helper() + require.Contains(tb, expected, primary) } } noPrimary := func() matcher { - return func(t testing.TB, primary string) { - t.Helper() - require.Empty(t, primary) + return func(tb testing.TB, primary string) { + tb.Helper() + require.Empty(tb, primary) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping.go index ec0380af0a..e0bcd9b9b4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping.go @@ -8,10 +8,11 @@ import ( "strings" "sync" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" ) @@ -72,6 +73,8 @@ func (p *Ping) Address() string { func (p *Ping) dial(ctx context.Context) (*grpc.ClientConn, error) { opts := []grpc.DialOption{ grpc.WithBlock(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor(), } if len(p.token) > 0 { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping_test.go index 4857f8e801..72ac78a43f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/ping_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/ping_test.go @@ -1,10 +1,12 @@ +//go:build !gitaly_test_sha256 + package nodes import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" ) func TestNewPingSet(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector.go index b3adf2d8cb..224e5b3e45 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector.go @@ -12,9 +12,9 @@ import ( "github.com/google/uuid" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/metrics" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector_test.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector_test.go index 07760c869d..b2c90ac219 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/sql_elector_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/sql_elector_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package nodes import ( @@ -9,15 +11,15 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -46,7 +48,7 @@ func TestGetPrimaryAndSecondaries(t *testing.T) { cc0, err := grpc.Dial( "unix://"+internalSocket0, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer testhelper.MustClose(t, cc0) require.NoError(t, err) @@ -83,7 +85,7 @@ func TestSqlElector_slow_execution(t *testing.T) { gitalyConn, err := grpc.Dial( "unix://"+gitalySocket, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer testhelper.MustClose(t, gitalyConn) require.NoError(t, err) @@ -125,7 +127,7 @@ func TestBasicFailover(t *testing.T) { addr0 := "unix://" + internalSocket0 cc0, err := grpc.Dial( addr0, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer testhelper.MustClose(t, cc0) require.NoError(t, err) @@ -133,7 +135,7 @@ func TestBasicFailover(t *testing.T) { addr1 := "unix://" + internalSocket1 cc1, err := grpc.Dial( addr1, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer testhelper.MustClose(t, cc1) @@ -256,21 +258,21 @@ func TestElectDemotedPrimary(t *testing.T) { // predateLastSeenActiveAt shifts the last_seen_active_at column to an earlier time. This avoids // waiting for the node's status to become unhealthy. -func predateLastSeenActiveAt(t testing.TB, db testdb.DB, shardName, nodeName string, amount time.Duration) { - t.Helper() +func predateLastSeenActiveAt(tb testing.TB, db testdb.DB, shardName, nodeName string, amount time.Duration) { + tb.Helper() _, err := db.Exec(` UPDATE node_status SET last_seen_active_at = last_seen_active_at - INTERVAL '1 MICROSECOND' * $1 WHERE shard_name = $2 AND node_name = $3`, amount.Microseconds(), shardName, nodeName, ) - require.NoError(t, err) + require.NoError(tb, err) } // predateElection shifts the election to an earlier time. This avoids waiting for the failover timeout to trigger // a new election. -func predateElection(t testing.TB, ctx context.Context, db glsql.Querier, shardName string, amount time.Duration) { - t.Helper() +func predateElection(tb testing.TB, ctx context.Context, db glsql.Querier, shardName string, amount time.Duration) { + tb.Helper() _, err := db.ExecContext(ctx, "UPDATE shard_primaries SET elected_at = elected_at - INTERVAL '1 MICROSECOND' * $1 WHERE shard_name = $2", @@ -278,7 +280,7 @@ func predateElection(t testing.TB, ctx context.Context, db glsql.Querier, shardN shardName, ) - require.NoError(t, err) + require.NoError(tb, err) } func TestElectNewPrimary(t *testing.T) { @@ -500,7 +502,7 @@ func TestConnectionMultiplexing(t *testing.T) { require.Len(t, shard.Secondaries, 1) for _, node := range []Node{shard.Primary, shard.Secondaries[0]} { - require.Equal(t, + testhelper.RequireGrpcError(t, tc.error, node.GetConnection().Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{}), ) @@ -509,7 +511,7 @@ func TestConnectionMultiplexing(t *testing.T) { nodes := mgr.Nodes()["virtual-storage-1"] require.Len(t, nodes, 2) for _, node := range nodes { - require.Equal(t, + testhelper.RequireGrpcError(t, tc.error, node.GetConnection().Invoke(ctx, "/Service/Method", &gitalypb.VoteTransactionRequest{}, &gitalypb.VoteTransactionResponse{}), ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors.go index 0074dab095..8a87d30ccf 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" ) // ErrorTracker allows tracking how many read/write errors have occurred, and whether or not it has diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors_test.go index 3d1a03566c..81e4a8e3b2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/errors_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/errors_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package tracker import ( @@ -8,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) var ( @@ -102,8 +104,8 @@ func TestErrorTracker_ClearErrors(t *testing.T) { errors.IncrReadErr(node) errors.clear() - assert.Len(t, errors.readErrors[node], 1, "clear should only have cleared the read error older than the time specifiied") - assert.Len(t, errors.writeErrors[node], 1, "clear should only have cleared the write error older than the time specifiied") + assert.Len(t, errors.readErrors[node], 1, "clear should only have cleared the read error older than the time specified") + assert.Len(t, errors.writeErrors[node], 1, "clear should only have cleared the write error older than the time specified") } func TestErrorTracker_Expired(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/health_client.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/health_client.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker/health_client.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker/health_client.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path.go new file mode 100644 index 0000000000..1bf34b33b2 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path.go @@ -0,0 +1,45 @@ +package praefectutil + +import ( + "crypto/sha256" + "fmt" + "path/filepath" + "strconv" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" +) + +// poolPathPrefix is the prefix directory where Praefect places object pools. +const poolPathPrefix = "@cluster/pools/" + +// IsPoolRepository returns whether the repository is a Praefect generated object pool repository. +func IsPoolRepository(repo repository.GitRepo) bool { + return strings.HasPrefix(repo.GetRelativePath(), poolPathPrefix) +} + +// DeriveReplicaPath derives a repository's disk storage path from its repository ID. The repository ID +// is hashed with SHA256 and the first four hex digits of the hash are used as the two subdirectories to +// ensure even distribution into subdirectories. The format is @cluster/repositories/ab/cd/. +func DeriveReplicaPath(repositoryID int64) string { + return deriveDiskPath("@cluster/repositories", repositoryID) +} + +// DerivePoolPath derives an object pools's disk storage path from its repository ID. The repository ID +// is hashed with SHA256 and the first four hex digits of the hash are used as the two subdirectories to +// ensure even distribution into subdirectories. The format is @cluster/pools/ab/cd/. The pools +// have a different directory prefix from other repositories so Gitaly can identify them in OptimizeRepository +// and avoid pruning them. +func DerivePoolPath(repositoryID int64) string { + return deriveDiskPath(poolPathPrefix, repositoryID) +} + +func deriveDiskPath(prefixDir string, repositoryID int64) string { + hasher := sha256.New() + // String representation of the ID is used to make it easier to derive the replica paths with + // external tools. The error is ignored as the hash.Hash interface is documented to never return + // an error. + hasher.Write([]byte(strconv.FormatInt(repositoryID, 10))) + hash := hasher.Sum(nil) + return filepath.Join(prefixDir, fmt.Sprintf("%x/%x/%d", hash[0:1], hash[1:2], repositoryID)) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path_test.go new file mode 100644 index 0000000000..c68002262f --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil/replica_path_test.go @@ -0,0 +1,64 @@ +//go:build !gitaly_test_sha256 + +package praefectutil + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func TestDeriveReplicaPath(t *testing.T) { + require.Equal(t, "@cluster/repositories/6b/86/1", DeriveReplicaPath(1)) + require.Equal(t, "@cluster/repositories/d4/73/2", DeriveReplicaPath(2)) +} + +func TestDerivePoolPath(t *testing.T) { + require.Equal(t, "@cluster/pools/6b/86/1", DerivePoolPath(1)) + require.Equal(t, "@cluster/pools/d4/73/2", DerivePoolPath(2)) +} + +func TestIsPoolRepository(t *testing.T) { + for _, tc := range []struct { + desc string + repo *gitalypb.Repository + isPoolPath bool + }{ + { + desc: "missing repository", + isPoolPath: false, + }, + { + desc: "empty string", + repo: &gitalypb.Repository{ + RelativePath: "", + }, + isPoolPath: false, + }, + { + desc: "praefect pool path", + repo: &gitalypb.Repository{ + RelativePath: DerivePoolPath(1), + }, + isPoolPath: true, + }, + { + desc: "praefect replica path", + repo: &gitalypb.Repository{ + RelativePath: DeriveReplicaPath(1), + }, + }, + { + desc: "rails pool path", + repo: &gitalypb.Repository{ + RelativePath: gittest.NewObjectPoolName(t), + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.isPoolPath, IsPoolRepository(tc.repo)) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid.go index b6e80ba98d..3f29358fa6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid.go @@ -7,7 +7,7 @@ import ( "regexp" "strconv" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid_test.go index b22846054e..d4b01f25af 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/find_oid_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/find_oid_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package protoregistry_test import ( @@ -6,8 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" ) @@ -76,7 +78,6 @@ func TestProtoRegistryTargetRepo(t *testing.T) { pbMsg: &gitalypb.FetchIntoObjectPoolRequest{ Origin: testRepos[0], ObjectPool: &gitalypb.ObjectPool{Repository: testRepos[1]}, - Repack: false, }, expectRepo: testRepos[1], expectAdditionalRepo: testRepos[0], diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry.go index d2b900b1eb..2bfb77706d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/protoutil" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/protoutil" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" @@ -100,7 +100,7 @@ func (mi MethodInfo) AdditionalRepo(msg proto.Message) (*gitalypb.Repository, bo return repo, true, err } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mi MethodInfo) FullMethodName() string { return mi.fullMethodName } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry_test.go index 89976b7c5b..eb42330df9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry/protoregistry_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry/protoregistry_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package protoregistry_test import ( @@ -5,9 +7,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestNewProtoRegistry(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/random.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/random.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/random.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/random.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/random_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/random_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/random_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/random_test.go index d24fe56c41..4aa3aa8d7d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/random_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/random_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler.go index 1908ef9ee9..a04b1ecc09 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler.go @@ -6,10 +6,10 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/advisorylock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/advisorylock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) const logBatchSize = 25 @@ -49,12 +49,12 @@ func NewReconciler(log logrus.FieldLogger, db glsql.Querier, hc praefect.HealthC return r } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r *Reconciler) Describe(ch chan<- *prometheus.Desc) { prometheus.DescribeByCollect(r, ch) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r *Reconciler) Collect(ch chan<- prometheus.Metric) { r.reconciliationSchedulingDuration.Collect(ch) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_benchmark_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_benchmark_test.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_benchmark_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_benchmark_test.go index abb95d8d8a..e5038515a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_benchmark_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_benchmark_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package reconciler import ( @@ -6,9 +8,9 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func BenchmarkReconcile(b *testing.B) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_test.go index 6390c9478d..4ba7ea238f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/reconciler/reconciler_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/reconciler/reconciler_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package reconciler import ( @@ -9,13 +11,13 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" ) func TestReconciler(t *testing.T) { @@ -386,11 +388,6 @@ func TestReconciler(t *testing.T) { []datastore.ChangeType{ datastore.DeleteRepo, datastore.RenameRepo, - datastore.GarbageCollect, - datastore.RepackFull, - datastore.RepackIncremental, - datastore.Cleanup, - datastore.PackRefs, }, datastore.ReplicationJob{ VirtualStorage: "virtual-storage-1", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository.go index 74a033ef8d..5b6ef285d9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository.go @@ -9,10 +9,10 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/protobuf/proto" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository_test.go index 56d6020a9f..f9eaf057ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/remove_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/remove_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,20 +9,21 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" ) @@ -117,18 +120,19 @@ func TestRemoveRepositoryHandler(t *testing.T) { nodeSet.Connections(), nil, nil, + nil, ) defer srv.Stop() go func() { srv.Serve(ln) }() - clientConn, err := grpc.DialContext(ctx, "unix:"+ln.Addr().String(), grpc.WithInsecure()) + clientConn, err := grpc.DialContext(ctx, "unix:"+ln.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer clientConn.Close() client := gitalypb.NewRepositoryServiceClient(clientConn) _, err = client.RepositorySize(ctx, &gitalypb.RepositorySizeRequest{Repository: tc.repository}) - require.Equal(t, errServedByGitaly, err, "other RPCs should be passed through") + testhelper.RequireGrpcError(t, errServedByGitaly, err) assertExistence := require.DirExists if tc.repoDeleted { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/rename_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/rename_repository.go new file mode 100644 index 0000000000..1a09189409 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/rename_repository.go @@ -0,0 +1,160 @@ +package praefect + +import ( + "errors" + "fmt" + "strings" + + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" +) + +type renamePeeker struct { + grpc.ServerStream + peeked *gitalypb.RenameRepositoryRequest +} + +func (peeker *renamePeeker) RecvMsg(msg interface{}) error { + // On the first read, we'll return the peeked first message of the stream. + if peeker.peeked != nil { + peeked := peeker.peeked + peeker.peeked = nil + + codec := proxy.NewCodec() + payload, err := codec.Marshal(peeked) + if err != nil { + return fmt.Errorf("marshaling peeked rename request: %w", err) + } + + return codec.Unmarshal(payload, msg) + } + + return peeker.ServerStream.RecvMsg(msg) +} + +func validateRenameRepositoryRequest(req *gitalypb.RenameRepositoryRequest, virtualStorages map[string]struct{}) error { + // These checks are not strictly necessary but they exist to keep retain compatibility with + // Gitaly's tested behavior. + if req.GetRepository() == nil { + return helper.ErrInvalidArgumentf("empty Repository") + } else if req.GetRelativePath() == "" { + return helper.ErrInvalidArgumentf("destination relative path is empty") + } else if _, ok := virtualStorages[req.GetRepository().GetStorageName()]; !ok { + return helper.ErrInvalidArgumentf("GetStorageByName: no such storage: %q", req.GetRepository().GetStorageName()) + } else if _, err := storage.ValidateRelativePath("/fake-root", req.GetRelativePath()); err != nil { + // Gitaly uses ValidateRelativePath to verify there are no traversals, so we use the same function + // here. Praefect is not susceptible to path traversals as it generates its own disk paths but we + // do this to retain API compatibility with Gitaly. ValidateRelativePath checks for traversals by + // seeing whether the relative path escapes the root directory. It's not possible to traverse up + // from the /, so the traversals in the path wouldn't be caught. To allow for the check to work, + // we use the /fake-root directory simply to notice if there were traversals in the path. + return helper.ErrInvalidArgumentf("GetRepoPath: %s", err) + } + + return nil +} + +// RenameRepositoryFeatureFlagger decides whether Praefect should handle the rename request or whether it should +// be proxied to a Gitaly. Rolling out Praefect generated replica paths is difficult as the atomicity fixes depend on the +// unique replica paths. If the unique replica paths are disabled, the in-place rename handling makes no longer sense either. +// Since they don't work isolation, this method decides which handling is used based on whether the repository is using a Praefect +// generated replica path or not. Repositories with client set paths are handled non-atomically by proxying to Gitalys. +// The Praefect generated paths are always handled with the atomic handling, regardless whether the feature flag is disabled +// later. +// +// This function peeks the first request and forwards the call either to a Gitaly or handles it in Praefect. This requires +// peeking into the internals of the proxying so we can set restore the frame correctly. +func RenameRepositoryFeatureFlagger(virtualStorageNames []string, rs datastore.RepositoryStore, handleRenameRepository grpc.StreamHandler) grpc.StreamServerInterceptor { + virtualStorages := make(map[string]struct{}, len(virtualStorageNames)) + for _, virtualStorage := range virtualStorageNames { + virtualStorages[virtualStorage] = struct{}{} + } + + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if info.FullMethod != "/gitaly.RepositoryService/RenameRepository" { + return handler(srv, stream) + } + + // Peek the message + var request gitalypb.RenameRepositoryRequest + if err := stream.RecvMsg(&request); err != nil { + return fmt.Errorf("peek rename repository request: %w", err) + } + + // In order for the handlers to work after the message is peeked, the stream is restored + // with an alternative implementation that returns the first message correctly. + stream = &renamePeeker{ServerStream: stream, peeked: &request} + + if err := validateRenameRepositoryRequest(&request, virtualStorages); err != nil { + return err + } + + repo := request.GetRepository() + repositoryID, err := rs.GetRepositoryID(stream.Context(), repo.GetStorageName(), repo.GetRelativePath()) + if err != nil { + if errors.As(err, new(commonerr.RepositoryNotFoundError)) { + return helper.ErrNotFoundf("GetRepoPath: not a git repository: \"%s/%s\"", repo.GetStorageName(), repo.GetRelativePath()) + } + + return fmt.Errorf("get repository id: %w", err) + } + + replicaPath, err := rs.GetReplicaPath(stream.Context(), repositoryID) + if err != nil { + return fmt.Errorf("get replica path: %w", err) + } + + // Repositories that do not have a Praefect generated replica path are always handled in the old manner. + // Once the feature flag is removed, all of the repositories will be handled in the atomic manner. + if !strings.HasPrefix(replicaPath, "@cluster") { + return handler(srv, stream) + } + + return handleRenameRepository(srv, stream) + } +} + +// RenameRepositoryHandler handles /gitaly.RepositoryService/RenameRepository calls by renaming +// the repository in the lookup table stored in the database. +func RenameRepositoryHandler(virtualStoragesNames []string, rs datastore.RepositoryStore) grpc.StreamHandler { + virtualStorages := make(map[string]struct{}, len(virtualStoragesNames)) + for _, virtualStorage := range virtualStoragesNames { + virtualStorages[virtualStorage] = struct{}{} + } + + return func(srv interface{}, stream grpc.ServerStream) error { + var req gitalypb.RenameRepositoryRequest + if err := stream.RecvMsg(&req); err != nil { + return fmt.Errorf("receive request: %w", err) + } + + if err := validateRenameRepositoryRequest(&req, virtualStorages); err != nil { + return err + } + + if err := rs.RenameRepositoryInPlace(stream.Context(), + req.GetRepository().GetStorageName(), + req.GetRepository().GetRelativePath(), + req.GetRelativePath(), + ); err != nil { + if errors.Is(err, commonerr.ErrRepositoryNotFound) { + return helper.ErrNotFoundf( + `GetRepoPath: not a git repository: "%s/%s"`, + req.GetRepository().GetStorageName(), + req.GetRepository().GetRelativePath(), + ) + } else if errors.Is(err, commonerr.ErrRepositoryAlreadyExists) { + return helper.ErrAlreadyExistsf("target repo exists already") + } + + return helper.ErrInternal(err) + } + + return stream.SendMsg(&gitalypb.RenameRepositoryResponse{}) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator.go similarity index 72% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator.go index fcca4b1332..d3d36c586d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator.go @@ -9,14 +9,14 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - prommetrics "gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + prommetrics "gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "google.golang.org/grpc" "google.golang.org/protobuf/proto" @@ -30,24 +30,6 @@ type Replicator interface { Destroy(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error // Rename will rename(move) the target repo on the specified target connection Rename(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // GarbageCollect will run gc on the target repository - GarbageCollect(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // RepackFull will do a full repack on the target repository - RepackFull(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // RepackIncremental will do an incremental repack on the target repository - RepackIncremental(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // Cleanup will do a cleanup on the target repository - Cleanup(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // PackRefs will optimize references on the target repository - PackRefs(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // WriteCommitGraph will optimize references on the target repository - WriteCommitGraph(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // MidxRepack will optimize references on the target repository - MidxRepack(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // OptimizeRepository will optimize the target repository - OptimizeRepository(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error - // PruneUnreachableObjects prunes unreachable objects from the target repository - PruneUnreachableObjects(ctx context.Context, event datastore.ReplicationEvent, target *grpc.ClientConn) error } type defaultReplicator struct { @@ -216,199 +198,6 @@ func (dr defaultReplicator) Rename(ctx context.Context, event datastore.Replicat return nil } -func (dr defaultReplicator) GarbageCollect(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - createBitmap, err := event.Job.Params.GetBool("CreateBitmap") - if err != nil { - return fmt.Errorf("getting CreateBitmap parameter for GarbageCollect: %w", err) - } - - prune, err := event.Job.Params.GetBool("Prune") - if err != nil { - return fmt.Errorf("getting Purge parameter for GarbageCollect: %w", err) - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - if _, err := repoSvcClient.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{ - Repository: targetRepo, - CreateBitmap: createBitmap, - Prune: prune, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) RepackIncremental(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - _, err := repoSvcClient.RepackIncremental(ctx, &gitalypb.RepackIncrementalRequest{ - Repository: targetRepo, - }) - - return err -} - -func (dr defaultReplicator) Cleanup(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - _, err := repoSvcClient.Cleanup(ctx, &gitalypb.CleanupRequest{ - Repository: targetRepo, - }) - - return err -} - -func (dr defaultReplicator) PackRefs(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - refSvcClient := gitalypb.NewRefServiceClient(targetCC) - - //nolint:staticcheck - if _, err := refSvcClient.PackRefs(ctx, &gitalypb.PackRefsRequest{ - Repository: targetRepo, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) WriteCommitGraph(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - val, found := event.Job.Params["SplitStrategy"] - if !found { - return fmt.Errorf("no SplitStrategy parameter for WriteCommitGraph") - } - - // While we store the parameter as the correct type in the in-memory replication queue, the - // Postgres queue will serialize parameters into a JSON structure. On deserialization, we'll - // thus get a float64 and need to cast it. - var splitStrategy gitalypb.WriteCommitGraphRequest_SplitStrategy - switch v := val.(type) { - case float64: - splitStrategy = gitalypb.WriteCommitGraphRequest_SplitStrategy(v) - case gitalypb.WriteCommitGraphRequest_SplitStrategy: - splitStrategy = v - default: - return fmt.Errorf("split strategy has wrong type %T", val) - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - if _, err := repoSvcClient.WriteCommitGraph(ctx, &gitalypb.WriteCommitGraphRequest{ - Repository: targetRepo, - SplitStrategy: splitStrategy, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) MidxRepack(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - if _, err := repoSvcClient.MidxRepack(ctx, &gitalypb.MidxRepackRequest{ - Repository: targetRepo, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) OptimizeRepository(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - if _, err := repoSvcClient.OptimizeRepository(ctx, &gitalypb.OptimizeRepositoryRequest{ - Repository: targetRepo, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) PruneUnreachableObjects(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - if _, err := repoSvcClient.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{ - Repository: targetRepo, - }); err != nil { - return err - } - - return nil -} - -func (dr defaultReplicator) RepackFull(ctx context.Context, event datastore.ReplicationEvent, targetCC *grpc.ClientConn) error { - targetRepo := &gitalypb.Repository{ - StorageName: event.Job.TargetNodeStorage, - RelativePath: event.Job.ReplicaPath, - } - - createBitmap, err := event.Job.Params.GetBool("CreateBitmap") - if err != nil { - return fmt.Errorf("getting CreateBitmap parameter for RepackFull: %w", err) - } - - repoSvcClient := gitalypb.NewRepositoryServiceClient(targetCC) - - //nolint:staticcheck - if _, err := repoSvcClient.RepackFull(ctx, &gitalypb.RepackFullRequest{ - Repository: targetRepo, - CreateBitmap: createBitmap, - }); err != nil { - return err - } - - return nil -} - // ReplMgr is a replication manager for handling replication jobs type ReplMgr struct { log *logrus.Entry @@ -498,12 +287,12 @@ func NewReplMgr(log logrus.FieldLogger, storageNames map[string][]string, queue return r } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r ReplMgr) Describe(ch chan<- *prometheus.Desc) { prometheus.DescribeByCollect(r, ch) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r ReplMgr) Collect(ch chan<- prometheus.Metric) { r.replInFlightMetric.Collect(ch) } @@ -850,24 +639,6 @@ func (r ReplMgr) processReplicationEvent(ctx context.Context, event datastore.Re err = r.replicator.Destroy(ctx, event, targetCC) case datastore.RenameRepo: err = r.replicator.Rename(ctx, event, targetCC) - case datastore.GarbageCollect: - err = r.replicator.GarbageCollect(ctx, event, targetCC) - case datastore.RepackFull: - err = r.replicator.RepackFull(ctx, event, targetCC) - case datastore.RepackIncremental: - err = r.replicator.RepackIncremental(ctx, event, targetCC) - case datastore.Cleanup: - err = r.replicator.Cleanup(ctx, event, targetCC) - case datastore.PackRefs: - err = r.replicator.PackRefs(ctx, event, targetCC) - case datastore.WriteCommitGraph: - err = r.replicator.WriteCommitGraph(ctx, event, targetCC) - case datastore.MidxRepack: - err = r.replicator.MidxRepack(ctx, event, targetCC) - case datastore.OptimizeRepository: - err = r.replicator.OptimizeRepository(ctx, event, targetCC) - case datastore.PruneUnreachableObjects: - err = r.replicator.PruneUnreachableObjects(ctx, event, targetCC) default: err = fmt.Errorf("unknown replication change type encountered: %q", event.Job.Change) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_pg_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_pg_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_pg_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_pg_test.go index 7fd5be3f2d..4bd66365e9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_pg_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_pg_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,13 +9,14 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) type mockRepositoryService struct { @@ -101,7 +104,7 @@ func TestReplicatorDestroy(t *testing.T) { go srv.Serve(ln) defer srv.Stop() - clientConn, err := grpc.Dial(ln.Addr().String(), grpc.WithInsecure()) + clientConn, err := grpc.Dial(ln.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer clientConn.Close() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_test.go similarity index 64% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_test.go index 89e5d342c7..b9349a0bc5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/replicator_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/replicator_test.go @@ -1,8 +1,9 @@ +//go:build !gitaly_test_sha256 + package praefect import ( "context" - "fmt" "path/filepath" "strings" "sync" @@ -15,33 +16,32 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/objectpool" - gconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/objectpool" + gconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" ) @@ -279,358 +279,19 @@ func TestReplicatorDowngradeAttempt(t *testing.T) { } } -func TestReplicator_PropagateReplicationJob(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - primaryStorage, secondaryStorage := "internal-gitaly-0", "internal-gitaly-1" - - primCfg := testcfg.Build(t, testcfg.WithStorages(primaryStorage)) - primaryServer, primarySocketPath := runMockRepositoryServer(t, primCfg) - - secCfg := testcfg.Build(t, testcfg.WithStorages(secondaryStorage)) - secondaryServer, secondarySocketPath := runMockRepositoryServer(t, secCfg) - - conf := config.Config{ - VirtualStorages: []*config.VirtualStorage{ - { - Name: "default", - Nodes: []*config.Node{ - { - Storage: primaryStorage, - Address: primarySocketPath, - }, - { - Storage: secondaryStorage, - Address: secondarySocketPath, - }, - }, - }, - }, - } - - // We need to await for the replication event to make a complete roundtrip to the remote. - // Because send to the channel happens during in-flight request there are ongoing filesystem - // operations related to caching. The cleanup happens before all IO cache operations finished - // those resulting to: - // unlinkat /tmp/gitaly-222007427/381349228/storages.d/internal-gitaly-1/+gitaly/state/path/to/repo: directory not empty - // By using WaitGroup we are sure the test cleanup will be started after all replication - // requests are completed, so no running cache IO operations happen. - queue := datastore.NewReplicationEventQueueInterceptor(datastore.NewPostgresReplicationEventQueue(testdb.New(t))) - - var wg sync.WaitGroup - // When maintenance operation routing is enabled we don't expect to see any - // replication events. The observed behaviour should still be the same though: we - // expect to observe the RPC calls on both the primary and secondary node because we - // route them to both at the same time. - queue.OnEnqueue(func(ctx context.Context, event datastore.ReplicationEvent, queue datastore.ReplicationEventQueue) (datastore.ReplicationEvent, error) { - require.FailNow(t, "no replication jobs should have been created") - return datastore.ReplicationEvent{}, fmt.Errorf("unexpected enqueue") - }) - - logEntry := testhelper.NewDiscardingLogEntry(t) - - nodeMgr, err := nodes.NewManager(logEntry, conf, nil, nil, promtest.NewMockHistogramVec(), protoregistry.GitalyProtoPreregistered, nil, nil, nil) - require.NoError(t, err) - nodeMgr.Start(0, time.Hour) - defer nodeMgr.Stop() - - txMgr := transactions.NewManager(conf) - - repositoryRelativePath := "/path/to/repo" - - rs := datastore.MockRepositoryStore{ - GetConsistentStoragesFunc: func(ctx context.Context, virtualStorage, relativePath string) (string, map[string]struct{}, error) { - return repositoryRelativePath, nil, nil - }, - GetReplicaPathFunc: func(ctx context.Context, repositoryID int64) (string, error) { - return repositoryRelativePath, nil - }, - } - - coordinator := NewCoordinator( - queue, - rs, - NewNodeManagerRouter(nodeMgr, rs), - txMgr, - conf, - protoregistry.GitalyProtoPreregistered, - ) - - replmgr := NewReplMgr(logEntry, conf.StorageNames(), queue, rs, nodeMgr, NodeSetFromNodeManager(nodeMgr)) - - prf := NewGRPCServer(conf, logEntry, protoregistry.GitalyProtoPreregistered, coordinator.StreamDirector, txMgr, rs, nil, nil, nil, nil) - - listener, port := listenAvailPort(t) - ctx, cancel := context.WithCancel(ctx) - - go prf.Serve(listener) - defer prf.Stop() - - cc := dialLocalPort(t, port, false) - repositoryClient := gitalypb.NewRepositoryServiceClient(cc) - refClient := gitalypb.NewRefServiceClient(cc) - defer listener.Close() - defer cc.Close() - - repository := &gitalypb.Repository{ - StorageName: conf.VirtualStorages[0].Name, - RelativePath: repositoryRelativePath, - } - - //nolint:staticcheck - _, err = repositoryClient.GarbageCollect(ctx, &gitalypb.GarbageCollectRequest{ - Repository: repository, - CreateBitmap: true, - Prune: true, - }) - require.NoError(t, err) - - //nolint:staticcheck - _, err = repositoryClient.RepackFull(ctx, &gitalypb.RepackFullRequest{Repository: repository, CreateBitmap: false}) - require.NoError(t, err) - - //nolint:staticcheck - _, err = repositoryClient.RepackIncremental(ctx, &gitalypb.RepackIncrementalRequest{Repository: repository}) - require.NoError(t, err) - - //nolint:staticcheck - _, err = repositoryClient.Cleanup(ctx, &gitalypb.CleanupRequest{Repository: repository}) - require.NoError(t, err) - - //nolint:staticcheck - _, err = repositoryClient.WriteCommitGraph(ctx, &gitalypb.WriteCommitGraphRequest{ - Repository: repository, - // This is not a valid split strategy, but we currently only support a - // single default split strategy with value 0. So we just test with an - // invalid split strategy to check that a non-default value gets properly - // replicated. - SplitStrategy: 1, - }) - require.NoError(t, err) - - //nolint:staticcheck - _, err = repositoryClient.MidxRepack(ctx, &gitalypb.MidxRepackRequest{Repository: repository}) - require.NoError(t, err) - - _, err = repositoryClient.OptimizeRepository(ctx, &gitalypb.OptimizeRepositoryRequest{Repository: repository}) - require.NoError(t, err) - - _, err = repositoryClient.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{Repository: repository}) - require.NoError(t, err) - - //nolint:staticcheck - _, err = refClient.PackRefs(ctx, &gitalypb.PackRefsRequest{ - Repository: repository, - }) - require.NoError(t, err) - - primaryRepository := &gitalypb.Repository{StorageName: primaryStorage, RelativePath: repositoryRelativePath} - expectedPrimaryGcReq := &gitalypb.GarbageCollectRequest{ - Repository: primaryRepository, - CreateBitmap: true, - Prune: true, - } - expectedPrimaryRepackFullReq := &gitalypb.RepackFullRequest{ - Repository: primaryRepository, - CreateBitmap: false, - } - expectedPrimaryRepackIncrementalReq := &gitalypb.RepackIncrementalRequest{ - Repository: primaryRepository, - } - expectedPrimaryCleanup := &gitalypb.CleanupRequest{ - Repository: primaryRepository, - } - expectedPrimaryWriteCommitGraph := &gitalypb.WriteCommitGraphRequest{ - Repository: primaryRepository, - SplitStrategy: 1, - } - expectedPrimaryMidxRepack := &gitalypb.MidxRepackRequest{ - Repository: primaryRepository, - } - expectedPrimaryOptimizeRepository := &gitalypb.OptimizeRepositoryRequest{ - Repository: primaryRepository, - } - expectedPruneUnreachableObjects := &gitalypb.PruneUnreachableObjectsRequest{ - Repository: primaryRepository, - } - expectedPrimaryPackRefs := &gitalypb.PackRefsRequest{ - Repository: primaryRepository, - } - - replMgrDone := startProcessBacklog(ctx, replmgr) - - // ensure primary gitaly server received the expected requests - waitForRequest(t, primaryServer.gcChan, expectedPrimaryGcReq, 5*time.Second) - waitForRequest(t, primaryServer.repackIncrChan, expectedPrimaryRepackIncrementalReq, 5*time.Second) - waitForRequest(t, primaryServer.repackFullChan, expectedPrimaryRepackFullReq, 5*time.Second) - waitForRequest(t, primaryServer.cleanupChan, expectedPrimaryCleanup, 5*time.Second) - waitForRequest(t, primaryServer.writeCommitGraphChan, expectedPrimaryWriteCommitGraph, 5*time.Second) - waitForRequest(t, primaryServer.midxRepackChan, expectedPrimaryMidxRepack, 5*time.Second) - waitForRequest(t, primaryServer.optimizeRepositoryChan, expectedPrimaryOptimizeRepository, 5*time.Second) - waitForRequest(t, primaryServer.pruneUnreachableObjectsChan, expectedPruneUnreachableObjects, 5*time.Second) - waitForRequest(t, primaryServer.packRefsChan, expectedPrimaryPackRefs, 5*time.Second) - - secondaryRepository := &gitalypb.Repository{StorageName: secondaryStorage, RelativePath: repositoryRelativePath} - - expectedSecondaryGcReq := expectedPrimaryGcReq - expectedSecondaryGcReq.Repository = secondaryRepository - - expectedSecondaryRepackFullReq := expectedPrimaryRepackFullReq - expectedSecondaryRepackFullReq.Repository = secondaryRepository - - expectedSecondaryRepackIncrementalReq := expectedPrimaryRepackIncrementalReq - expectedSecondaryRepackIncrementalReq.Repository = secondaryRepository - - expectedSecondaryCleanup := expectedPrimaryCleanup - expectedSecondaryCleanup.Repository = secondaryRepository - - expectedSecondaryWriteCommitGraph := expectedPrimaryWriteCommitGraph - expectedSecondaryWriteCommitGraph.Repository = secondaryRepository - - expectedSecondaryMidxRepack := expectedPrimaryMidxRepack - expectedSecondaryMidxRepack.Repository = secondaryRepository - - expectedSecondaryOptimizeRepository := expectedPrimaryOptimizeRepository - expectedSecondaryOptimizeRepository.Repository = secondaryRepository - - expectedSecondaryPruneUnreachableObjects := expectedPruneUnreachableObjects - expectedSecondaryPruneUnreachableObjects.Repository = secondaryRepository - - expectedSecondaryPackRefs := expectedPrimaryPackRefs - expectedSecondaryPackRefs.Repository = secondaryRepository - - // ensure secondary gitaly server received the expected requests - waitForRequest(t, secondaryServer.gcChan, expectedSecondaryGcReq, 5*time.Second) - waitForRequest(t, secondaryServer.repackIncrChan, expectedSecondaryRepackIncrementalReq, 5*time.Second) - waitForRequest(t, secondaryServer.repackFullChan, expectedSecondaryRepackFullReq, 5*time.Second) - waitForRequest(t, secondaryServer.cleanupChan, expectedSecondaryCleanup, 5*time.Second) - waitForRequest(t, secondaryServer.writeCommitGraphChan, expectedSecondaryWriteCommitGraph, 5*time.Second) - waitForRequest(t, secondaryServer.midxRepackChan, expectedSecondaryMidxRepack, 5*time.Second) - waitForRequest(t, secondaryServer.optimizeRepositoryChan, expectedSecondaryOptimizeRepository, 5*time.Second) - waitForRequest(t, secondaryServer.pruneUnreachableObjectsChan, expectedSecondaryPruneUnreachableObjects, 5*time.Second) - waitForRequest(t, secondaryServer.packRefsChan, expectedSecondaryPackRefs, 5*time.Second) - wg.Wait() - cancel() - <-replMgrDone -} - -type mockServer struct { - gcChan, repackFullChan, repackIncrChan, cleanupChan, writeCommitGraphChan, midxRepackChan, optimizeRepositoryChan, pruneUnreachableObjectsChan, packRefsChan chan proto.Message - - gitalypb.UnimplementedRepositoryServiceServer - gitalypb.UnimplementedRefServiceServer -} - -func newMockRepositoryServer() *mockServer { - return &mockServer{ - gcChan: make(chan proto.Message), - repackFullChan: make(chan proto.Message), - repackIncrChan: make(chan proto.Message), - cleanupChan: make(chan proto.Message), - writeCommitGraphChan: make(chan proto.Message), - midxRepackChan: make(chan proto.Message), - optimizeRepositoryChan: make(chan proto.Message), - pruneUnreachableObjectsChan: make(chan proto.Message), - packRefsChan: make(chan proto.Message), - } -} - -func (m *mockServer) GarbageCollect(ctx context.Context, in *gitalypb.GarbageCollectRequest) (*gitalypb.GarbageCollectResponse, error) { - go func() { - m.gcChan <- in - }() - return &gitalypb.GarbageCollectResponse{}, nil -} - -func (m *mockServer) RepackFull(ctx context.Context, in *gitalypb.RepackFullRequest) (*gitalypb.RepackFullResponse, error) { - go func() { - m.repackFullChan <- in - }() - return &gitalypb.RepackFullResponse{}, nil -} - -func (m *mockServer) RepackIncremental(ctx context.Context, in *gitalypb.RepackIncrementalRequest) (*gitalypb.RepackIncrementalResponse, error) { - go func() { - m.repackIncrChan <- in - }() - return &gitalypb.RepackIncrementalResponse{}, nil -} - -func (m *mockServer) Cleanup(ctx context.Context, in *gitalypb.CleanupRequest) (*gitalypb.CleanupResponse, error) { - go func() { - m.cleanupChan <- in - }() - return &gitalypb.CleanupResponse{}, nil -} - -func (m *mockServer) WriteCommitGraph(ctx context.Context, in *gitalypb.WriteCommitGraphRequest) (*gitalypb.WriteCommitGraphResponse, error) { - go func() { - m.writeCommitGraphChan <- in - }() - return &gitalypb.WriteCommitGraphResponse{}, nil -} - -func (m *mockServer) MidxRepack(ctx context.Context, in *gitalypb.MidxRepackRequest) (*gitalypb.MidxRepackResponse, error) { - go func() { - m.midxRepackChan <- in - }() - return &gitalypb.MidxRepackResponse{}, nil -} - -func (m *mockServer) OptimizeRepository(ctx context.Context, in *gitalypb.OptimizeRepositoryRequest) (*gitalypb.OptimizeRepositoryResponse, error) { - go func() { - m.optimizeRepositoryChan <- in - }() - return &gitalypb.OptimizeRepositoryResponse{}, nil -} - -func (m *mockServer) PruneUnreachableObjects(ctx context.Context, in *gitalypb.PruneUnreachableObjectsRequest) (*gitalypb.PruneUnreachableObjectsResponse, error) { - go func() { - m.pruneUnreachableObjectsChan <- in - }() - return &gitalypb.PruneUnreachableObjectsResponse{}, nil -} - -func (m *mockServer) PackRefs(ctx context.Context, in *gitalypb.PackRefsRequest) (*gitalypb.PackRefsResponse, error) { - go func() { - m.packRefsChan <- in - }() - return &gitalypb.PackRefsResponse{}, nil -} - -func runMockRepositoryServer(t *testing.T, cfg gconfig.Cfg) (*mockServer, string) { - mockServer := newMockRepositoryServer() - - addr := testserver.RunGitalyServer(t, cfg, nil, func(srv *grpc.Server, deps *service.Dependencies) { - gitalypb.RegisterRepositoryServiceServer(srv, mockServer) - gitalypb.RegisterRefServiceServer(srv, mockServer) - }, testserver.WithDisablePraefect()) - return mockServer, addr -} - -func waitForRequest(t *testing.T, ch chan proto.Message, expected proto.Message, timeout time.Duration) { - timer := time.NewTimer(timeout) - defer timer.Stop() - select { - case req := <-ch: - testhelper.ProtoEqual(t, expected, req) - close(ch) - case <-timer.C: - t.Fatal("timed out") - } -} - func TestConfirmReplication(t *testing.T) { ctx := testhelper.Context(t) cfg, testRepoA, testRepoAPath := testcfg.BuildWithRepo(t) srvSocketPath := testserver.RunGitalyServer(t, cfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) - testRepoB, _ := gittest.CloneRepo(t, cfg, cfg.Storages[0]) + testRepoB, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) connOpts := []grpc.DialOption{ - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cfg.Auth.Token)), } conn, err := grpc.Dial(srvSocketPath, connOpts...) @@ -1105,7 +766,7 @@ func newRepositoryClient(t *testing.T, serverSocketPath, token string) gitalypb. conn, err := grpc.Dial( serverSocketPath, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(token)), ) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/action_log.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/action_log.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/action_log.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/action_log.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/action_log_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/action_log_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/action_log_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/action_log_test.go index 00239d99f4..ea481922b9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/action_log_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/action_log_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repocleaner import ( @@ -6,7 +8,7 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestLogWarnAction_Perform(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/init_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/init_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/init_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/init_test.go index 7b5501eabe..5e446c055b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/init_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/init_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package repocleaner import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository.go index afc8fd3177..fc3441e7ed 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository.go @@ -8,10 +8,10 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // StateOwner performs check for the existence of the repositories. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository_test.go similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository_test.go index 6924d30690..441540a138 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repocleaner/repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repocleaner/repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package repocleaner import ( @@ -11,19 +13,19 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" ) func TestRunner_Run(t *testing.T) { @@ -72,25 +74,71 @@ func TestRunner_Run(t *testing.T) { RepositoriesInBatch: 2, } - // each gitaly has an extra repo-4.git repository - gittest.CloneRepo(t, g1Cfg, g1Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo1RelPath}) - gittest.CloneRepo(t, g1Cfg, g1Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo2RelPath}) - gittest.CloneRepo(t, g1Cfg, g1Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo3RelPath}) - _, repo4Path := gittest.CloneRepo(t, g1Cfg, g1Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: "repo-4.git"}) - require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) - - gittest.CloneRepo(t, g2Cfg, g2Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo1RelPath}) - gittest.CloneRepo(t, g2Cfg, g2Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo2RelPath}) - _, repo4Path = gittest.CloneRepo(t, g2Cfg, g2Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: "repo-4.git"}) - require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) - - gittest.CloneRepo(t, g3Cfg, g3Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo1RelPath}) - gittest.CloneRepo(t, g3Cfg, g3Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo2RelPath}) - gittest.CloneRepo(t, g3Cfg, g3Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo3RelPath}) - _, repo4Path = gittest.CloneRepo(t, g3Cfg, g3Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: "repo-4.git"}) - require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) ctx, cancel := context.WithCancel(testhelper.Context(t)) + // each gitaly has an extra repo-4.git repository + gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo1RelPath, + Seed: gittest.SeedGitLabTest, + }) + gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo2RelPath, + Seed: gittest.SeedGitLabTest, + }) + gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo3RelPath, + Seed: gittest.SeedGitLabTest, + }) + _, repo4Path := gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: "repo-4.git", + Seed: gittest.SeedGitLabTest, + }) + require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) + + gittest.CreateRepository(ctx, t, g2Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo1RelPath, + Seed: gittest.SeedGitLabTest, + }) + gittest.CreateRepository(ctx, t, g2Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo2RelPath, + Seed: gittest.SeedGitLabTest, + }) + _, repo4Path = gittest.CreateRepository(ctx, t, g2Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: "repo-4.git", + Seed: gittest.SeedGitLabTest, + }) + require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) + + gittest.CreateRepository(ctx, t, g3Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo1RelPath, + Seed: gittest.SeedGitLabTest, + }) + gittest.CreateRepository(ctx, t, g3Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo2RelPath, + Seed: gittest.SeedGitLabTest, + }) + gittest.CreateRepository(ctx, t, g3Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo3RelPath, + Seed: gittest.SeedGitLabTest, + }) + _, repo4Path = gittest.CreateRepository(ctx, t, g3Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: "repo-4.git", + Seed: gittest.SeedGitLabTest, + }) + + require.NoError(t, os.Chtimes(repo4Path, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) + repoStore := datastore.NewPostgresRepositoryStore(db.DB, nil) for i, set := range []struct { relativePath string @@ -205,10 +253,15 @@ func TestRunner_Run_noAvailableStorages(t *testing.T) { RepositoriesInBatch: 2, } - _, repoPath := gittest.CloneRepo(t, g1Cfg, g1Cfg.Storages[0], gittest.CloneRepoOpts{RelativePath: repo1RelPath}) - require.NoError(t, os.Chtimes(repoPath, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) ctx, cancel := context.WithCancel(testhelper.Context(t)) + _, repoPath := gittest.CreateRepository(ctx, t, g1Cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + RelativePath: repo1RelPath, + Seed: gittest.SeedGitLabTest, + }) + require.NoError(t, os.Chtimes(repoPath, time.Now().Add(-25*time.Hour), time.Now().Add(-25*time.Hour))) + repoStore := datastore.NewPostgresRepositoryStore(db.DB, nil) for i, set := range []struct { relativePath string @@ -307,11 +360,11 @@ func (as actionStub) Perform(ctx context.Context, virtualStorage, storage string return nil } -func waitReceive(t testing.TB, waitChan <-chan struct{}) { - t.Helper() +func waitReceive(tb testing.TB, waitChan <-chan struct{}) { + tb.Helper() select { case <-waitChan: case <-time.After(time.Minute): - require.FailNow(t, "waiting for too long") + require.FailNow(tb, "waiting for too long") } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists.go index bbafff8232..9246e329f1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists.go @@ -3,8 +3,8 @@ package praefect import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists_test.go similarity index 82% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists_test.go index 0f6bb148b9..3eb445e7eb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/repository_exists_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/repository_exists_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,15 +9,16 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" ) @@ -96,21 +99,22 @@ func TestRepositoryExistsHandler(t *testing.T) { nil, nil, nil, + nil, ) defer srv.Stop() go func() { srv.Serve(ln) }() - clientConn, err := grpc.DialContext(ctx, "unix://"+ln.Addr().String(), grpc.WithInsecure()) + clientConn, err := grpc.DialContext(ctx, "unix://"+ln.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer testhelper.MustClose(t, clientConn) client := gitalypb.NewRepositoryServiceClient(clientConn) _, err = client.RepositorySize(ctx, &gitalypb.RepositorySizeRequest{Repository: tc.repository}) - require.Equal(t, errServedByGitaly, err, "other RPCs should be passed through") + testhelper.RequireGrpcError(t, errServedByGitaly, err) resp, err := client.RepositoryExists(ctx, &gitalypb.RepositoryExistsRequest{Repository: tc.repository}) - require.Equal(t, tc.error, err) + testhelper.RequireGrpcError(t, tc.error, err) testhelper.ProtoEqual(t, tc.response, resp) }) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router.go index da9dbd36f6..139bd62f92 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router.go @@ -3,9 +3,32 @@ package praefect import ( "context" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "github.com/sirupsen/logrus" "google.golang.org/grpc" ) +const ( + logFieldRepositoryID = "repository_id" + logFieldReplicaPath = "replica_path" + logFieldAdditionalReplicaPath = "additional_replica_path" + logFieldPrimary = "primary" + logFieldSecondaries = "secondaries" + logFieldStorage = "storage" +) + +func addRouteLogField(ctx context.Context, fields logrus.Fields) { + ctxlogrus.AddFields(ctx, logrus.Fields{"route": fields}) +} + +func routerNodeStorages(secondaries []RouterNode) []string { + storages := make([]string, len(secondaries)) + for i := range secondaries { + storages[i] = secondaries[i].Storage + } + return storages +} + // RepositoryAccessorRoute describes how to route a repository scoped accessor call. type RepositoryAccessorRoute struct { // ReplicaPath is the disk path where the replicas are stored. @@ -14,6 +37,13 @@ type RepositoryAccessorRoute struct { Node RouterNode } +func (r RepositoryAccessorRoute) addLogFields(ctx context.Context) { + addRouteLogField(ctx, logrus.Fields{ + logFieldReplicaPath: r.ReplicaPath, + logFieldStorage: r.Node.Storage, + }) +} + // RouterNode is a subset of a node's configuration needed to perform // request routing. type RouterNode struct { @@ -23,6 +53,12 @@ type RouterNode struct { Connection *grpc.ClientConn } +func (r RouterNode) addLogFields(ctx context.Context) { + addRouteLogField(ctx, logrus.Fields{ + logFieldStorage: r.Storage, + }) +} + // StorageMutatorRoute describes how to route a storage scoped mutator call. type StorageMutatorRoute struct { // Primary is the primary node of the routing decision. @@ -31,6 +67,13 @@ type StorageMutatorRoute struct { Secondaries []RouterNode } +func (r StorageMutatorRoute) addLogFields(ctx context.Context) { + addRouteLogField(ctx, logrus.Fields{ + logFieldPrimary: r.Primary, + logFieldSecondaries: routerNodeStorages(r.Secondaries), + }) +} + // RepositoryMutatorRoute describes how to route a repository scoped mutator call. type RepositoryMutatorRoute struct { // RepositoryID is the repository's ID as Praefect identifies it. @@ -49,6 +92,17 @@ type RepositoryMutatorRoute struct { ReplicationTargets []string } +func (r RepositoryMutatorRoute) addLogFields(ctx context.Context) { + addRouteLogField(ctx, logrus.Fields{ + logFieldRepositoryID: r.RepositoryID, + logFieldReplicaPath: r.ReplicaPath, + logFieldAdditionalReplicaPath: r.AdditionalReplicaPath, + logFieldPrimary: r.Primary, + logFieldSecondaries: routerNodeStorages(r.Secondaries), + "replication_targets": r.ReplicationTargets, + }) +} + // RepositoryMaintenanceRoute describes how to route a repository scoped maintenance call. type RepositoryMaintenanceRoute struct { // RepositoryID is the repository's ID as Praefect identifies it. @@ -59,6 +113,14 @@ type RepositoryMaintenanceRoute struct { Nodes []RouterNode } +func (r RepositoryMaintenanceRoute) addLogFields(ctx context.Context) { + addRouteLogField(ctx, logrus.Fields{ + logFieldRepositoryID: r.RepositoryID, + logFieldReplicaPath: r.ReplicaPath, + "storages": routerNodeStorages(r.Nodes), + }) +} + // Router decides which nodes to direct accessor and mutator RPCs to. type Router interface { // RouteStorageAccessor returns the node which should serve the storage accessor request. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_node_manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_node_manager.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_node_manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_node_manager.go index f1f3c474ae..2f2a7a6e09 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_node_manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_node_manager.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" ) type nodeManagerRouter struct { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository.go index 6f1b4e7bd8..153bab616c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository.go @@ -5,8 +5,12 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -131,7 +135,7 @@ func (r *PerRepositoryRouter) RouteStorageMutator(ctx context.Context, virtualSt return StorageMutatorRoute{}, errors.New("RouteStorageMutator is not implemented on PerRepositoryRouter") } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r *PerRepositoryRouter) RouteRepositoryAccessor(ctx context.Context, virtualStorage, relativePath string, forcePrimary bool) (RepositoryAccessorRoute, error) { healthyNodes, err := r.healthyNodes(virtualStorage) if err != nil { @@ -204,7 +208,7 @@ func (r *PerRepositoryRouter) resolveAdditionalReplicaPath(ctx context.Context, return r.rs.GetReplicaPath(ctx, additionalRepositoryID) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (r *PerRepositoryRouter) RouteRepositoryMutator(ctx context.Context, virtualStorage, relativePath, additionalRelativePath string) (RepositoryMutatorRoute, error) { healthyNodes, err := r.healthyNodes(virtualStorage) if err != nil { @@ -307,11 +311,22 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu return RepositoryMutatorRoute{}, fmt.Errorf("reserve repository id: %w", err) } + replicaPath := relativePath + if featureflag.PraefectGeneratedReplicaPaths.IsEnabled(ctx) { + replicaPath = praefectutil.DeriveReplicaPath(id) + if housekeeping.IsRailsPoolRepository(&gitalypb.Repository{ + StorageName: virtualStorage, + RelativePath: relativePath, + }) { + replicaPath = praefectutil.DerivePoolPath(id) + } + } + replicationFactor := r.defaultReplicationFactors[virtualStorage] if replicationFactor == 1 { return RepositoryMutatorRoute{ RepositoryID: id, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: primary, }, nil } @@ -360,7 +375,7 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu return RepositoryMutatorRoute{ RepositoryID: id, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, AdditionalReplicaPath: additionalReplicaPath, Primary: primary, Secondaries: secondaries, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository_test.go index 44d8b10ce9..c4c8eb5d01 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/router_per_repository_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/router_per_repository_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,12 +9,14 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/praefectutil" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) @@ -662,6 +666,10 @@ func TestPerRepositoryRouter_RouteRepositoryMaintenance(t *testing.T) { } func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { + testhelper.NewFeatureSets(featureflag.PraefectGeneratedReplicaPaths).Run(t, testPerRepositoryRouterRouteRepositoryCreation) +} + +func testPerRepositoryRouterRouteRepositoryCreation(t *testing.T, ctx context.Context) { t.Parallel() configuredNodes := map[string][]string{ @@ -692,6 +700,11 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { additionalReplicaPath = "additional-replica-path" ) + replicaPath := relativePath + if featureflag.PraefectGeneratedReplicaPaths.IsEnabled(ctx) { + replicaPath = praefectutil.DeriveReplicaPath(1) + } + for _, tc := range []struct { desc string virtualStorage string @@ -726,7 +739,7 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, AdditionalReplicaPath: additionalReplicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, ReplicationTargets: []string{"secondary-1", "secondary-2"}, @@ -742,7 +755,7 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, Secondaries: []RouterNode{ {Storage: "secondary-1", Connection: secondary1Conn}, @@ -760,7 +773,7 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, Secondaries: []RouterNode{ {Storage: "secondary-1", Connection: secondary1Conn}, @@ -779,7 +792,7 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, }, ), @@ -795,13 +808,13 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, Secondaries: []RouterNode{{Storage: "secondary-1", Connection: secondary1Conn}}, }, RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, Secondaries: []RouterNode{{Storage: "secondary-2", Connection: secondary1Conn}}, }, @@ -818,7 +831,7 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { matchRoute: requireOneOf( RepositoryMutatorRoute{ RepositoryID: 1, - ReplicaPath: relativePath, + ReplicaPath: replicaPath, Primary: RouterNode{Storage: "primary", Connection: primaryConn}, Secondaries: []RouterNode{{Storage: "secondary-1", Connection: secondary1Conn}}, ReplicationTargets: []string{"secondary-2"}, @@ -848,14 +861,12 @@ func TestPerRepositoryRouter_RouteRepositoryCreation(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - ctx := testhelper.Context(t) - db.TruncateAll(t) rs := datastore.NewPostgresRepositoryStore(db, nil) if tc.repositoryExists { require.NoError(t, - rs.CreateRepository(ctx, 1, "virtual-storage-1", relativePath, relativePath, "primary", nil, nil, true, true), + rs.CreateRepository(ctx, 1, "virtual-storage-1", relativePath, replicaPath, "primary", nil, nil, true, true), ) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server.go similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server.go index d758102464..202eb2e6da 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server.go @@ -10,27 +10,27 @@ import ( grpcmwtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server/auth" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/fieldextractors" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/cancelhandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/metadatahandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/panichandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/sentryhandler" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/middleware" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/fieldextractors" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cancelhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/middleware" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" "google.golang.org/grpc" @@ -92,6 +92,7 @@ func NewGRPCServer( conns Connections, primaryGetter PrimaryGetter, creds credentials.TransportCredentials, + checks []service.CheckFunc, grpcOpts ...grpc.ServerOption, ) *grpc.Server { streamInterceptors := []grpc.StreamServerInterceptor{ @@ -111,6 +112,13 @@ func NewGRPCServer( panichandler.StreamPanicHandler, } + if conf.Failover.ElectionStrategy == config.ElectionStrategyPerRepository { + streamInterceptors = append( + streamInterceptors, + RenameRepositoryFeatureFlagger(conf.VirtualStorageNames(), rs, RenameRepositoryHandler(conf.VirtualStorageNames(), rs)), + ) + } + grpcOpts = append(grpcOpts, proxyRequiredOpts(director)...) grpcOpts = append(grpcOpts, []grpc.ServerOption{ grpc.StreamInterceptor(grpcmw.ChainStreamServer(streamInterceptors...)), @@ -121,8 +129,12 @@ func NewGRPCServer( auth.UnaryServerInterceptor(conf.Auth), )..., )), + // We deliberately set the server MinTime to significantly less than the client interval of 20 + // seconds to allow for network jitter. We can afford to be forgiving as the maximum number of + // concurrent clients for a Gitaly server is typically in the hundreds and this volume of + // keepalives won't add significant load. grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ - MinTime: 20 * time.Second, + MinTime: 10 * time.Second, PermitWithoutStream: true, }), grpc.KeepaliveParams(keepalive.ServerParameters{ @@ -142,7 +154,7 @@ func NewGRPCServer( warnDupeAddrs(logger, conf) srv := grpc.NewServer(grpcOpts...) - registerServices(srv, txMgr, conf, rs, assignmentStore, service.Connections(conns), primaryGetter) + registerServices(srv, txMgr, conf, rs, assignmentStore, service.Connections(conns), primaryGetter, checks) if conf.Failover.ElectionStrategy == config.ElectionStrategyPerRepository { proxy.RegisterStreamHandlers(srv, "gitaly.RepositoryService", map[string]grpc.StreamHandler{ @@ -173,9 +185,10 @@ func registerServices( assignmentStore AssignmentStore, conns service.Connections, primaryGetter info.PrimaryGetter, + checks []service.CheckFunc, ) { // ServerServiceServer is necessary for the ServerInfo RPC - gitalypb.RegisterServerServiceServer(srv, server.NewServer(conf, conns)) + gitalypb.RegisterServerServiceServer(srv, server.NewServer(conf, conns, checks)) gitalypb.RegisterPraefectInfoServiceServer(srv, info.NewServer(conf, rs, assignmentStore, conns, primaryGetter)) gitalypb.RegisterRefTransactionServer(srv, transaction.NewServer(tm)) healthpb.RegisterHealthServer(srv, health.NewServer()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory.go similarity index 85% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory.go index 847fe1f462..45424fe9d7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory.go @@ -7,12 +7,13 @@ import ( "sync" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -30,6 +31,7 @@ func NewServerFactory( registry *protoregistry.Registry, conns Connections, primaryGetter PrimaryGetter, + checks []service.CheckFunc, ) *ServerFactory { return &ServerFactory{ conf: conf, @@ -43,6 +45,7 @@ func NewServerFactory( registry: registry, conns: conns, primaryGetter: primaryGetter, + checks: checks, } } @@ -61,6 +64,7 @@ type ServerFactory struct { secure, insecure []*grpc.Server conns Connections primaryGetter PrimaryGetter + checks []service.CheckFunc } // Serve starts serving on the provided listener with newly created grpc.Server @@ -131,6 +135,7 @@ func (s *ServerFactory) createGRPC(creds credentials.TransportCredentials) *grpc s.conns, s.primaryGetter, creds, + s.checks, ) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory_test.go index fddc86ce84..7fd850e214 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_factory_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_factory_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -13,27 +15,27 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/bootstrap/starter" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - gconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap/starter" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -177,7 +179,7 @@ func TestServerFactory(t *testing.T) { } t.Run("insecure", func(t *testing.T) { - praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil) + praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil, nil) defer praefectServerFactory.Stop() listener, err := net.Listen(starter.TCP, "localhost:0") @@ -210,7 +212,7 @@ func TestServerFactory(t *testing.T) { }) t.Run("secure", func(t *testing.T) { - praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil) + praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil, nil) defer praefectServerFactory.Stop() listener, err := net.Listen(starter.TCP, "localhost:0") @@ -252,7 +254,7 @@ func TestServerFactory(t *testing.T) { t.Run("stops all listening servers", func(t *testing.T) { ctx := testhelper.Context(t) - praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil) + praefectServerFactory := NewServerFactory(conf, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil, nil) defer praefectServerFactory.Stop() // start with tcp address @@ -320,7 +322,7 @@ func TestServerFactory(t *testing.T) { t.Run("tls key path invalid", func(t *testing.T) { badTLSKeyPath := conf badTLSKeyPath.TLS.KeyPath = "invalid" - praefectServerFactory := NewServerFactory(badTLSKeyPath, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil) + praefectServerFactory := NewServerFactory(badTLSKeyPath, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil, nil) err := praefectServerFactory.Serve(nil, true) require.EqualError(t, err, "load certificate key pair: open invalid: no such file or directory") @@ -329,7 +331,7 @@ func TestServerFactory(t *testing.T) { t.Run("tls cert path invalid", func(t *testing.T) { badTLSKeyPath := conf badTLSKeyPath.TLS.CertPath = "invalid" - praefectServerFactory := NewServerFactory(badTLSKeyPath, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil) + praefectServerFactory := NewServerFactory(badTLSKeyPath, logger, coordinator.StreamDirector, nodeMgr, txMgr, queue, rs, datastore.AssignmentStore{}, registry, nil, nil, nil) err := praefectServerFactory.Serve(nil, true) require.EqualError(t, err, "load certificate key pair: open invalid: no such file or directory") diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_test.go similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_test.go index c3681a34c4..edbed63e0c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/server_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/server_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -7,8 +9,6 @@ import ( "io" "math/rand" "net" - "os" - "path/filepath" "sort" "strings" "sync" @@ -19,34 +19,34 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - gconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/grpc-proxy/proxy" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/mock" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes/tracker" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - serversvc "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes/tracker" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + serversvc "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -159,8 +159,8 @@ func TestGitalyServerInfo(t *testing.T) { require.NoError(t, err) t.Cleanup(nodeSet.Close) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withConnections: nodeSet.Connections(), + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithConnections: nodeSet.Connections(), }) t.Cleanup(cleanup) @@ -225,8 +225,8 @@ func TestGitalyServerInfo(t *testing.T) { require.NoError(t, err) t.Cleanup(nodeSet.Close) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withConnections: nodeSet.Connections(), + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithConnections: nodeSet.Connections(), }) t.Cleanup(cleanup) @@ -262,8 +262,8 @@ func TestGitalyServerInfoBadNode(t *testing.T) { require.NoError(t, err) defer nodes.Close() - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withConnections: nodes.Connections(), + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithConnections: nodes.Connections(), }) defer cleanup() @@ -294,8 +294,8 @@ func TestDiskStatistics(t *testing.T) { require.NoError(t, err) defer nodes.Close() - cc, _, cleanup := runPraefectServer(t, ctx, praefectCfg, buildOptions{ - withConnections: nodes.Connections(), + cc, _, cleanup := RunPraefectServer(t, ctx, praefectCfg, BuildOptions{ + WithConnections: nodes.Connections(), }) defer cleanup() @@ -314,12 +314,12 @@ func TestHealthCheck(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cc, _, cleanup := runPraefectServer(t, ctx, config.Config{VirtualStorages: []*config.VirtualStorage{ + cc, _, cleanup := RunPraefectServer(t, ctx, config.Config{VirtualStorages: []*config.VirtualStorage{ { Name: "praefect", Nodes: []*config.Node{{Storage: "stub", Address: "unix:///stub-address", Token: ""}}, }, - }}, buildOptions{}) + }}, BuildOptions{}) defer cleanup() client := grpc_health_v1.NewHealthClient(cc) @@ -344,7 +344,7 @@ func TestRejectBadStorage(t *testing.T) { } ctx := testhelper.Context(t) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{}) + cc, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{}) defer cleanup() req := &gitalypb.GarbageCollectRequest{ @@ -396,9 +396,9 @@ func TestWarnDuplicateAddrs(t *testing.T) { tLogger, hook := test.NewNullLogger() // instantiate a praefect server and trigger warning - _, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withLogger: logrus.NewEntry(tLogger), - withNodeMgr: nullNodeMgr{}, // to suppress node address issues + _, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithLogger: logrus.NewEntry(tLogger), + WithNodeMgr: nullNodeMgr{}, // to suppress node address issues }) defer cleanup() @@ -427,9 +427,9 @@ func TestWarnDuplicateAddrs(t *testing.T) { tLogger, hook = test.NewNullLogger() // instantiate a praefect server and trigger warning - _, _, cleanup = runPraefectServer(t, ctx, conf, buildOptions{ - withLogger: logrus.NewEntry(tLogger), - withNodeMgr: nullNodeMgr{}, // to suppress node address issues + _, _, cleanup = RunPraefectServer(t, ctx, conf, BuildOptions{ + WithLogger: logrus.NewEntry(tLogger), + WithNodeMgr: nullNodeMgr{}, // to suppress node address issues }) defer cleanup() @@ -476,9 +476,9 @@ func TestWarnDuplicateAddrs(t *testing.T) { tLogger, hook = test.NewNullLogger() // instantiate a praefect server and trigger warning - _, _, cleanup = runPraefectServer(t, ctx, conf, buildOptions{ - withLogger: logrus.NewEntry(tLogger), - withNodeMgr: nullNodeMgr{}, // to suppress node address issues + _, _, cleanup = RunPraefectServer(t, ctx, conf, BuildOptions{ + WithLogger: logrus.NewEntry(tLogger), + WithNodeMgr: nullNodeMgr{}, // to suppress node address issues }) defer cleanup() @@ -535,15 +535,15 @@ func TestRemoveRepository(t *testing.T) { nodeMgr.Start(0, time.Hour) defer nodeMgr.Stop() - cc, _, cleanup := runPraefectServer(t, ctx, praefectCfg, buildOptions{ - withQueue: queueInterceptor, - withRepoStore: datastore.MockRepositoryStore{ + cc, _, cleanup := RunPraefectServer(t, ctx, praefectCfg, BuildOptions{ + WithQueue: queueInterceptor, + WithRepoStore: datastore.MockRepositoryStore{ GetConsistentStoragesFunc: func(ctx context.Context, virtualStorage, relativePath string) (string, map[string]struct{}, error) { return relativePath, nil, nil }, }, - withNodeMgr: nodeMgr, - withTxMgr: txMgr, + WithNodeMgr: nodeMgr, + WithTxMgr: txMgr, }) defer cleanup() @@ -568,43 +568,20 @@ func TestRemoveRepository(t *testing.T) { verifyReposExistence(t, codes.NotFound) } -func pollUntilRemoved(t testing.TB, path string, deadline <-chan time.Time) { - for { - select { - case <-deadline: - require.Failf(t, "unable to detect path removal for %s", path) - default: - _, err := os.Stat(path) - if os.IsNotExist(err) { - return - } - require.NoError(t, err, "unexpected error while checking path %s", path) - } - time.Sleep(time.Millisecond) - } +func TestRenameRepository(t *testing.T) { + testhelper.NewFeatureSets(featureflag.PraefectGeneratedReplicaPaths).Run(t, testRenameRepository) } -func TestRenameRepository(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - +func testRenameRepository(t *testing.T, ctx context.Context) { gitalyStorages := []string{"gitaly-1", "gitaly-2", "gitaly-3"} - repoPaths := make([]string, len(gitalyStorages)) praefectCfg := config.Config{ VirtualStorages: []*config.VirtualStorage{{Name: "praefect"}}, Failover: config.Failover{Enabled: true, ElectionStrategy: config.ElectionStrategyPerRepository}, } - var repo *gitalypb.Repository - for i, storageName := range gitalyStorages { - const relativePath = "test-repository" - + for _, storageName := range gitalyStorages { cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages(storageName)) - gitalyCfg, repos := cfgBuilder.BuildWithRepoAt(t, relativePath) - if repo == nil { - repo = repos[0] - } - + gitalyCfg := cfgBuilder.Build(t) gitalyAddr := testserver.RunGitalyServer(t, gitalyCfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) praefectCfg.VirtualStorages[0].Nodes = append(praefectCfg.VirtualStorages[0].Nodes, &config.Node{ @@ -612,76 +589,95 @@ func TestRenameRepository(t *testing.T) { Address: gitalyAddr, Token: gitalyCfg.Auth.Token, }) - - repoPaths[i] = filepath.Join(gitalyCfg.Storages[0].Path, relativePath) } evq := datastore.NewReplicationEventQueueInterceptor(datastore.NewPostgresReplicationEventQueue(testdb.New(t))) - tx := testdb.New(t).Begin(t) - defer tx.Rollback(t) + db := testdb.New(t) - rs := datastore.NewPostgresRepositoryStore(tx, nil) - require.NoError(t, rs.CreateRepository(ctx, 1, "praefect", repo.RelativePath, repo.RelativePath, "gitaly-1", []string{"gitaly-2", "gitaly-3"}, nil, true, false)) + rs := datastore.NewPostgresRepositoryStore(db, nil) - nodeSet, err := DialNodes(ctx, praefectCfg.VirtualStorages, nil, nil, nil, nil) + txManager := transactions.NewManager(praefectCfg) + logger := testhelper.NewDiscardingLogEntry(t) + clientHandshaker := backchannel.NewClientHandshaker( + logger, + NewBackchannelServerFactory( + logger, + transaction.NewServer(txManager), + nil, + ), + ) + + nodeSet, err := DialNodes(ctx, praefectCfg.VirtualStorages, nil, nil, clientHandshaker, nil) require.NoError(t, err) defer nodeSet.Close() - testdb.SetHealthyNodes(t, ctx, tx, map[string]map[string][]string{"praefect": praefectCfg.StorageNames()}) - - cc, _, cleanup := runPraefectServer(t, ctx, praefectCfg, buildOptions{ - withQueue: evq, - withRepoStore: rs, - withRouter: NewPerRepositoryRouter( + cc, _, cleanup := RunPraefectServer(t, ctx, praefectCfg, BuildOptions{ + WithQueue: evq, + WithRepoStore: rs, + WithRouter: NewPerRepositoryRouter( nodeSet.Connections(), - nodes.NewPerRepositoryElector(tx), + nodes.NewPerRepositoryElector(db), StaticHealthChecker(praefectCfg.StorageNames()), NewLockedRandom(rand.New(rand.NewSource(0))), rs, - datastore.NewAssignmentStore(tx, praefectCfg.StorageNames()), + datastore.NewAssignmentStore(db, praefectCfg.StorageNames()), rs, nil, ), + WithTxMgr: txManager, }) - defer cleanup() + t.Cleanup(cleanup) - // virtualRepo is a virtual repository all requests to it would be applied to the underline Gitaly nodes behind it - virtualRepo := proto.Clone(repo).(*gitalypb.Repository) - virtualRepo.StorageName = praefectCfg.VirtualStorages[0].Name + virtualRepo1, _ := gittest.CreateRepository(ctx, t, gconfig.Cfg{ + Storages: []gconfig.Storage{{Name: "praefect"}}, + }, gittest.CreateRepositoryConfig{ClientConn: cc}) + + virtualRepo2, _ := gittest.CreateRepository(ctx, t, gconfig.Cfg{ + Storages: []gconfig.Storage{{Name: "praefect"}}, + }, gittest.CreateRepositoryConfig{ClientConn: cc}) + + const newRelativePath = "unused-relative-path" repoServiceClient := gitalypb.NewRepositoryServiceClient(cc) - newName, err := text.RandomHex(20) - require.NoError(t, err) + _, err = repoServiceClient.RenameRepository(ctx, &gitalypb.RenameRepositoryRequest{ + Repository: &gitalypb.Repository{ + StorageName: virtualRepo1.StorageName, + RelativePath: "not-found", + }, + RelativePath: virtualRepo2.RelativePath, + }) + testhelper.RequireGrpcError(t, helper.ErrNotFoundf(`GetRepoPath: not a git repository: "praefect/not-found"`), err) _, err = repoServiceClient.RenameRepository(ctx, &gitalypb.RenameRepositoryRequest{ - Repository: virtualRepo, - RelativePath: newName, + Repository: virtualRepo1, + RelativePath: virtualRepo2.RelativePath, + }) + + expectedErr := helper.ErrAlreadyExistsf("target repo exists already") + testhelper.RequireGrpcError(t, expectedErr, err) + + _, err = repoServiceClient.RenameRepository(ctx, &gitalypb.RenameRepositoryRequest{ + Repository: virtualRepo1, + RelativePath: newRelativePath, }) require.NoError(t, err) resp, err := repoServiceClient.RepositoryExists(ctx, &gitalypb.RepositoryExistsRequest{ - Repository: virtualRepo, + Repository: virtualRepo1, }) require.NoError(t, err) require.False(t, resp.GetExists(), "repo with old name must gone") - // as we renamed the repo we need to update RelativePath before we could check if it exists - renamedVirtualRepo := virtualRepo - renamedVirtualRepo.RelativePath = newName - - // wait until replication jobs propagate changes to other storages - // as we don't know which one will be used to check because of reads distribution - require.NoError(t, evq.Wait(time.Minute, func(i *datastore.ReplicationEventQueueInterceptor) bool { - return len(i.GetAcknowledge()) == 2 - })) - - for _, oldLocation := range repoPaths { - pollUntilRemoved(t, oldLocation, time.After(10*time.Second)) - newLocation := filepath.Join(filepath.Dir(oldLocation), newName) - require.DirExists(t, newLocation, "must be renamed on secondary from %q to %q", oldLocation, newLocation) - } + resp, err = repoServiceClient.RepositoryExists(ctx, &gitalypb.RepositoryExistsRequest{ + Repository: &gitalypb.Repository{ + StorageName: virtualRepo1.StorageName, + RelativePath: newRelativePath, + }, + }) + require.NoError(t, err) + require.True(t, resp.GetExists(), "repo with new name must exist") } type mockSmartHTTP struct { @@ -1009,7 +1005,7 @@ func TestErrorThreshold(t *testing.T) { go server.Serve(listener) defer server.Stop() - conn, err := dial("unix://"+socket, []grpc.DialOption{grpc.WithInsecure()}) + conn, err := dial("unix://"+socket, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}) require.NoError(t, err) defer testhelper.MustClose(t, conn) cli := mock.NewSimpleServiceClient(conn) @@ -1053,7 +1049,7 @@ func TestErrorThreshold(t *testing.T) { func newSmartHTTPClient(t *testing.T, serverSocketPath string) (gitalypb.SmartHTTPServiceClient, *grpc.ClientConn) { t.Helper() - conn, err := grpc.Dial(serverSocketPath, grpc.WithInsecure()) + conn, err := grpc.Dial(serverSocketPath, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { testhelper.MustClose(t, conn) }) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks.go index acf5efe6cb..41fd44de1a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks.go @@ -1,4 +1,4 @@ -package praefect +package service import ( "context" @@ -10,18 +10,21 @@ import ( "time" migrate "github.com/rubenv/sql-migrate" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/env" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/env" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/correlation" "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/protobuf/types/known/durationpb" ) // Severity is a type that indicates the severity of a check @@ -48,6 +51,17 @@ type Check struct { // CheckFunc is a function type that takes a praefect config and returns a Check type CheckFunc func(conf config.Config, w io.Writer, quiet bool) *Check +// AllChecks returns slice of all checks that can be executed for praefect. +func AllChecks() []CheckFunc { + return []CheckFunc{ + NewPraefectMigrationCheck, + NewGitalyNodeConnectivityCheck, + NewPostgresReadWriteCheck, + NewUnavailableReposCheck, + NewClockSyncCheck(helper.CheckClockSync), + } +} + // NewPraefectMigrationCheck returns a Check that checks if all praefect migrations have run func NewPraefectMigrationCheck(conf config.Config, w io.Writer, quiet bool) *Check { return &Check{ @@ -232,7 +246,11 @@ func NewClockSyncCheck(clockDriftCheck func(ntpHost string, driftThreshold time. for j := range conf.VirtualStorages[i].Nodes { node := conf.VirtualStorages[i].Nodes[j] g.Go(func() error { - opts := []grpc.DialOption{grpc.WithBlock()} + opts := []grpc.DialOption{ + grpc.WithBlock(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor(), + } if len(node.Token) > 0 { opts = append(opts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(node.Token))) } @@ -245,7 +263,7 @@ func NewClockSyncCheck(clockDriftCheck func(ntpHost string, driftThreshold time. serverServiceClient := gitalypb.NewServerServiceClient(cc) resp, err := serverServiceClient.ClockSynced(ctx, &gitalypb.ClockSyncedRequest{ - NtpHost: ntpHost, DriftThresholdMillis: driftThreshold.Milliseconds(), + NtpHost: ntpHost, DriftThreshold: durationpb.New(driftThreshold), }) if err != nil { return fmt.Errorf("gitaly node at %s: %w", node.Address, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks_test.go index 80ddb15f76..851d216927 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/checks_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/checks_test.go @@ -1,4 +1,6 @@ -package praefect +//go:build !gitaly_test_sha256 + +package service import ( "bytes" @@ -15,13 +17,13 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" @@ -535,7 +537,7 @@ func TestNewClockSyncCheck(t *testing.T) { return true, nil }, setup: func(t *testing.T) { - testhelper.ModifyEnvironment(t, "NTP_HOST", "custom") + t.Setenv("NTP_HOST", "custom") }, }, } { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/connections.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/connections.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/connections.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/connections.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/client_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/helper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/client_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/helper_test.go index e8083a74e7..4bf8104641 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/client/client_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/helper_test.go @@ -1,9 +1,9 @@ -package client +package service import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/dataloss.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/dataloss.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/dataloss.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/dataloss.go index da6d948f3e..d5ae5c6b9e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/dataloss.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/dataloss.go @@ -3,10 +3,10 @@ package info import ( "context" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) DatalossCheck(ctx context.Context, req *gitalypb.DatalossCheckRequest) (*gitalypb.DatalossCheckResponse, error) { repos, err := s.rs.GetPartiallyAvailableRepositories(ctx, req.GetVirtualStorage()) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/metadata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/metadata.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/metadata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/metadata.go index 24c7162248..f64824e457 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/metadata.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/metadata.go @@ -4,10 +4,10 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/replication_factor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/replication_factor.go similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/replication_factor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/replication_factor.go index b713ce79f0..ba4ac1b9d0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/replication_factor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/replication_factor.go @@ -5,12 +5,12 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) SetReplicationFactor(ctx context.Context, req *gitalypb.SetReplicationFactorRequest) (*gitalypb.SetReplicationFactorResponse, error) { resp, err := s.setReplicationFactor(ctx, req) if err != nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/repositories.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/repositories.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/repositories.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/repositories.go index 6b00a4f03d..1c17519b7f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/repositories.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/repositories.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "golang.org/x/sync/errgroup" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/server.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/server.go index 6babeac349..c8fffb6d14 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/server.go @@ -4,12 +4,12 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/commonerr" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // AssignmentStore is an interface for getting repository host node assignments. @@ -60,7 +60,7 @@ func NewServer( } } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (s *Server) SetAuthoritativeStorage(ctx context.Context, req *gitalypb.SetAuthoritativeStorageRequest) (*gitalypb.SetAuthoritativeStorageResponse, error) { storages := s.conf.StorageNames()[req.VirtualStorage] if storages == nil { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/verification.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/verification.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/verification.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/verification.go index 9ef07a1295..25827079e4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/info/verification.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/info/verification.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // MarkUnverified marks replicas as unverified. See the protobuf declarations for details. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/clocksynced.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/clocksynced.go new file mode 100644 index 0000000000..966028ab12 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/clocksynced.go @@ -0,0 +1,20 @@ +package server + +import ( + "context" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// ClockSynced returns whether the system clock has an acceptable time drift when compared to NTP service. +func (s *Server) ClockSynced(_ context.Context, req *gitalypb.ClockSyncedRequest) (*gitalypb.ClockSyncedResponse, error) { + if err := req.DriftThreshold.CheckValid(); err != nil { + return nil, helper.ErrInvalidArgument(err) + } + synced, err := helper.CheckClockSync(req.NtpHost, req.DriftThreshold.AsDuration()) + if err != nil { + return nil, err + } + return &gitalypb.ClockSyncedResponse{Synced: synced}, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/disk_stats.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/disk_stats.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/disk_stats.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/disk_stats.go index be65a1ae8f..704bd2e2a0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/disk_stats.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/disk_stats.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // DiskStatistics sends DiskStatisticsRequest to all of a praefect server's internal gitaly nodes and aggregates the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/info.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/info.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/info.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/info.go index 841860b524..34fcc84aca 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/server/info.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/info.go @@ -6,8 +6,8 @@ import ( "github.com/google/uuid" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness.go new file mode 100644 index 0000000000..39f1392e8d --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness.go @@ -0,0 +1,53 @@ +package server + +import ( + "context" + "io" + "sort" + + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// ReadinessCheck runs the set of the checks to make sure service is in operational state. +func (s *Server) ReadinessCheck(ctx context.Context, req *gitalypb.ReadinessCheckRequest) (*gitalypb.ReadinessCheckResponse, error) { + checkCtx := ctx + checkCancel := func() {} + timeout := req.GetTimeout().AsDuration() + if req.GetTimeout().IsValid() && timeout > 0 { + checkCtx, checkCancel = context.WithTimeout(ctx, timeout) + } + defer checkCancel() + + results := make(chan *gitalypb.ReadinessCheckResponse_Failure_Response, len(s.checks)) + for _, newCheck := range s.checks { + check := newCheck(s.conf, io.Discard, true) + go func() { + if err := check.Run(checkCtx); err != nil { + results <- &gitalypb.ReadinessCheckResponse_Failure_Response{ + Name: check.Name, + ErrorMessage: err.Error(), + } + } else { + results <- nil + } + }() + } + + var failedChecks []*gitalypb.ReadinessCheckResponse_Failure_Response + for i := 0; i < cap(results); i++ { + if result := <-results; result != nil { + failedChecks = append(failedChecks, result) + } + } + + if len(failedChecks) > 0 { + sort.Slice(failedChecks, func(i, j int) bool { return failedChecks[i].Name < failedChecks[j].Name }) + return &gitalypb.ReadinessCheckResponse{Result: &gitalypb.ReadinessCheckResponse_FailureResponse{ + FailureResponse: &gitalypb.ReadinessCheckResponse_Failure{ + FailedChecks: failedChecks, + }, + }}, nil + } + + return &gitalypb.ReadinessCheckResponse{Result: &gitalypb.ReadinessCheckResponse_OkResponse{}}, nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness_test.go new file mode 100644 index 0000000000..d53deb4139 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/readiness_test.go @@ -0,0 +1,114 @@ +package server_test + +import ( + "context" + "io" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/protobuf/types/known/durationpb" +) + +func TestServer_ReadinessCheck(t *testing.T) { + t.Parallel() + stubCheck := func(t *testing.T, triggered chan string, name string) *service.Check { + return &service.Check{ + Name: name, + Run: func(ctx context.Context) error { + _, ok := ctx.Deadline() + assert.True(t, ok, "the deadline should be set as we provide timeout") + triggered <- name + return nil + }, + } + } + + const gitalyStorageName = "praefect-internal-0" + gitalyCfg := testcfg.Build(t, testcfg.WithStorages(gitalyStorageName)) + gitalyAddr := testserver.RunGitalyServer(t, gitalyCfg, nil, setup.RegisterAll, testserver.WithDisablePraefect()) + + praefectConf := config.Config{ + SocketPath: testhelper.GetTemporaryGitalySocketFileName(t), + VirtualStorages: []*config.VirtualStorage{ + { + Name: "default", + Nodes: []*config.Node{ + { + Storage: gitalyStorageName, + Address: gitalyAddr, + }, + }, + }, + }, + } + ctx := testhelper.Context(t) + triggered := make(chan string, 2) + grpcPraefectConn, _, cleanup := praefect.RunPraefectServer(t, ctx, praefectConf, praefect.BuildOptions{ + WithChecks: []service.CheckFunc{ + func(conf config.Config, w io.Writer, quiet bool) *service.Check { + return stubCheck(t, triggered, "1") + }, + func(conf config.Config, w io.Writer, quiet bool) *service.Check { + return stubCheck(t, triggered, "2") + }, + }, + }) + t.Cleanup(cleanup) + serverClient := gitalypb.NewServerServiceClient(grpcPraefectConn) + resp, err := serverClient.ReadinessCheck(ctx, &gitalypb.ReadinessCheckRequest{Timeout: durationpb.New(time.Second)}) + require.NoError(t, err) + assert.NotNil(t, resp.GetOkResponse()) + if !assert.Nil(t, resp.GetFailureResponse()) { + for _, failure := range resp.GetFailureResponse().GetFailedChecks() { + assert.Failf(t, "failed check", "%s: %s", failure.Name, failure.ErrorMessage) + } + } + names := make([]string, 0, cap(triggered)) + for i := 0; i < cap(triggered); i++ { + name := <-triggered + names = append(names, name) + } + require.ElementsMatch(t, []string{"1", "2"}, names, "both tasks should be triggered for an execution") +} + +func TestServer_ReadinessCheck_unreachableGitaly(t *testing.T) { + t.Parallel() + praefectConf := config.Config{ + SocketPath: testhelper.GetTemporaryGitalySocketFileName(t), + VirtualStorages: []*config.VirtualStorage{ + { + Name: "default", + Nodes: []*config.Node{ + { + Storage: "praefect-internal-0", + Address: "tcp://non-existing:42", + }, + }, + }, + }, + } + ctx := testhelper.Context(t) + grpcConn, _, cleanup := praefect.RunPraefectServer(t, ctx, praefectConf, praefect.BuildOptions{}) + t.Cleanup(cleanup) + serverClient := gitalypb.NewServerServiceClient(grpcConn) + resp, err := serverClient.ReadinessCheck(ctx, &gitalypb.ReadinessCheckRequest{Timeout: durationpb.New(time.Nanosecond)}) + require.NoError(t, err) + require.Nil(t, resp.GetOkResponse()) + require.NotNil(t, resp.GetFailureResponse()) + require.Len(t, resp.GetFailureResponse().FailedChecks, 5) + require.Equal(t, "clock synchronization", resp.GetFailureResponse().FailedChecks[0].Name) + require.Equal(t, "database read/write", resp.GetFailureResponse().FailedChecks[1].Name) + require.Equal(t, "gitaly node connectivity & disk access", resp.GetFailureResponse().FailedChecks[2].Name) + require.Equal(t, "praefect migrations", resp.GetFailureResponse().FailedChecks[3].Name) + require.Equal(t, "unavailable repositories", resp.GetFailureResponse().FailedChecks[4].Name) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/server.go new file mode 100644 index 0000000000..f49621576e --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/server.go @@ -0,0 +1,26 @@ +package server + +import ( + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +// Server is a ServerService server +type Server struct { + gitalypb.UnimplementedServerServiceServer + conf config.Config + conns service.Connections + checks []service.CheckFunc +} + +// NewServer creates a new instance of a grpc ServerServiceServer +func NewServer(conf config.Config, conns service.Connections, checks []service.CheckFunc) gitalypb.ServerServiceServer { + s := &Server{ + conf: conf, + conns: conns, + checks: checks, + } + + return s +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/testhelper_test.go new file mode 100644 index 0000000000..39eb55aaf4 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/server/testhelper_test.go @@ -0,0 +1,11 @@ +package server_test + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction/server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction/server.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction/server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction/server.go index fdc838fce9..7d0af1999b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction/server.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction/server.go @@ -4,19 +4,19 @@ import ( "context" "errors" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type Server struct { gitalypb.UnimplementedRefTransactionServer txMgr *transactions.Manager } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func NewServer(txMgr *transactions.Manager) gitalypb.RefTransactionServer { return &Server{ txMgr: txMgr, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/testserver.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/testserver.go new file mode 100644 index 0000000000..f957634cfb --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/testserver.go @@ -0,0 +1,285 @@ +package praefect + +import ( + "context" + "fmt" + "net" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/client" + gitalycfgauth "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server/auth" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/grpc-proxy/proxy" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/mock" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + correlation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + healthpb "google.golang.org/grpc/health/grpc_health_v1" +) + +// BuildOptions is a set of configurations options that can be set to configure praefect service. +type BuildOptions struct { + // WithQueue sets an implementation of the replication queue to use by praefect service. + WithQueue datastore.ReplicationEventQueue + // WithTxMgr sets the transaction manager to use by praefect service. + WithTxMgr *transactions.Manager + // WithBackends sets a callback that is triggered during initialization. + WithBackends func([]*config.VirtualStorage) []testhelper.Cleanup + // WithAnnotations sets a proto-registry to use by praefect service. + WithAnnotations *protoregistry.Registry + // WithLogger sets a logger to use by praefect service. + WithLogger *logrus.Entry + // WithNodeMgr sets an implementation of the node manager to use by praefect service. + WithNodeMgr nodes.Manager + // WithRepoStore sets an implementation of the repositories store to use by praefect service. + WithRepoStore datastore.RepositoryStore + // WithAssignmentStore sets an implementation of the repositories store to use by praefect service. + WithAssignmentStore AssignmentStore + // WithConnections sets a set of connections to gitalies. + WithConnections Connections + // WithPrimaryGetter sets an implementation of the primary node getter to use by praefect service. + WithPrimaryGetter PrimaryGetter + // WithRouter sets an implementation of the request router to use by praefect service. + WithRouter Router + // WithChecks sets a list of check to run when ReadinessCheck RPC is called. + WithChecks []service.CheckFunc +} + +// WithMockBackends mocks backends with a set of passed in stubs. +func WithMockBackends(tb testing.TB, backends map[string]mock.SimpleServiceServer) func([]*config.VirtualStorage) []testhelper.Cleanup { + return func(virtualStorages []*config.VirtualStorage) []testhelper.Cleanup { + var cleanups []testhelper.Cleanup + + for _, vs := range virtualStorages { + require.Equal(tb, len(backends), len(vs.Nodes), + "mock server count doesn't match config nodes") + + for i, node := range vs.Nodes { + backend, ok := backends[node.Storage] + require.True(tb, ok, "missing backend server for node %s", node.Storage) + + backendAddr, cleanup := newMockDownstream(tb, node.Token, backend) + cleanups = append(cleanups, cleanup) + + node.Address = backendAddr + vs.Nodes[i] = node + } + } + + return cleanups + } +} + +func defaultQueue(tb testing.TB) datastore.ReplicationEventQueue { + return datastore.NewPostgresReplicationEventQueue(testdb.New(tb)) +} + +func defaultTxMgr(conf config.Config) *transactions.Manager { + return transactions.NewManager(conf) +} + +func defaultNodeMgr(tb testing.TB, conf config.Config, rs datastore.RepositoryStore) nodes.Manager { + nodeMgr, err := nodes.NewManager(testhelper.NewDiscardingLogEntry(tb), conf, nil, rs, promtest.NewMockHistogramVec(), protoregistry.GitalyProtoPreregistered, nil, nil, nil) + require.NoError(tb, err) + nodeMgr.Start(0, time.Hour) + tb.Cleanup(nodeMgr.Stop) + return nodeMgr +} + +func defaultRepoStore(conf config.Config) datastore.RepositoryStore { + return datastore.MockRepositoryStore{} +} + +func listenAvailPort(tb testing.TB) (net.Listener, int) { + listener, err := net.Listen("tcp", "localhost:0") + require.NoError(tb, err) + + return listener, listener.Addr().(*net.TCPAddr).Port +} + +func dialLocalPort(tb testing.TB, port int, backend bool) *grpc.ClientConn { + opts := []grpc.DialOption{ + grpc.WithBlock(), + grpc.WithUnaryInterceptor(correlation.UnaryClientCorrelationInterceptor()), + grpc.WithStreamInterceptor(correlation.StreamClientCorrelationInterceptor()), + } + if backend { + opts = append( + opts, + grpc.WithDefaultCallOptions(grpc.ForceCodec(proxy.NewCodec())), + ) + } + + cc, err := client.Dial( + fmt.Sprintf("tcp://localhost:%d", port), + opts, + ) + require.NoError(tb, err) + + return cc +} + +func newMockDownstream(tb testing.TB, token string, m mock.SimpleServiceServer) (string, func()) { + srv := grpc.NewServer(grpc.UnaryInterceptor(auth.UnaryServerInterceptor(gitalycfgauth.Config{Token: token}))) + mock.RegisterSimpleServiceServer(srv, m) + healthpb.RegisterHealthServer(srv, health.NewServer()) + + // client to backend service + lis, port := listenAvailPort(tb) + + errQ := make(chan error) + + go func() { + errQ <- srv.Serve(lis) + }() + + cleanup := func() { + srv.GracefulStop() + lis.Close() + + // If the server is shutdown before Serve() is called on it + // the Serve() calls will return the ErrServerStopped + if err := <-errQ; err != nil && err != grpc.ErrServerStopped { + require.NoError(tb, err) + } + } + + return fmt.Sprintf("tcp://localhost:%d", port), cleanup +} + +type noopBackoffFactory struct{} + +func (noopBackoffFactory) Create() (Backoff, BackoffReset) { + return func() time.Duration { + return 0 + }, func() {} +} + +func startProcessBacklog(ctx context.Context, replMgr ReplMgr) <-chan struct{} { + done := make(chan struct{}) + go func() { + defer close(done) + replMgr.ProcessBacklog(ctx, noopBackoffFactory{}) + }() + return done +} + +// RunPraefectServer starts praefect service based on the passed in configuration and options. +// The caller is responsible to call returned testhelper.Cleanup in order to stop the service +// and release all acquired resources. +// The function should be used only for testing purposes and not as part of the production code. +func RunPraefectServer( + tb testing.TB, + ctx context.Context, + conf config.Config, + opt BuildOptions, +) (*grpc.ClientConn, *grpc.Server, testhelper.Cleanup) { + var cleanups []testhelper.Cleanup + + if opt.WithQueue == nil { + opt.WithQueue = defaultQueue(tb) + } + if opt.WithRepoStore == nil { + opt.WithRepoStore = defaultRepoStore(conf) + } + if opt.WithTxMgr == nil { + opt.WithTxMgr = defaultTxMgr(conf) + } + if opt.WithBackends != nil { + cleanups = append(cleanups, opt.WithBackends(conf.VirtualStorages)...) + } + if opt.WithAnnotations == nil { + opt.WithAnnotations = protoregistry.GitalyProtoPreregistered + } + if opt.WithLogger == nil { + opt.WithLogger = log.Default() + } + if opt.WithNodeMgr == nil { + opt.WithNodeMgr = defaultNodeMgr(tb, conf, opt.WithRepoStore) + } + if opt.WithAssignmentStore == nil { + opt.WithAssignmentStore = NewDisabledAssignmentStore(conf.StorageNames()) + } + if opt.WithRouter == nil { + opt.WithRouter = NewNodeManagerRouter(opt.WithNodeMgr, opt.WithRepoStore) + } + if opt.WithChecks == nil { + opt.WithChecks = service.AllChecks() + } + + coordinator := NewCoordinator( + opt.WithQueue, + opt.WithRepoStore, + opt.WithRouter, + opt.WithTxMgr, + conf, + opt.WithAnnotations, + ) + + // TODO: run a replmgr for EVERY virtual storage + replmgr := NewReplMgr( + opt.WithLogger, + conf.StorageNames(), + opt.WithQueue, + opt.WithRepoStore, + opt.WithNodeMgr, + NodeSetFromNodeManager(opt.WithNodeMgr), + ) + + prf := NewGRPCServer( + conf, + opt.WithLogger, + protoregistry.GitalyProtoPreregistered, + coordinator.StreamDirector, + opt.WithTxMgr, + opt.WithRepoStore, + opt.WithAssignmentStore, + opt.WithConnections, + opt.WithPrimaryGetter, + nil, + opt.WithChecks, + ) + + listener, port := listenAvailPort(tb) + + errQ := make(chan error) + ctx, cancel := context.WithCancel(ctx) + + go func() { + errQ <- prf.Serve(listener) + close(errQ) + }() + replMgrDone := startProcessBacklog(ctx, replmgr) + + // dial client to praefect + cc := dialLocalPort(tb, port, false) + + cleanup := func() { + cc.Close() + + for _, cu := range cleanups { + cu() + } + + prf.Stop() + + cancel() + <-replMgrDone + require.NoError(tb, <-errQ) + } + + return cc, prf, cleanup +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transaction_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transaction_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transaction_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transaction_test.go index 9ac11f1bde..472f294d9f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transaction_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transaction_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -11,10 +13,10 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -27,12 +29,12 @@ type voter struct { shouldSucceed bool } -func runPraefectServerAndTxMgr(t testing.TB, ctx context.Context) (*grpc.ClientConn, *transactions.Manager, testhelper.Cleanup) { +func runPraefectServerAndTxMgr(tb testing.TB, ctx context.Context) (*grpc.ClientConn, *transactions.Manager, testhelper.Cleanup) { conf := testConfig(1) txMgr := transactions.NewManager(conf) - cc, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withTxMgr: txMgr, - withNodeMgr: nullNodeMgr{}, // to suppress node address issues + cc, _, cleanup := RunPraefectServer(tb, ctx, conf, BuildOptions{ + WithTxMgr: txMgr, + WithNodeMgr: nullNodeMgr{}, // to suppress node address issues }) return cc, txMgr, cleanup } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/manager.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/manager.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/manager.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/manager.go index e836ef749c..e05b2ed7f8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/manager.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/manager.go @@ -11,11 +11,11 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. var ErrNotFound = errors.New("transaction not found") // Manager handles reference transactions for Praefect. It is required in order @@ -63,12 +63,12 @@ func NewManager(cfg config.Config) *Manager { } } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mgr *Manager) Describe(descs chan<- *prometheus.Desc) { prometheus.DescribeByCollect(mgr, descs) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (mgr *Manager) Collect(metrics chan<- prometheus.Metric) { mgr.counterMetric.Collect(metrics) mgr.delayMetric.Collect(metrics) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction.go index 87b0ae1b03..ab21107b86 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction.go @@ -6,7 +6,7 @@ import ( "fmt" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) // VoteResult represents the outcome of a transaction for a single voter. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction_test.go index f58f9eb4f3..d7b2eee429 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/subtransaction_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/subtransaction_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package transactions import ( @@ -10,8 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) func TestSubtransaction_cancel(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction.go index 9b6a15886c..a1dd1f75ae 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction.go @@ -5,7 +5,7 @@ import ( "errors" "sync" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction_test.go index d67b341d0c..b3648ed62b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions/transaction_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions/transaction_test.go @@ -1,11 +1,13 @@ +//go:build !gitaly_test_sha256 + package transactions import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) func TestTransactionCancellationWithEmptyTransaction(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier.go index cf23ae7f48..afb48d0e85 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier.go @@ -9,9 +9,9 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // MetadataVerifier verifies the repository metadata against the actual replicas on the @@ -28,6 +28,12 @@ type MetadataVerifier struct { leaseDuration time.Duration healthChecker HealthChecker verificationInterval time.Duration + // If performDeletions is set, the worker deletes invalid metadata records. If it is not + // set, the worker marks the replica as successfully verified in the database but produces + // logs and metrics for the invalid replica. Marking the verification successful in the database + // allows the worker to proceed. The invalid replicas will be found again after the configured + // verificationInterval has passed. + performDeletions bool dequeuedJobsTotal *prometheus.CounterVec completedJobsTotal *prometheus.CounterVec @@ -47,6 +53,7 @@ func NewMetadataVerifier( conns Connections, healthChecker HealthChecker, verificationInterval time.Duration, + performDeletions bool, ) *MetadataVerifier { v := &MetadataVerifier{ log: log, @@ -56,6 +63,7 @@ func NewMetadataVerifier( leaseDuration: 30 * time.Second, healthChecker: healthChecker, verificationInterval: verificationInterval, + performDeletions: performDeletions, dequeuedJobsTotal: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "gitaly_praefect_verification_jobs_dequeued_total", @@ -298,7 +306,10 @@ func (v *MetadataVerifier) updateMetadata(ctx context.Context, results []verific } if len(logRecords) > 0 { - v.log.WithField("replicas", logRecords).Info("removing metadata records of non-existent replicas") + v.log.WithFields(logrus.Fields{ + "perform_deletions": v.performDeletions, + "replicas": logRecords, + }).Info("removing metadata records of non-existent replicas") } _, err := v.db.ExecContext(ctx, ` @@ -331,8 +342,10 @@ DELETE FROM storage_repositories USING results WHERE storage_repositories.repository_id = results.repository_id AND storage_repositories.storage = results.storage -AND successfully_verified AND NOT exists - `, repositoryIDs, storages, successfullyVerifieds, exists) +AND successfully_verified +AND NOT exists +AND $5 + `, repositoryIDs, storages, successfullyVerifieds, exists, v.performDeletions) if err != nil { return fmt.Errorf("query: %w", err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier_test.go similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier_test.go index 9c2ffda9bd..f2252e0ad5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/verifier_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/verifier_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package praefect import ( @@ -13,26 +15,26 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - gitalyconfig "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/setup" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/protoregistry" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/service/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/transactions" - "gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + gitalyconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/setup" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/nodes" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/protoregistry" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/service/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/transactions" + "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -79,14 +81,15 @@ func TestVerifier(t *testing.T) { } for _, tc := range []struct { - desc string - erroringGitalys map[string]bool - replicas replicas - healthyStorages StaticHealthChecker - batchSize int - steps []step - dequeuedJobsTotal map[string]map[string]int - completedJobsTotal map[string]map[string]map[string]int + desc string + dontPerformDeletions bool + erroringGitalys map[string]bool + replicas replicas + healthyStorages StaticHealthChecker + batchSize int + steps []step + dequeuedJobsTotal map[string]map[string]int + completedJobsTotal map[string]map[string]map[string]int }{ { desc: "all replicas exist", @@ -278,6 +281,60 @@ func TestVerifier(t *testing.T) { }, }, }, + { + desc: "metadata is not deleted if deletions are disabled", + dontPerformDeletions: true, + batchSize: 2, + replicas: replicas{ + "virtual-storage": { + "repository-1": { + gitaly1: {exists: true, lastVerified: neverVerified}, + gitaly2: {exists: false, lastVerified: neverVerified}, + gitaly3: {exists: false, lastVerified: pendingVerification}, + }, + }, + }, + steps: []step{ + { + expectedRemovals: logRecord{ + "virtual-storage": { + "repository-1": {gitaly2}, + }, + }, + expectedReplicas: map[string]map[string][]string{ + "virtual-storage": { + "repository-1": {gitaly1, gitaly2, gitaly3}, + }, + }, + }, + { + expectedRemovals: logRecord{ + "virtual-storage": { + "repository-1": {gitaly3}, + }, + }, + expectedReplicas: map[string]map[string][]string{ + "virtual-storage": { + "repository-1": {gitaly1, gitaly2, gitaly3}, + }, + }, + }, + }, + dequeuedJobsTotal: map[string]map[string]int{ + "virtual-storage": { + gitaly1: 1, + gitaly2: 1, + gitaly3: 1, + }, + }, + completedJobsTotal: map[string]map[string]map[string]int{ + "virtual-storage": { + gitaly1: {"valid": 1}, + gitaly2: {"invalid": 1}, + gitaly3: {"invalid": 1}, + }, + }, + }, { desc: "verification time is updated when repository exists", replicas: replicas{ @@ -471,8 +528,8 @@ func TestVerifier(t *testing.T) { conns := nodeSet.Connections() rs := datastore.NewPostgresRepositoryStore(db, conf.StorageNames()) - conn, _, cleanup := runPraefectServer(t, ctx, conf, buildOptions{ - withRouter: NewPerRepositoryRouter( + conn, _, cleanup := RunPraefectServer(t, ctx, conf, BuildOptions{ + WithRouter: NewPerRepositoryRouter( conns, elector, StaticHealthChecker(conf.StorageNames()), @@ -482,8 +539,8 @@ func TestVerifier(t *testing.T) { rs, conf.DefaultReplicationFactors(), ), - withRepoStore: rs, - withTxMgr: txManager, + WithRepoStore: rs, + WithTxMgr: txManager, }) t.Cleanup(cleanup) @@ -491,11 +548,13 @@ func TestVerifier(t *testing.T) { for virtualStorage, relativePaths := range tc.replicas { for relativePath, storages := range relativePaths { // Create the expected repository. This creates all of the replicas transactionally. - gittest.CreateRepository(ctx, t, + repo, _ := gittest.CreateRepository(ctx, t, gitalyconfig.Cfg{Storages: []gitalyconfig.Storage{{Name: virtualStorage}}}, gittest.CreateRepositoryConfig{ClientConn: conn, RelativePath: relativePath}, ) + replicaPath := gittest.GetReplicaPath(ctx, t, gitalyconfig.Cfg{}, repo, gittest.GetReplicaPathConfig{ClientConn: conn}) + // Now remove the replicas that were created in the transaction but the test case // expects not to exist. We remove them directly from the Gitalys so the metadata // records are left in place. @@ -536,7 +595,7 @@ func TestVerifier(t *testing.T) { &gitalypb.RemoveRepositoryRequest{ Repository: &gitalypb.Repository{ StorageName: storage, - RelativePath: relativePath, + RelativePath: replicaPath, }, }, ) @@ -581,7 +640,7 @@ func TestVerifier(t *testing.T) { healthyStorages = tc.healthyStorages } - verifier := NewMetadataVerifier(logger, db, conns, healthyStorages, 24*7*time.Hour) + verifier := NewMetadataVerifier(logger, db, conns, healthyStorages, 24*7*time.Hour, !tc.dontPerformDeletions) if tc.batchSize > 0 { verifier.batchSize = tc.batchSize } @@ -685,7 +744,7 @@ gitaly_praefect_verification_jobs_dequeued_total{storage="gitaly-2",virtual_stor // getAllReplicas gets all replicas from the database except for the locked-repository which is created // by the test suite to ensure non-blocking queries. -func getAllReplicas(ctx context.Context, t testing.TB, db glsql.Querier) map[string]map[string][]string { +func getAllReplicas(ctx context.Context, tb testing.TB, db glsql.Querier) map[string]map[string][]string { rows, err := db.QueryContext(ctx, ` SELECT repositories.virtual_storage, repositories.relative_path, storage FROM repositories @@ -693,13 +752,13 @@ func getAllReplicas(ctx context.Context, t testing.TB, db glsql.Querier) map[str WHERE repositories.relative_path != 'locked-repository' ORDER BY virtual_storage, relative_path, storage `) - require.NoError(t, err) + require.NoError(tb, err) defer rows.Close() results := map[string]map[string][]string{} for rows.Next() { var virtualStorage, relativePath, storage string - require.NoError(t, rows.Scan(&virtualStorage, &relativePath, &storage)) + require.NoError(tb, rows.Scan(&virtualStorage, &relativePath, &storage)) if results[virtualStorage] == nil { results[virtualStorage] = map[string][]string{} @@ -707,7 +766,7 @@ func getAllReplicas(ctx context.Context, t testing.TB, db glsql.Querier) map[str results[virtualStorage][relativePath] = append(results[virtualStorage][relativePath], storage) } - require.NoError(t, rows.Err()) + require.NoError(tb, rows.Err()) return results } @@ -744,7 +803,7 @@ func TestVerifier_runExpiredLeaseReleaser(t *testing.T) { defer tx.Rollback(t) logger, hook := test.NewNullLogger() - verifier := NewMetadataVerifier(logrus.NewEntry(logger), tx, nil, nil, 0) + verifier := NewMetadataVerifier(logrus.NewEntry(logger), tx, nil, nil, 0, true) // set batch size lower than the number of locked leases to ensure the batching works verifier.batchSize = 2 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/version.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/version.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/version.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/version.go index 5125cb95d3..af78afc597 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/praefect/version.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/praefect/version.go @@ -3,7 +3,7 @@ package praefect import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/version" + "gitlab.com/gitlab-org/gitaly/v15/internal/version" ) // GetVersionString returns a standard version header diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics/metrics.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics/metrics.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/prometheus/metrics/metrics.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/prometheus/metrics/metrics.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/protoutil/extension.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/protoutil/extension.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/protoutil/extension.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/protoutil/extension.go index 9e2e9f9a0f..3a5c6ebbb4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/protoutil/extension.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/protoutil/extension.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/runtime/protoimpl" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/ps.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/ps.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/ps.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/ps.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/ps_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/ps_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/ps_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/ps_test.go index e752d146c6..31f6575416 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/ps_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/ps_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package ps import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/rss.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/rss.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/rss.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/rss.go index 3bee36771a..4b7c330590 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/rss.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/rss.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux package ps diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/rss_linux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/rss_linux.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/ps/rss_linux.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/ps/rss_linux.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/file_writer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/file_writer.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/file_writer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/file_writer.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/file_writer_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/file_writer_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/file_writer_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/file_writer_test.go index c31420a7f5..83992a25a9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/file_writer_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/file_writer_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package safe_test import ( @@ -10,8 +12,8 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestFileWriter_successful(t *testing.T) { @@ -126,8 +128,8 @@ func TestFileWriter_commitBeforeClose(t *testing.T) { require.FileExists(t, dstPath) } -func dirEmpty(t testing.TB, dirPath string) bool { +func dirEmpty(tb testing.TB, dirPath string) bool { infos, err := os.ReadDir(dirPath) - require.NoError(t, err) + require.NoError(tb, err) return len(infos) == 0 } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_directory.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_directory.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_directory.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_directory.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_directory_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_directory_test.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_directory_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_directory_test.go index e9280c3dd2..d58b963889 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_directory_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_directory_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package safe_test import ( @@ -9,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestLockingDirectory(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_file_writer.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_file_writer.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_file_writer.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_file_writer.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_file_writer_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_file_writer_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_file_writer_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_file_writer_test.go index 7632a9d692..83af8c6915 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/locking_file_writer_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/locking_file_writer_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package safe_test import ( @@ -7,10 +9,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/safe" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/safe" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestLockingFileWriter_lifecycle(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/main_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/main_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/main_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/main_test.go index 7158dca836..823e2365d3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/safe/main_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/safe/main_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package safe_test import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn.go index 5af660faba..a1b68f403f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn.go @@ -5,8 +5,8 @@ import ( "io" "net" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/v14/streamio" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/streamio" ) // ServerConn and ClientConn implement an asymmetric framing protocol to diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn_test.go index 257fd42730..22d8f07d54 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/conn_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/conn_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package sidechannel import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy.go index db184ff887..6da61274f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy.go @@ -5,7 +5,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "google.golang.org/grpc" grpcMetadata "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy_test.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy_test.go index 136f469ee5..ed2f3e2a8e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/proxy_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/proxy_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package sidechannel import ( @@ -9,11 +11,11 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" healthpb "google.golang.org/grpc/health/grpc_health_v1" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/registry.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/registry.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/registry.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/registry.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/registry_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/registry_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/registry_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/registry_test.go index 032534a81c..8a286b617c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/registry_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/registry_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package sidechannel import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel.go index a8e7088d5d..2605fceb0a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/yamux" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel_test.go index 6fd4628f6a..7043e16421 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/sidechannel/sidechannel_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel/sidechannel_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package sidechannel import ( @@ -10,9 +12,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/listenmux" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/listenmux" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" healthpb "google.golang.org/grpc/health/grpc_health_v1" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/pktline.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/pktline.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/pktline.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/pktline.go index d83eb3a454..73dd0d85df 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/pktline.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/pktline.go @@ -4,7 +4,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" ) // Conn represents a bi-directional client side connection. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/std_stream.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/std_stream.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/std_stream.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/std_stream.go index cd716f8cdf..b807a01180 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/stream/std_stream.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/stream/std_stream.go @@ -4,7 +4,7 @@ import ( "fmt" "io" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // StdoutStderrResponse is an interface for RPC responses that need to stream stderr and stdout diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache.go index b09cb9aa5e..333be63c78 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache.go @@ -36,8 +36,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" ) var ( @@ -320,7 +320,11 @@ func (c *cache) newEntry(key string, create func(io.Writer) error) (_ *Stream, _ go func() { err := runCreate(e.pipe, create) - e.waiter.SetError(err) + + // We defer this until after we have removed the cache entry so that the waiter is + // only unblocked when the cache key has already been pruned from the cache. + defer e.waiter.SetError(err) + if err != nil { c.logger.WithError(err).Error("create cache entry") c.m.Lock() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache_test.go index 783c444671..4010f95fec 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cache_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cache_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package streamcache import ( @@ -15,16 +17,17 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func newCache(dir string) Cache { return New(config.StreamCacheConfig{ Enabled: true, Dir: dir, - MaxAge: config.Duration(time.Hour), + MaxAge: duration.Duration(time.Hour), }, log.Default()) } @@ -339,8 +342,6 @@ func TestCache_failedWrite(t *testing.T) { require.NoError(t, r1.Close(), "errors on the write end are not propagated via Close()") require.Error(t, r1.Wait(ctx), "error propagation happens via Wait()") - time.Sleep(10 * time.Millisecond) - const happy = "all is good" r2, created, err := c.FindOrCreate(tc.desc, writeString(happy)) require.NoError(t, err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cursor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cursor.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cursor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cursor.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cursor_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cursor_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cursor_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cursor_test.go index a0cf12b0d0..d4d66489a4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/cursor_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/cursor_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package streamcache import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore.go index 8933bc1274..5cd6f1d6ab 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore.go @@ -13,8 +13,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" ) var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore_test.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore_test.go index cf8a295062..9606ad3a69 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/filestore_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/filestore_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package streamcache import ( @@ -9,8 +11,8 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestFilestoreCreate(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe_linux.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe_linux.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe_linux.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe_linux.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe_test.go index 15309c7df9..3917c717cd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/pipe_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/pipe_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package streamcache import ( @@ -12,7 +14,7 @@ import ( "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func createPipe(t *testing.T) (*pipeReader, *pipe) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/sendfile_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/sendfile_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/sendfile_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/sendfile_test.go index 769198cf09..67f1257b1f 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/sendfile_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/sendfile_test.go @@ -1,5 +1,4 @@ -//go:build linux -// +build linux +//go:build linux && !gitaly_test_sha256 package streamcache @@ -13,7 +12,7 @@ import ( "testing/iotest" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) type wrappedFile struct{ f *os.File } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/testhelper_test.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/testhelper_test.go index 03bcc2acf5..ae86518bb9 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/streamcache/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/streamcache/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package streamcache import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/events.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/events.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/events.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/events.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/monitor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/monitor.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/monitor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/monitor.go index fcf6d3dcc5..0e88c7fc48 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/monitor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/monitor.go @@ -6,8 +6,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" - "gitlab.com/gitlab-org/gitaly/v14/internal/ps" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/ps" ) var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor.go index f695b071e9..df7e6fd0d5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor.go @@ -12,7 +12,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -93,12 +93,22 @@ func New(config Config, name string, env []string, args []string, dir string, me func (p *Process) start(logger *log.Entry) (*exec.Cmd, error) { startCounter.WithLabelValues(p.Name).Inc() + logWriter := logger.WriterLevel(log.InfoLevel) + cmd := exec.Command(p.args[0], p.args[1:]...) cmd.Env = p.env cmd.Dir = p.dir - cmd.Stdout = logger.WriterLevel(log.InfoLevel) - cmd.Stderr = logger.WriterLevel(log.InfoLevel) - return cmd, cmd.Start() + cmd.Stdout = logWriter + cmd.Stderr = logWriter + + // When starting the command fails we need to make sure to close the log pipes, or + // otherwise the Goroutines spawned by logrus may leak. + if err := cmd.Start(); err != nil { + logWriter.Close() + return nil, err + } + + return cmd, nil } func (p *Process) notifyEvent(eventType EventType, pid int) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor_test.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor_test.go index 10c1cff6de..40b54ba20d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/supervisor_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/supervisor_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package supervisor import ( @@ -13,8 +15,8 @@ import ( "github.com/kelseyhightower/envconfig" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestMain(m *testing.M) { @@ -179,7 +181,7 @@ func TestNewConfigFromEnv(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { for key, value := range tc.envvars { - testhelper.ModifyEnvironment(t, key, value) + t.Setenv(key, value) } config, err := NewConfigFromEnv() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/test-scripts/pid-server.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/test-scripts/pid-server.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/supervisor/test-scripts/pid-server.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/supervisor/test-scripts/pid-server.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean.go index 327423225b..2edfcc929e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean.go @@ -11,10 +11,10 @@ import ( "time" "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/dontpanic" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/dontpanic" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" ) const ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean_test.go index 3d3e16c13e..b21368d065 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/clean_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/clean_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package tempdir import ( @@ -10,11 +12,11 @@ import ( "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestCleanSuccess(t *testing.T) { @@ -53,10 +55,14 @@ func TestCleanSuccess(t *testing.T) { } func TestCleanTempDir(t *testing.T) { + ctx := testhelper.Context(t) cfg := testcfg.Build(t, testcfg.WithStorages("first", "second")) locator := config.NewLocator(cfg) - gittest.CloneRepo(t, cfg, cfg.Storages[0]) + gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: gittest.SeedGitLabTest, + }) logrus.SetLevel(logrus.InfoLevel) logrus.SetOutput(io.Discard) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir.go index b345388519..0e59f4cea6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir.go @@ -8,8 +8,8 @@ import ( "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // Dir is a storage-scoped temporary directory. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir_test.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir_test.go index d1a26d3c5c..86e7063270 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/tempdir_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/tempdir_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package tempdir import ( @@ -7,9 +9,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) func TestNewRepositorySuccess(t *testing.T) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/testhelper_test.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/testhelper_test.go index cdc9dc00e8..a51a8905e2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/tempdir/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/tempdir/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package tempdir import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/configure.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/configure.go similarity index 79% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/configure.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/configure.go index a3ec4ac643..ad5df7ad93 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/configure.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/configure.go @@ -5,10 +5,11 @@ import ( "fmt" "os" "path/filepath" + "runtime" "testing" log "github.com/sirupsen/logrus" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/log" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/log" ) var testDirectory string @@ -101,6 +102,32 @@ func configure() (_ func(), returnedErr error) { } } + // We need to make sure that we're gitconfig-clean: neither Git nor libgit2 should pick up + // gitconfig files from anywhere but the repository itself in case they're configured to + // ignore them. We set that configuration by default in our tests to have a known-good + // environment. + // + // In order to verify that this really works as expected we optionally intercept the user's + // HOME with a custom home directory that contains gitconfig files that cannot be parsed. So + // if these were picked up, we'd see errors and thus know that something's going on. We + // need to make this opt-in though given that some users require HOME to be set, e.g. for + // Bundler. Our CI does run with this setting enabled though. + if len(os.Getenv("GITALY_TESTING_INTERCEPT_HOME")) > 0 { + _, currentFile, _, ok := runtime.Caller(0) + if !ok { + return nil, fmt.Errorf("cannot compute intercepted home location") + } + + homeDir := filepath.Join(filepath.Dir(currentFile), "testdata", "home") + if _, err := os.Stat(homeDir); err != nil { + return nil, fmt.Errorf("statting intercepted home location: %w", err) + } + + if err := os.Setenv("HOME", homeDir); err != nil { + return nil, fmt.Errorf("setting home: %w", err) + } + } + cleanup, err := configureTestDirectory() if err != nil { return nil, fmt.Errorf("configuring test directory: %w", err) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset.go index 6e1ccce6f7..62b49a5b78 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" ) // FeatureSet is a representation of a set of features that should be disabled. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset_test.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset_test.go index fdbbba5ed9..2443c3d04b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/featureset_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/featureset_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package testhelper import ( @@ -5,7 +7,7 @@ import ( "testing" "github.com/stretchr/testify/require" - ff "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + ff "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "google.golang.org/grpc/metadata" ) @@ -171,15 +173,12 @@ func TestNewFeatureSetsWithRubyFlags(t *testing.T) { } func TestFeatureSets_Run(t *testing.T) { - // This test depends on feature flags being default-enabled in the test - // context, which requires those flags to exist in the ff.All slice. So - // let's just append them here so we do not need to use a "real" - // feature flag, as that would require constant change when we remove - // old feature flags. - defer func(old []ff.FeatureFlag) { - ff.All = old - }(ff.All) - ff.All = append(ff.All, featureFlagA, featureFlagB) + // Define two default-enabled feature flags. Note that with `NewFeatureFlag()`, we + // automatically add them to the list of defined feature flags. While this is stateful and + // would theoretically also impact other tests, we don't really need to mind that given + // that we use test-specific names for the flags here. + featureFlagA := ff.NewFeatureFlag("global_feature_flag_a", "", "", true) + featureFlagB := ff.NewFeatureFlag("global_feature_flag_b", "", "", true) var featureFlags [][2]bool NewFeatureSets(featureFlagB, featureFlagA).Run(t, func(t *testing.T, ctx context.Context) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/gitlabtest.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/gitlabtest.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/gitlabtest.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/gitlabtest.go index 76c54f2dd0..46632874bb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/gitlabtest.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/gitlabtest.go @@ -1,7 +1,7 @@ package testhelper import ( - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc.go index 536894d16c..8cf96b3262 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc.go @@ -35,27 +35,27 @@ func (mockServerTransportStream) SetTrailer(md metadata.MD) error { return nil } // It can accept not only proto.Message, but slices, maps, and structs too. // This is required as comparing messages directly with `require.Equal` doesn't // work. -func ProtoEqual(t testing.TB, expected, actual interface{}) { - t.Helper() - require.Empty(t, cmp.Diff(expected, actual, protocmp.Transform(), cmpopts.EquateErrors())) +func ProtoEqual(tb testing.TB, expected, actual interface{}) { + tb.Helper() + require.Empty(tb, cmp.Diff(expected, actual, protocmp.Transform(), cmpopts.EquateErrors())) } // RequireGrpcCode asserts that the error has the expected gRPC status code. -func RequireGrpcCode(t testing.TB, err error, expectedCode codes.Code) { - t.Helper() +func RequireGrpcCode(tb testing.TB, err error, expectedCode codes.Code) { + tb.Helper() - require.Error(t, err) + require.Error(tb, err) status, ok := status.FromError(err) - require.True(t, ok) - require.Equal(t, expectedCode, status.Code()) + require.True(tb, ok) + require.Equal(tb, expectedCode, status.Code()) } // RequireGrpcError asserts that expected and actual gRPC errors are equal. Comparing gRPC errors // directly with `require.Equal()` will not typically work correct. -func RequireGrpcError(t testing.TB, expected, actual error) { - t.Helper() +func RequireGrpcError(tb testing.TB, expected, actual error) { + tb.Helper() // .Proto() handles nil receiver - ProtoEqual(t, status.Convert(expected).Proto(), status.Convert(actual).Proto()) + ProtoEqual(tb, status.Convert(expected).Proto(), status.Convert(actual).Proto()) } // MergeOutgoingMetadata merges provided metadata-s and returns context with resulting value. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc_test.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc_test.go index fd95bc645b..ad2a70a711 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/grpc_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/grpc_test.go @@ -1,10 +1,12 @@ +//go:build !gitaly_test_sha256 + package testhelper_test import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "google.golang.org/grpc" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/leakage.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/leakage.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/leakage.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/leakage.go index 946b867d2c..ffec6c7ae0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/leakage.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/leakage.go @@ -8,8 +8,8 @@ import ( "syscall" "time" - "gitlab.com/gitlab-org/gitaly/v14/internal/command/commandcounter" - "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/command/commandcounter" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "go.uber.org/goleak" ) @@ -25,13 +25,13 @@ func mustHaveNoGoroutines() { // eventually, but the pragmatic approach is to just wait until we remove // the Ruby sidecar altogether. goleak.IgnoreTopFunction("google.golang.org/grpc.(*ccBalancerWrapper).watcher"), - goleak.IgnoreTopFunction("gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver/balancer.(*builder).monitor"), + goleak.IgnoreTopFunction("gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver/balancer.(*builder).monitor"), // labkit's logger spawns a Goroutine which cannot be closed when calling // `Initialize()`. goleak.IgnoreTopFunction("gitlab.com/gitlab-org/labkit/log.listenForSignalHangup"), // The backchannel code is somehow stock on closing its connections. I have no clue // why that is, but we should investigate. - goleak.IgnoreTopFunction("gitlab.com/gitlab-org/gitaly/v14/internal/backchannel.clientHandshake.serve.func4"), + goleak.IgnoreTopFunction("gitlab.com/gitlab-org/gitaly/v15/internal/backchannel.clientHandshake.serve.func4"), ); err != nil { panic(fmt.Errorf("goroutines running: %w", err)) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/logger.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/logger.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/logger.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/logger.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/counter.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/counter.go similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/counter.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/counter.go index 576b56643c..1d29831e8a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/counter.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/counter.go @@ -4,25 +4,25 @@ import ( "sync" ) -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. type MockCounter struct { m sync.RWMutex value float64 } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockCounter) Value() float64 { m.m.RLock() defer m.m.RUnlock() return m.value } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockCounter) Inc() { m.Add(1) } -//nolint: revive,stylecheck // This is unintentionally missing documentation. +//nolint: stylecheck // This is unintentionally missing documentation. func (m *MockCounter) Add(v float64) { m.m.Lock() defer m.m.Unlock() diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/gauge.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/gauge.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/gauge.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/gauge.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/histogram.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/histogram.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/promtest/histogram.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/promtest/histogram.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/build.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/build.go new file mode 100644 index 0000000000..3d527a0415 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/build.go @@ -0,0 +1,194 @@ +package testcfg + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "sync" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +var buildOnceByName sync.Map + +// BuildGitalyGit2Go builds the gitaly-git2go command and installs it into the binary directory. +func BuildGitalyGit2Go(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly-git2go") +} + +// BuildGitalyWrapper builds the gitaly-wrapper command and installs it into the binary directory. +func BuildGitalyWrapper(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly-wrapper") +} + +// BuildGitalyLFSSmudge builds the gitaly-lfs-smudge command and installs it into the binary +// directory. +func BuildGitalyLFSSmudge(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly-lfs-smudge") +} + +// BuildGitalyHooks builds the gitaly-hooks command and installs it into the binary directory. +func BuildGitalyHooks(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly-hooks") +} + +// BuildGitalySSH builds the gitaly-ssh command and installs it into the binary directory. +func BuildGitalySSH(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly-ssh") +} + +// BuildPraefect builds the praefect command and installs it into the binary directory. +func BuildPraefect(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "praefect") +} + +// BuildGitaly builds the gitaly binary and installs it into the binary directory. The gitaly binary +// embeds other binaries it needs to use when servicing requests. The packed binaries are not built +// prior to building this gitaly binary and thus cannot be guaranteed to be from the same build. +func BuildGitaly(tb testing.TB, cfg config.Cfg) string { + return buildGitalyCommand(tb, cfg, "gitaly") +} + +// buildGitalyCommand builds an executable and places it in the correct directory depending +// whether it is packed in the production build or not. +func buildGitalyCommand(tb testing.TB, cfg config.Cfg, executableName string) string { + return BuildBinary(tb, filepath.Dir(cfg.BinaryPath(executableName)), gitalyCommandPath(executableName)) +} + +var ( + sharedBinariesDir string + createGlobalBinaryDirectoryOnce sync.Once +) + +// BuildBinary builds a Go binary once and copies it into the target directory. The source path can +// either be a ".go" file or a directory containing Go files. Returns the path to the executable in +// the destination directory. +func BuildBinary(tb testing.TB, targetDir, sourcePath string) string { + createGlobalBinaryDirectoryOnce.Do(func() { + sharedBinariesDir = testhelper.CreateGlobalDirectory(tb, "bins") + }) + require.NotEmpty(tb, sharedBinariesDir, "creation of shared binary directory failed") + + var ( + // executableName is the name of the executable. + executableName = filepath.Base(sourcePath) + // sharedBinaryPath is the path to the binary shared between all tests. + sharedBinaryPath = filepath.Join(sharedBinariesDir, executableName) + // targetPath is the final path where the binary should be copied to. + targetPath = filepath.Join(targetDir, executableName) + ) + + buildOnceInterface, _ := buildOnceByName.LoadOrStore(executableName, &sync.Once{}) + buildOnce, ok := buildOnceInterface.(*sync.Once) + require.True(tb, ok) + + buildOnce.Do(func() { + require.NoFileExists(tb, sharedBinaryPath, "binary has already been built") + + cfg := Build(tb) + gitCommandFactory := gittest.NewCommandFactory(tb, cfg) + gitExecEnv := gitCommandFactory.GetExecutionEnvironment(context.TODO()) + + // Unfortunately, Go has started to execute Git as parts of its build process in + // order to embed VCS information into the resulting binary. In Gitaly we're doing a + // bunch of things to verify that we don't ever use Git information from outside of + // our defined parameters: we intercept Git executed via PATH, and we also override + // Git configuration locations. So executing Git without special logic simply does + // not work. + // + // While we could in theory just ask it not to do that via `-buildvcs=false`, this + // option is only understood with Go 1.18+. So we have the option between either + // using logic that is conditional on the Go version here, or alternatively we fix + // the environment to allow for the execution of Git. We opt for the latter here and + // set up a Git command factory. + gitEnvironment := make([]string, 0, len(os.Environ())) + + // We need to filter out some environments we set globally in our tests which would + // cause Git to not operate correctly. + for _, env := range os.Environ() { + if !strings.HasPrefix(env, "GIT_DIR=") { + gitEnvironment = append(gitEnvironment, env) + } + } + + // Furthermore, as we're using the Git command factory which may or may not use + // bundled Git we need to append some environment variables that make Git find its + // auxiliary helper binaries. + gitEnvironment = append(gitEnvironment, gitExecEnv.EnvironmentVariables...) + + // And last but not least we need to override PATH so that our Git binary from the + // command factory is up front. + gitEnvironment = append(gitEnvironment, fmt.Sprintf( + "PATH=%s:%s", filepath.Dir(gitExecEnv.BinaryPath), os.Getenv("PATH"), + )) + + // Go 1.18 has started to extract VCS information so that it can be embedded into + // the resulting binary and will thus execute Git in the Gitaly repository. In CI, + // the Gitaly repository is owned by a different user than the one that is executing + // tests though, which means that Git will refuse to open the repository because of + // CVE-2022-24765. + // + // Let's override this mechanism by labelling the Git repository as safe. While this + // does in theory make us vulnerable to this exploit, it is clear that any adversary + // would already have arbitrary code execution because we are executing code right + // now that would be controlled by the very same adversary. + // + // Note that we cannot pass `safe.directory` via command line arguments by design. + // Instead, we just override the system-level gitconfig to point to a temporary file + // that contains this setting. + _, currentFile, _, ok := runtime.Caller(0) + require.True(tb, ok) + gitconfigPath := filepath.Join(testhelper.TempDir(tb), "gitconfig") + require.NoError(tb, os.WriteFile(gitconfigPath, []byte( + "[safe]\ndirectory = "+filepath.Join(filepath.Dir(currentFile), "..", "..", "..")+"\n"), 0o400), + ) + gitEnvironment = append(gitEnvironment, + "GIT_CONFIG_SYSTEM="+gitconfigPath, + ) + + buildTags := []string{ + "static", "system_libgit2", "gitaly_test", + } + if os.Getenv("GITALY_TESTING_ENABLE_FIPS") != "" { + buildTags = append(buildTags, "fips") + } + + cmd := exec.Command( + "go", + "build", + "-tags", strings.Join(buildTags, ","), + "-o", sharedBinaryPath, + sourcePath, + ) + cmd.Env = gitEnvironment + + output, err := cmd.CombinedOutput() + require.NoError(tb, err, "building Go executable: %v, output: %q", err, output) + }) + + require.FileExists(tb, sharedBinaryPath, "%s does not exist", executableName) + require.NoFileExists(tb, targetPath, "%s exists already -- do you try to build it twice?", executableName) + + require.NoError(tb, os.MkdirAll(targetDir, os.ModePerm)) + + // We hard-link the file into place instead of copying it because copying used to cause + // ETXTBSY errors in CI. This is likely caused by a bug in the overlay filesystem used by + // Docker, so we just work around this by linking the file instead. It's more efficient + // anyway, the only thing is that no test must modify the binary directly. But let's count + // on that. + require.NoError(tb, os.Link(sharedBinaryPath, targetPath)) + + return targetPath +} + +func gitalyCommandPath(command string) string { + return fmt.Sprintf("gitlab.com/gitlab-org/gitaly/v15/cmd/%s", command) +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/gitaly_builder.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/gitaly_builder.go similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/gitaly_builder.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/gitaly_builder.go index 855bbe5493..e8aead0f44 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/gitaly_builder.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/gitaly_builder.go @@ -7,10 +7,10 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // UnconfiguredSocketPath is used to bypass config validation errors @@ -75,54 +75,50 @@ type GitalyCfgBuilder struct { } // Build setups required filesystem structure, creates and returns configuration of the gitaly service. -func (gc *GitalyCfgBuilder) Build(t testing.TB) config.Cfg { - t.Helper() +func (gc *GitalyCfgBuilder) Build(tb testing.TB) config.Cfg { + tb.Helper() cfg := gc.cfg if cfg.SocketPath == "" { cfg.SocketPath = UnconfiguredSocketPath } - root := testhelper.TempDir(t) + root := testhelper.TempDir(tb) if cfg.BinDir == "" { cfg.BinDir = filepath.Join(root, "bin.d") - require.NoError(t, os.Mkdir(cfg.BinDir, 0o755)) + require.NoError(tb, os.Mkdir(cfg.BinDir, 0o755)) } if cfg.Ruby.Dir == "" { _, currentFile, _, ok := runtime.Caller(0) - require.True(t, ok, "could not get caller info") + require.True(tb, ok, "could not get caller info") cfg.Ruby.Dir = filepath.Join(filepath.Dir(currentFile), "../../../ruby") } if cfg.Logging.Dir == "" { cfg.Logging.Dir = filepath.Join(root, "log.d") - require.NoError(t, os.Mkdir(cfg.Logging.Dir, 0o755)) + require.NoError(tb, os.Mkdir(cfg.Logging.Dir, 0o755)) } if cfg.GitlabShell.Dir == "" { cfg.GitlabShell.Dir = filepath.Join(root, "shell.d") - require.NoError(t, os.Mkdir(cfg.GitlabShell.Dir, 0o755)) + require.NoError(tb, os.Mkdir(cfg.GitlabShell.Dir, 0o755)) } if cfg.RuntimeDir == "" { cfg.RuntimeDir = filepath.Join(root, "runtime.d") - require.NoError(t, os.Mkdir(cfg.RuntimeDir, 0o700)) - } - - if cfg.InternalSocketDir == "" { - cfg.InternalSocketDir = filepath.Join(cfg.RuntimeDir, "sock.d") - require.NoError(t, os.Mkdir(cfg.InternalSocketDir, 0o755)) + require.NoError(tb, os.Mkdir(cfg.RuntimeDir, 0o700)) + require.NoError(tb, os.Mkdir(cfg.InternalSocketDir(), 0o755)) } if len(cfg.Storages) != 0 && len(gc.storages) != 0 { - require.FailNow(t, "invalid configuration build setup: fix storages configured") + require.FailNow(tb, "invalid configuration build setup: fix storages configured") } if len(cfg.Storages) == 0 { storagesDir := filepath.Join(root, "storages.d") - require.NoError(t, os.Mkdir(storagesDir, 0o755)) + require.NoError(tb, os.Mkdir(storagesDir, 0o755)) if len(gc.storages) == 0 { gc.storages = []string{"default"} @@ -132,7 +128,7 @@ func (gc *GitalyCfgBuilder) Build(t testing.TB) config.Cfg { cfg.Storages = make([]config.Storage, len(gc.storages)) for i, storageName := range gc.storages { storagePath := filepath.Join(storagesDir, storageName) - require.NoError(t, os.MkdirAll(storagePath, 0o755)) + require.NoError(tb, os.MkdirAll(storagePath, 0o755)) cfg.Storages[i].Name = storageName cfg.Storages[i].Path = storagePath } @@ -142,29 +138,36 @@ func (gc *GitalyCfgBuilder) Build(t testing.TB) config.Cfg { if cfg.Ruby.LinguistLanguagesPath == "" { // set a stub to prevent a long ruby process to run where it is not needed cfg.Ruby.LinguistLanguagesPath = filepath.Join(root, "linguist_languages.json") - require.NoError(t, os.WriteFile(cfg.Ruby.LinguistLanguagesPath, []byte(`{}`), 0o655)) + require.NoError(tb, os.WriteFile(cfg.Ruby.LinguistLanguagesPath, []byte(`{}`), 0o655)) } } cfg.PackObjectsCache.Enabled = gc.packObjectsCacheEnabled + // Ignore the gitconfig so that tests aren't impacted by any configuration the user happens + // to have lying around. + cfg.Git.IgnoreGitconfig = true - require.NoError(t, cfg.Validate()) + require.NoError(tb, cfg.Validate()) return cfg } // BuildWithRepoAt setups required filesystem structure, creates and returns configuration of the gitaly service, // clones test repository into each configured storage the provided relative path. -func (gc *GitalyCfgBuilder) BuildWithRepoAt(t testing.TB, relativePath string) (config.Cfg, []*gitalypb.Repository) { - t.Helper() +func (gc *GitalyCfgBuilder) BuildWithRepoAt(tb testing.TB, relativePath string) (config.Cfg, []*gitalypb.Repository) { + tb.Helper() - cfg := gc.Build(t) + ctx := testhelper.Context(tb) + cfg := gc.Build(tb) // clone the test repo to the each storage repos := make([]*gitalypb.Repository, len(cfg.Storages)) for i, gitalyStorage := range cfg.Storages { - repo, _ := gittest.CloneRepo(t, cfg, gitalyStorage, gittest.CloneRepoOpts{ - RelativePath: relativePath, + repo, _ := gittest.CreateRepository(ctx, tb, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Storage: gitalyStorage, + RelativePath: relativePath, + Seed: gittest.SeedGitLabTest, }) repos[i] = repo @@ -175,18 +178,18 @@ func (gc *GitalyCfgBuilder) BuildWithRepoAt(t testing.TB, relativePath string) ( } // Build creates a minimal configuration setup with no options and returns it with cleanup function. -func Build(t testing.TB, opts ...Option) config.Cfg { +func Build(tb testing.TB, opts ...Option) config.Cfg { cfgBuilder := NewGitalyCfgBuilder(opts...) - return cfgBuilder.Build(t) + return cfgBuilder.Build(tb) } // BuildWithRepo creates a minimal configuration setup with no options. // It also clones test repository at the storage and returns it with the full path to the repository. -func BuildWithRepo(t testing.TB, opts ...Option) (config.Cfg, *gitalypb.Repository, string) { +func BuildWithRepo(tb testing.TB, opts ...Option) (config.Cfg, *gitalypb.Repository, string) { cfgBuilder := NewGitalyCfgBuilder(opts...) - cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + cfg, repos := cfgBuilder.BuildWithRepoAt(tb, tb.Name()) repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) return cfg, repos[0], repoPath } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/metadata.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/metadata.go similarity index 75% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/metadata.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/metadata.go index df4cb274a6..2913c28695 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg/metadata.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg/metadata.go @@ -6,14 +6,14 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" "google.golang.org/grpc/metadata" ) // GitalyServersMetadataFromCfg returns a metadata pair for gitaly-servers to be used in // inter-gitaly operations. -func GitalyServersMetadataFromCfg(t testing.TB, cfg config.Cfg) metadata.MD { +func GitalyServersMetadataFromCfg(tb testing.TB, cfg config.Cfg) metadata.MD { gitalyServers := storage.GitalyServers{} storages: for _, s := range cfg.Storages { @@ -27,12 +27,12 @@ storages: continue storages } } - require.FailNow(t, "no address found on the config") + require.FailNow(tb, "no address found on the config") } gitalyServersJSON, err := json.Marshal(gitalyServers) if err != nil { - t.Fatal(err) + tb.Fatal(err) } return metadata.Pairs("gitaly-servers", base64.StdEncoding.EncodeToString(gitalyServersJSON)) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.config/git/config b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.config/git/config new file mode 100644 index 0000000000..aef95e47e8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.config/git/config @@ -0,0 +1,5 @@ +# We're trying to catch any instances of libgit2 or Git that pick up the +# gitconfig even though they're told not to. If they do pick up this file +# though, then they would fail to parse it and thus return an error, which we +# can detect quite easily. +this is broken on purpose: [ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.gitconfig b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.gitconfig new file mode 100644 index 0000000000..aef95e47e8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/.gitconfig @@ -0,0 +1,5 @@ +# We're trying to catch any instances of libgit2 or Git that pick up the +# gitconfig even though they're told not to. If they do pick up this file +# though, then they would fail to parse it and thus return an error, which we +# can detect quite easily. +this is broken on purpose: [ diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-receive-pack b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-receive-pack similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-receive-pack rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-receive-pack diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-upload-archive b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-upload-archive similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-upload-archive rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-upload-archive diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-upload-pack b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-upload-pack similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdata/home/bin/git-upload-pack rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdata/home/bin/git-upload-pack diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db.go similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db.go index f085ebc582..c909859c13 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db.go @@ -17,10 +17,10 @@ import ( migrate "github.com/rubenv/sql-migrate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/migrations" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/migrations" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) const ( @@ -36,10 +36,10 @@ type TxWrapper struct { // Rollback executes Rollback operation on the wrapped *sql.Tx if it is set. // After execution is sets Tx to nil to prevent errors on the repeated invocations (useful // for testing when Rollback is deferred). -func (txw *TxWrapper) Rollback(t testing.TB) { - t.Helper() +func (txw *TxWrapper) Rollback(tb testing.TB) { + tb.Helper() if txw.Tx != nil { - require.NoError(t, txw.Tx.Rollback()) + require.NoError(tb, txw.Tx.Rollback()) txw.Tx = nil } } @@ -47,10 +47,10 @@ func (txw *TxWrapper) Rollback(t testing.TB) { // Commit executes Commit operation on the wrapped *sql.Tx if it is set. // After execution is sets Tx to nil to prevent errors on the deferred invocations (useful // for testing when Rollback is deferred). -func (txw *TxWrapper) Commit(t testing.TB) { - t.Helper() +func (txw *TxWrapper) Commit(tb testing.TB) { + tb.Helper() if txw.Tx != nil { - require.NoError(t, txw.Tx.Commit()) + require.NoError(tb, txw.Tx.Commit()) txw.Tx = nil } } @@ -63,38 +63,38 @@ type DB struct { } // Begin starts a new transaction and returns it wrapped into TxWrapper. -func (db DB) Begin(t testing.TB) *TxWrapper { - t.Helper() +func (db DB) Begin(tb testing.TB) *TxWrapper { + tb.Helper() tx, err := db.DB.Begin() - require.NoError(t, err) + require.NoError(tb, err) return &TxWrapper{Tx: tx} } // Truncate removes all data from the list of tables and restarts identities for them. -func (db DB) Truncate(t testing.TB, tables ...string) { - t.Helper() +func (db DB) Truncate(tb testing.TB, tables ...string) { + tb.Helper() for _, table := range tables { _, err := db.DB.Exec("DELETE FROM " + table) - require.NoError(t, err, "database cleanup failed: %s", tables) + require.NoError(tb, err, "database cleanup failed: %s", tables) } _, err := db.DB.Exec("SELECT setval(relname::TEXT, 1, false) from pg_class where relkind = 'S'") - require.NoError(t, err, "database cleanup failed: %s", tables) + require.NoError(tb, err, "database cleanup failed: %s", tables) } // RequireRowsInTable verifies that `tname` table has `n` amount of rows in it. -func (db DB) RequireRowsInTable(t *testing.T, tname string, n int) { - t.Helper() +func (db DB) RequireRowsInTable(tb testing.TB, tname string, n int) { + tb.Helper() var count int - require.NoError(t, db.QueryRow("SELECT COUNT(*) FROM "+tname).Scan(&count)) - require.Equal(t, n, count, "unexpected amount of rows in table: %d instead of %d", count, n) + require.NoError(tb, db.QueryRow("SELECT COUNT(*) FROM "+tname).Scan(&count)) + require.Equal(tb, n, count, "unexpected amount of rows in table: %d instead of %d", count, n) } // TruncateAll removes all data from known set of tables. -func (db DB) TruncateAll(t testing.TB) { - db.Truncate(t, +func (db DB) TruncateAll(tb testing.TB) { + db.Truncate(tb, "replication_queue_job_lock", "replication_queue", "replication_queue_lock", @@ -109,9 +109,9 @@ func (db DB) TruncateAll(t testing.TB) { } // MustExec executes `q` with `args` and verifies there are no errors. -func (db DB) MustExec(t testing.TB, q string, args ...interface{}) { +func (db DB) MustExec(tb testing.TB, q string, args ...interface{}) { _, err := db.DB.Exec(q, args...) - require.NoError(t, err) + require.NoError(tb, err) } // Close removes schema if it was used and releases connection pool. @@ -130,22 +130,22 @@ func (db DB) Close() error { // PGPORT - required, binding port // PGUSER - optional, user - `$ whoami` would be used if not provided // Once the test is completed the database will be dropped on test cleanup execution. -func New(t testing.TB) DB { - t.Helper() +func New(tb testing.TB) DB { + tb.Helper() database := "praefect_" + strings.ReplaceAll(uuid.New().String(), "-", "") - return DB{DB: initPraefectDB(t, database), Name: database} + return DB{DB: initPraefectDB(tb, database), Name: database} } // GetConfig returns the database configuration determined by // environment variables. See NewDB() for the list of variables. -func GetConfig(t testing.TB, database string) config.DB { - env := getDatabaseEnvironment(t) +func GetConfig(tb testing.TB, database string) config.DB { + env := getDatabaseEnvironment(tb) - require.Contains(t, env, "PGHOST", "PGHOST env var expected to be provided to connect to Postgres database") - require.Contains(t, env, "PGPORT", "PGHOST env var expected to be provided to connect to Postgres database") + require.Contains(tb, env, "PGHOST", "PGHOST env var expected to be provided to connect to Postgres database") + require.Contains(tb, env, "PGPORT", "PGHOST env var expected to be provided to connect to Postgres database") portNumber, err := strconv.Atoi(env["PGPORT"]) - require.NoError(t, err, "PGPORT must be a port number of the Postgres database listens for incoming connections") + require.NoError(tb, err, "PGPORT must be a port number of the Postgres database listens for incoming connections") // connect to 'postgres' database first to re-create testing database from scratch conf := config.DB{ @@ -166,27 +166,27 @@ func GetConfig(t testing.TB, database string) config.DB { if bouncerPort, ok := env["PGPORT_PGBOUNCER"]; ok { bouncerPortNumber, err := strconv.Atoi(bouncerPort) - require.NoError(t, err, "PGPORT_PGBOUNCER must be a port number of the PgBouncer") + require.NoError(tb, err, "PGPORT_PGBOUNCER must be a port number of the PgBouncer") conf.Port = bouncerPortNumber } return conf } -func requireSQLOpen(t testing.TB, dbCfg config.DB, direct bool) *sql.DB { - t.Helper() +func requireSQLOpen(tb testing.TB, dbCfg config.DB, direct bool) *sql.DB { + tb.Helper() db, err := sql.Open("pgx", glsql.DSN(dbCfg, direct)) - require.NoErrorf(t, err, "failed to connect to %q database", dbCfg.DBName) - if !assert.NoErrorf(t, db.Ping(), "failed to communicate with %q database", dbCfg.DBName) { - require.NoErrorf(t, db.Close(), "release connection to the %q database", dbCfg.DBName) + require.NoErrorf(tb, err, "failed to connect to %q database", dbCfg.DBName) + if !assert.NoErrorf(tb, db.Ping(), "failed to communicate with %q database", dbCfg.DBName) { + require.NoErrorf(tb, db.Close(), "release connection to the %q database", dbCfg.DBName) } return db } -func requireTerminateAllConnections(t testing.TB, db *sql.DB, database string) { - t.Helper() +func requireTerminateAllConnections(tb testing.TB, db *sql.DB, database string) { + tb.Helper() _, err := db.Exec("SELECT PG_TERMINATE_BACKEND(pid) FROM PG_STAT_ACTIVITY WHERE datname = '" + database + "'") - require.NoError(t, err) + require.NoError(tb, err) // Once the pg_terminate_backend has completed, we may need to wait before the connections // are fully released. pg_terminate_backend will return true as long as the signal was @@ -194,9 +194,9 @@ func requireTerminateAllConnections(t testing.TB, db *sql.DB, database string) { // TODO: In Postgre 14, pg_terminate_backend takes an optional timeout argument that makes it a blocking // call. https://gitlab.com/gitlab-org/gitaly/-/issues/3937 tracks the refactor work to remove this // require.Eventuallyf call in favor of passing in a timeout to pg_terminate_backend - require.Eventuallyf(t, func() bool { + require.Eventuallyf(tb, func() bool { var openConnections int - require.NoError(t, db.QueryRow( + require.NoError(tb, db.QueryRow( `SELECT COUNT(*) FROM pg_stat_activity WHERE datname = $1 AND pid != pg_backend_pid()`, database). Scan(&openConnections)) @@ -204,35 +204,37 @@ func requireTerminateAllConnections(t testing.TB, db *sql.DB, database string) { }, 20*time.Second, 10*time.Millisecond, "wait for all connections to be terminated") } -func initPraefectDB(t testing.TB, database string) *sql.DB { - t.Helper() +func initPraefectDB(tb testing.TB, database string) *sql.DB { + tb.Helper() - dbCfg := GetConfig(t, "postgres") + dbCfg := GetConfig(tb, "postgres") // We require a direct connection to the Postgres instance and not through the PgBouncer // because we use transaction pool mood for it and it doesn't work well for system advisory locks. - postgresDB := requireSQLOpen(t, dbCfg, true) - defer func() { require.NoErrorf(t, postgresDB.Close(), "release connection to the %q database", dbCfg.DBName) }() + postgresDB := requireSQLOpen(tb, dbCfg, true) + defer func() { + require.NoErrorf(tb, postgresDB.Close(), "release connection to the %q database", dbCfg.DBName) + }() // Acquire exclusive advisory lock to prevent other concurrent test from doing the same. _, err := postgresDB.Exec(`SELECT pg_advisory_lock($1)`, advisoryLockIDDatabaseTemplate) - require.NoError(t, err, "not able to acquire lock for synchronisation") + require.NoError(tb, err, "not able to acquire lock for synchronisation") var advisoryUnlock func() advisoryUnlock = func() { - require.True(t, scanSingleBool(t, postgresDB, `SELECT pg_advisory_unlock($1)`, advisoryLockIDDatabaseTemplate), "release advisory lock") + require.True(tb, scanSingleBool(tb, postgresDB, `SELECT pg_advisory_unlock($1)`, advisoryLockIDDatabaseTemplate), "release advisory lock") advisoryUnlock = func() {} } defer func() { advisoryUnlock() }() - templateDBExists := databaseExist(t, postgresDB, praefectTemplateDatabase) + templateDBExists := databaseExist(tb, postgresDB, praefectTemplateDatabase) if !templateDBExists { _, err := postgresDB.Exec("CREATE DATABASE " + praefectTemplateDatabase + " WITH ENCODING 'UTF8'") - require.NoErrorf(t, err, "failed to create %q database", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to create %q database", praefectTemplateDatabase) } - templateDBConf := GetConfig(t, praefectTemplateDatabase) - templateDB := requireSQLOpen(t, templateDBConf, true) + templateDBConf := GetConfig(tb, praefectTemplateDatabase) + templateDB := requireSQLOpen(tb, templateDBConf, true) defer func() { - require.NoErrorf(t, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) + require.NoErrorf(tb, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) }() if _, err := glsql.Migrate(templateDB, false); err != nil { @@ -240,37 +242,37 @@ func initPraefectDB(t testing.TB, database string) *sql.DB { // current migration. It may be caused by other code changes done in another branch. if pErr := (*migrate.PlanError)(nil); errors.As(err, &pErr) { if strings.EqualFold(pErr.ErrorMessage, "unknown migration in database") { - require.NoErrorf(t, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) + require.NoErrorf(tb, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) _, err = postgresDB.Exec("DROP DATABASE " + praefectTemplateDatabase) - require.NoErrorf(t, err, "failed to drop %q database", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to drop %q database", praefectTemplateDatabase) _, err = postgresDB.Exec("CREATE DATABASE " + praefectTemplateDatabase + " WITH ENCODING 'UTF8'") - require.NoErrorf(t, err, "failed to create %q database", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to create %q database", praefectTemplateDatabase) - remigrateTemplateDB := requireSQLOpen(t, templateDBConf, true) + remigrateTemplateDB := requireSQLOpen(tb, templateDBConf, true) defer func() { - require.NoErrorf(t, remigrateTemplateDB.Close(), "release connection to the %q database", templateDBConf.DBName) + require.NoErrorf(tb, remigrateTemplateDB.Close(), "release connection to the %q database", templateDBConf.DBName) }() _, err = glsql.Migrate(remigrateTemplateDB, false) - require.NoErrorf(t, err, "failed to run database migration on %q", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to run database migration on %q", praefectTemplateDatabase) } else { - require.NoErrorf(t, err, "failed to run database migration on %q", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to run database migration on %q", praefectTemplateDatabase) } } else { - require.NoErrorf(t, err, "failed to run database migration on %q", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to run database migration on %q", praefectTemplateDatabase) } } // Release advisory lock as soon as possible to unblock other tests from execution. advisoryUnlock() - require.NoErrorf(t, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) + require.NoErrorf(tb, templateDB.Close(), "release connection to the %q database", templateDBConf.DBName) _, err = postgresDB.Exec(`CREATE DATABASE ` + database + ` TEMPLATE ` + praefectTemplateDatabase) - require.NoErrorf(t, err, "failed to create %q database", praefectTemplateDatabase) + require.NoErrorf(tb, err, "failed to create %q database", praefectTemplateDatabase) - t.Cleanup(func() { - if _, ok := getDatabaseEnvironment(t)["PGHOST_PGBOUNCER"]; ok { + tb.Cleanup(func() { + if _, ok := getDatabaseEnvironment(tb)["PGHOST_PGBOUNCER"]; ok { pgbouncerCfg := dbCfg // This database name will connect us to the special admin console. pgbouncerCfg.DBName = "pgbouncer" @@ -278,8 +280,8 @@ func initPraefectDB(t testing.TB, database string) *sql.DB { // We cannot use `requireSQLOpen()` because it would ping the database, // which is not supported by the PgBouncer admin console. pgbouncerDB, err := sql.Open("pgx", glsql.DSN(pgbouncerCfg, false)) - require.NoError(t, err) - defer testhelper.MustClose(t, pgbouncerDB) + require.NoError(tb, err) + defer testhelper.MustClose(tb, pgbouncerDB) // Trying to release connections like we do with the "normal" Postgres // database regularly results in flaky tests with PgBouncer given that the @@ -287,41 +289,41 @@ func initPraefectDB(t testing.TB, database string) *sql.DB { // connections by connecting to its admin console and using the KILL // command, which instructs it to kill all client and server connections. _, err = pgbouncerDB.Exec("KILL " + database) - require.NoError(t, err, "killing PgBouncer connections") + require.NoError(tb, err, "killing PgBouncer connections") } dbCfg.DBName = "postgres" - postgresDB := requireSQLOpen(t, dbCfg, true) - defer testhelper.MustClose(t, postgresDB) + postgresDB := requireSQLOpen(tb, dbCfg, true) + defer testhelper.MustClose(tb, postgresDB) // We need to force-terminate open connections as for the tasks that use PgBouncer // the actual client connected to the database is a PgBouncer and not a test that is // running. - requireTerminateAllConnections(t, postgresDB, database) + requireTerminateAllConnections(tb, postgresDB, database) _, err = postgresDB.Exec("DROP DATABASE " + database) - require.NoErrorf(t, err, "failed to drop %q database", database) + require.NoErrorf(tb, err, "failed to drop %q database", database) }) // Connect to the testing database with optional PgBouncer dbCfg.DBName = database - praefectTestDB := requireSQLOpen(t, dbCfg, false) - t.Cleanup(func() { + praefectTestDB := requireSQLOpen(tb, dbCfg, false) + tb.Cleanup(func() { if err := praefectTestDB.Close(); !errors.Is(err, net.ErrClosed) { - require.NoErrorf(t, err, "release connection to the %q database", dbCfg.DBName) + require.NoErrorf(tb, err, "release connection to the %q database", dbCfg.DBName) } }) return praefectTestDB } -func databaseExist(t testing.TB, db *sql.DB, database string) bool { - return scanSingleBool(t, db, `SELECT EXISTS(SELECT * FROM pg_database WHERE datname = $1)`, database) +func databaseExist(tb testing.TB, db *sql.DB, database string) bool { + return scanSingleBool(tb, db, `SELECT EXISTS(SELECT * FROM pg_database WHERE datname = $1)`, database) } -func scanSingleBool(t testing.TB, db *sql.DB, query string, args ...interface{}) bool { +func scanSingleBool(tb testing.TB, db *sql.DB, query string, args ...interface{}) bool { var flag bool row := db.QueryRow(query, args...) - require.NoError(t, row.Scan(&flag)) + require.NoError(tb, row.Scan(&flag)) return flag } @@ -333,7 +335,7 @@ var ( databaseEnv map[string]string ) -func getDatabaseEnvironment(t testing.TB) map[string]string { +func getDatabaseEnvironment(tb testing.TB) map[string]string { databaseEnvOnce.Do(func() { envvars := map[string]string{} @@ -374,12 +376,12 @@ func getDatabaseEnvironment(t testing.TB) map[string]string { // WaitForBlockedQuery is a helper that waits until a blocked query matching the prefix is present in the // database. This is useful for ensuring another transaction is blocking a query when testing concurrent // execution of multiple queries. -func WaitForBlockedQuery(ctx context.Context, t testing.TB, db glsql.Querier, queryPrefix string) { - t.Helper() +func WaitForBlockedQuery(ctx context.Context, tb testing.TB, db glsql.Querier, queryPrefix string) { + tb.Helper() for { var queryBlocked bool - require.NoError(t, db.QueryRowContext(ctx, ` + require.NoError(tb, db.QueryRowContext(ctx, ` SELECT EXISTS ( SELECT FROM pg_stat_activity WHERE TRIM(e'\n' FROM query) LIKE $1 @@ -404,10 +406,10 @@ func WaitForBlockedQuery(ctx context.Context, t testing.TB, db glsql.Querier, qu } // SetMigrations ensures the requested number of migrations are up and the remainder are down. -func SetMigrations(t testing.TB, db DB, cfg config.Config, up int) { +func SetMigrations(tb testing.TB, db DB, cfg config.Config, up int) { // Ensure all migrations are up first _, err := glsql.Migrate(db.DB, true) - require.NoError(t, err) + require.NoError(tb, err) migrationCt := len(migrations.All()) @@ -422,7 +424,7 @@ func SetMigrations(t testing.TB, db DB, cfg config.Config, up int) { // It would be preferable to use migrate.MigrateDown() here, but that introduces // a circular dependency between testdb and datastore. n, err := migrationSet.ExecMax(db.DB, "postgres", ms, migrate.Down, down) - require.NoError(t, err) - require.Equal(t, down, n) + require.NoError(tb, err) + require.Equal(tb, down, n) } } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db_test.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db_test.go index a3687d977b..d19f0ccdbb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/db_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/db_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package testdb import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/health.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/health.go similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/health.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/health.go index ab5cdce557..4cc1fdf57c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb/health.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb/health.go @@ -5,17 +5,15 @@ import ( "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/datastore/glsql" ) // SetHealthyNodes sets the healthy nodes in the database as determined by the passed in map. The healthyNodes map is keyed by // praefect name -> virtual storage -> storage. On each run, it clears all previous health checks from the table, so the // passed in nodes are the only ones considered healthy after the function. As the healthy nodes are determined by the time of // the last successful health check, this should be run in the same transastion as the tested query to prevent flakiness. -// -//nolint:revive -func SetHealthyNodes(t testing.TB, ctx context.Context, db glsql.Querier, healthyNodes map[string]map[string][]string) { - t.Helper() +func SetHealthyNodes(tb testing.TB, ctx context.Context, db glsql.Querier, healthyNodes map[string]map[string][]string) { + tb.Helper() var praefects, virtualStorages, storages []string for praefect, virtualStors := range healthyNodes { @@ -46,5 +44,5 @@ ON CONFLICT (praefect_name, shard_name, node_name) DO UPDATE SET virtualStorages, storages, ) - require.NoError(t, err) + require.NoError(tb, err) } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testhelper.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testhelper.go similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testhelper.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testhelper.go index f723aaf199..2599eed26d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testhelper.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testhelper.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "math/big" + mrand "math/rand" "net" "os" "os/exec" @@ -23,7 +24,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" ) const ( @@ -33,6 +34,8 @@ const ( RepositoryAuthToken = "the-secret-token" // DefaultStorageName is the default name of the Gitaly storage. DefaultStorageName = "default" + // SigningKeyPath is the default path to test commit signing. + SigningKeyPath = "testdata/signingKey.gpg" ) // IsPraefectEnabled returns whether this testing run is done with Praefect in front of the Gitaly. @@ -43,19 +46,19 @@ func IsPraefectEnabled() bool { // SkipWithPraefect skips the test if it is being executed with Praefect in front // of the Gitaly. -func SkipWithPraefect(t testing.TB, reason string) { +func SkipWithPraefect(tb testing.TB, reason string) { if IsPraefectEnabled() { - t.Skipf(reason) + tb.Skipf(reason) } } // MustReadFile returns the content of a file or fails at once. -func MustReadFile(t testing.TB, filename string) []byte { - t.Helper() +func MustReadFile(tb testing.TB, filename string) []byte { + tb.Helper() content, err := os.ReadFile(filename) if err != nil { - t.Fatal(err) + tb.Fatal(err) } return content @@ -70,11 +73,11 @@ func GitlabTestStoragePath() string { } // MustRunCommand runs a command with an optional standard input and returns the standard output, or fails. -func MustRunCommand(t testing.TB, stdin io.Reader, name string, args ...string) []byte { - t.Helper() +func MustRunCommand(tb testing.TB, stdin io.Reader, name string, args ...string) []byte { + tb.Helper() if filepath.Base(name) == "git" { - require.Fail(t, "Please use gittest.Exec or gittest.ExecStream to run git commands.") + require.Fail(tb, "Please use gittest.Exec or gittest.ExecStream to run git commands.") } cmd := exec.Command(name, args...) @@ -85,7 +88,7 @@ func MustRunCommand(t testing.TB, stdin io.Reader, name string, args ...string) output, err := cmd.Output() if err != nil { stderr := err.(*exec.ExitError).Stderr - require.NoError(t, err, "%s %s: %s", name, args, stderr) + require.NoError(tb, err, "%s %s: %s", name, args, stderr) } return output @@ -95,43 +98,43 @@ func MustRunCommand(t testing.TB, stdin io.Reader, name string, args ...string) // an error. This function is useful when closing via `defer`, as a simple // `defer require.NoError(t, closer.Close())` would cause `closer.Close()` to // be executed early already. -func MustClose(t testing.TB, closer io.Closer) { - require.NoError(t, closer.Close()) +func MustClose(tb testing.TB, closer io.Closer) { + require.NoError(tb, closer.Close()) } // CopyFile copies a file at the path src to a file at the path dst -func CopyFile(t testing.TB, src, dst string) { +func CopyFile(tb testing.TB, src, dst string) { fsrc, err := os.Open(src) - require.NoError(t, err) - defer MustClose(t, fsrc) + require.NoError(tb, err) + defer MustClose(tb, fsrc) fdst, err := os.Create(dst) - require.NoError(t, err) - defer MustClose(t, fdst) + require.NoError(tb, err) + defer MustClose(tb, fdst) _, err = io.Copy(fdst, fsrc) - require.NoError(t, err) + require.NoError(tb, err) } // GetTemporaryGitalySocketFileName will return a unique, useable socket file name -func GetTemporaryGitalySocketFileName(t testing.TB) string { - require.NotEmpty(t, testDirectory, "you must call testhelper.Configure() before GetTemporaryGitalySocketFileName()") +func GetTemporaryGitalySocketFileName(tb testing.TB) string { + require.NotEmpty(tb, testDirectory, "you must call testhelper.Configure() before GetTemporaryGitalySocketFileName()") tmpfile, err := os.CreateTemp(testDirectory, "gitaly.socket.") - require.NoError(t, err) + require.NoError(tb, err) name := tmpfile.Name() - require.NoError(t, tmpfile.Close()) - require.NoError(t, os.Remove(name)) + require.NoError(tb, tmpfile.Close()) + require.NoError(tb, os.Remove(name)) return name } // GetLocalhostListener listens on the next available TCP port and returns // the listener and the localhost address (host:port) string. -func GetLocalhostListener(t testing.TB) (net.Listener, string) { +func GetLocalhostListener(tb testing.TB) (net.Listener, string) { l, err := net.Listen("tcp", "localhost:0") - require.NoError(t, err) + require.NoError(tb, err) addr := fmt.Sprintf("localhost:%d", l.Addr().(*net.TCPAddr).Port) @@ -149,9 +152,9 @@ func ContextWithLogger(logger *log.Entry) ContextOpt { } // Context returns that gets canceled at the end of the test. -func Context(t testing.TB, opts ...ContextOpt) context.Context { +func Context(tb testing.TB, opts ...ContextOpt) context.Context { ctx, cancel := context.WithCancel(ContextWithoutCancel(opts...)) - t.Cleanup(cancel) + tb.Cleanup(cancel) return ctx } @@ -159,6 +162,10 @@ func Context(t testing.TB, opts ...ContextOpt) context.Context { func ContextWithoutCancel(opts ...ContextOpt) context.Context { ctx := context.Background() + t := time.Now() + + rnd := mrand.New(mrand.NewSource(t.Unix() + int64(t.Nanosecond()))) + // Enable use of explicit feature flags. Each feature flag which is checked must have been // explicitly injected into the context, or otherwise we panic. This is a sanity check to // verify that all feature flags we introduce are tested both with the flag enabled and @@ -168,15 +175,12 @@ func ContextWithoutCancel(opts ...ContextOpt) context.Context { // deep in the call stack, so almost every test function would have to inject it into its // context. ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.RunCommandsInCGroup, true) - // ConcurrencyQueueEnforceMax is in the codepath of every RPC call since its in the limithandler - // middleware. - ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.ConcurrencyQueueEnforceMax, true) - // ConcurrencyQueueMaxWait is in the codepath of every RPC call since it's in the limithandler - // middleware. - ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.ConcurrencyQueueMaxWait, true) - // CommandStatsMetrics is checked on every shelled out command, which may happen outside of - // RPC context. - ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.CommandStatsMetrics, true) + // Randomly inject the Git flag so that we have coverage of tests with both old and new Git + // version by pure chance. + ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.GitV2371Gl1, rnd.Int()%2 == 0) + // PraefectGeneratedReplicaPaths affects many tests as it changes the repository creation logic. + // Randomly enable the flag to exercise both paths to some extent. + ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.PraefectGeneratedReplicaPaths, rnd.Int()%2 == 0) for _, opt := range opts { ctx = opt(ctx) @@ -187,23 +191,23 @@ func ContextWithoutCancel(opts ...ContextOpt) context.Context { // CreateGlobalDirectory creates a directory in the test directory that is shared across all // between all tests. -func CreateGlobalDirectory(t testing.TB, name string) string { - require.NotEmpty(t, testDirectory, "global temporary directory does not exist") +func CreateGlobalDirectory(tb testing.TB, name string) string { + require.NotEmpty(tb, testDirectory, "global temporary directory does not exist") path := filepath.Join(testDirectory, name) - require.NoError(t, os.Mkdir(path, 0o777)) + require.NoError(tb, os.Mkdir(path, 0o777)) return path } // TempDir is a wrapper around os.MkdirTemp that provides a cleanup function. -func TempDir(t testing.TB) string { +func TempDir(tb testing.TB) string { if testDirectory == "" { panic("you must call testhelper.Configure() before TempDir()") } tmpDir, err := os.MkdirTemp(testDirectory, "") - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, os.RemoveAll(tmpDir)) + require.NoError(tb, err) + tb.Cleanup(func() { + require.NoError(tb, os.RemoveAll(tmpDir)) }) return tmpDir @@ -216,11 +220,11 @@ type Cleanup func() // WriteExecutable ensures that the parent directory exists, and writes an executable with provided // content. The executable must not exist previous to writing it. Returns the path of the written // executable. -func WriteExecutable(t testing.TB, path string, content []byte) string { +func WriteExecutable(tb testing.TB, path string, content []byte) string { dir := filepath.Dir(path) - require.NoError(t, os.MkdirAll(dir, 0o755)) - t.Cleanup(func() { - assert.NoError(t, os.RemoveAll(dir)) + require.NoError(tb, os.MkdirAll(dir, 0o755)) + tb.Cleanup(func() { + assert.NoError(tb, os.RemoveAll(dir)) }) // Open the file descriptor and write the script into it. It may happen that any other @@ -233,9 +237,9 @@ func WriteExecutable(t testing.TB, path string, content []byte) string { // We thus need to perform file locking to ensure that all writeable references to this // file have been closed before returning. executable, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o755) - require.NoError(t, err) + require.NoError(tb, err) _, err = io.Copy(executable, bytes.NewReader(content)) - require.NoError(t, err) + require.NoError(tb, err) // We now lock the file descriptor for exclusive access. If there was a forked process // holding the writeable file descriptor at this point in time, then it would refer to the @@ -245,50 +249,45 @@ func WriteExecutable(t testing.TB, path string, content []byte) string { // // No matter what, after this step any file descriptors referring to this writeable file // descriptor will be exclusively locked. - require.NoError(t, syscall.Flock(int(executable.Fd()), syscall.LOCK_EX)) + require.NoError(tb, syscall.Flock(int(executable.Fd()), syscall.LOCK_EX)) // We now close this file. The file will be automatically unlocked as soon as all // references to this file descriptor are closed. - MustClose(t, executable) + MustClose(tb, executable) // We now open the file again, but this time only for reading. executable, err = os.Open(path) - require.NoError(t, err) + require.NoError(tb, err) // And this time, we try to acquire a shared lock on this file. This call will block until // the exclusive file lock on the above writeable file descriptor has been dropped. So as // soon as we're able to acquire the lock we know that there cannot be any open writeable // file descriptors for this file anymore, and thus we won't get ETXTBSY anymore. - require.NoError(t, syscall.Flock(int(executable.Fd()), syscall.LOCK_SH)) - MustClose(t, executable) + require.NoError(tb, syscall.Flock(int(executable.Fd()), syscall.LOCK_SH)) + MustClose(tb, executable) return path } -// ModifyEnvironment will change an environment variable and revert it when the test completed. -func ModifyEnvironment(t testing.TB, key string, value string) { - t.Helper() +// Unsetenv unsets an environment variable. The variable will be restored after the test has +// finished. +func Unsetenv(tb testing.TB, key string) { + tb.Helper() - oldValue, hasOldValue := os.LookupEnv(key) - if value == "" { - require.NoError(t, os.Unsetenv(key)) - } else { - require.NoError(t, os.Setenv(key, value)) - } + // We're first using `tb.Setenv()` here due to two reasons: first, it will automitcally + // handle restoring the environment variable for us after the test has finished. And second, + // it performs a check whether we're running with `tb.Parallel()`. + tb.Setenv(key, "") - t.Cleanup(func() { - if hasOldValue { - require.NoError(t, os.Setenv(key, oldValue)) - } else { - require.NoError(t, os.Unsetenv(key)) - } - }) + // And now we can unset the environment variable given that we know we're not running in a + // parallel test and where the cleanup function has been installed. + require.NoError(tb, os.Unsetenv(key)) } // GenerateCerts creates a certificate that can be used to establish TLS protected TCP connection. // It returns paths to the file with the certificate and its private key. -func GenerateCerts(t *testing.T) (string, string) { - t.Helper() +func GenerateCerts(tb testing.TB) (string, string) { + tb.Helper() rootCA := &x509.Certificate{ SerialNumber: big.NewInt(1), @@ -302,31 +301,31 @@ func GenerateCerts(t *testing.T) (string, string) { } caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err) + require.NoError(tb, err) caCert, err := x509.CreateCertificate(rand.Reader, rootCA, rootCA, &caKey.PublicKey, caKey) - require.NoError(t, err) + require.NoError(tb, err) entityKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err) + require.NoError(tb, err) entityX509 := &x509.Certificate{ SerialNumber: big.NewInt(2), } entityCert, err := x509.CreateCertificate(rand.Reader, rootCA, entityX509, &entityKey.PublicKey, caKey) - require.NoError(t, err) + require.NoError(tb, err) certFile, err := os.CreateTemp(testDirectory, "") - require.NoError(t, err) - defer MustClose(t, certFile) - t.Cleanup(func() { - require.NoError(t, os.Remove(certFile.Name())) + require.NoError(tb, err) + defer MustClose(tb, certFile) + tb.Cleanup(func() { + require.NoError(tb, os.Remove(certFile.Name())) }) // create chained PEM file with CA and entity cert for _, cert := range [][]byte{entityCert, caCert} { - require.NoError(t, + require.NoError(tb, pem.Encode(certFile, &pem.Block{ Type: "CERTIFICATE", Bytes: cert, @@ -335,16 +334,16 @@ func GenerateCerts(t *testing.T) (string, string) { } keyFile, err := os.CreateTemp(testDirectory, "") - require.NoError(t, err) - defer MustClose(t, keyFile) - t.Cleanup(func() { - require.NoError(t, os.Remove(keyFile.Name())) + require.NoError(tb, err) + defer MustClose(tb, keyFile) + tb.Cleanup(func() { + require.NoError(tb, os.Remove(keyFile.Name())) }) entityKeyBytes, err := x509.MarshalECPrivateKey(entityKey) - require.NoError(t, err) + require.NoError(tb, err) - require.NoError(t, + require.NoError(tb, pem.Encode(keyFile, &pem.Block{ Type: "ECDSA PRIVATE KEY", Bytes: entityKeyBytes, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver.go index a48225810c..c344e59fad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver.go @@ -12,22 +12,22 @@ import ( // NewServerWithHealth creates a new gRPC server with the health server set up. // It will listen on the socket identified by `socketName`. -func NewServerWithHealth(t testing.TB, socketName string) *health.Server { +func NewServerWithHealth(tb testing.TB, socketName string) *health.Server { lis, err := net.Listen("unix", socketName) - require.NoError(t, err) + require.NoError(tb, err) - return NewHealthServerWithListener(t, lis) + return NewHealthServerWithListener(tb, lis) } // NewHealthServerWithListener creates a new gRPC server with the health server // set up. It will listen on the given listener. -func NewHealthServerWithListener(t testing.TB, listener net.Listener) *health.Server { +func NewHealthServerWithListener(tb testing.TB, listener net.Listener) *health.Server { srv := grpc.NewServer() healthSrvr := health.NewServer() healthpb.RegisterHealthServer(srv, healthSrvr) - t.Cleanup(srv.Stop) - go func() { require.NoError(t, srv.Serve(listener)) }() + tb.Cleanup(srv.Stop) + go func() { require.NoError(tb, srv.Serve(listener)) }() return healthSrvr } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/gitaly.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/gitaly.go similarity index 54% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/gitaly.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/gitaly.go index 753a579e39..db46ca0396 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/gitaly.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/gitaly.go @@ -1,6 +1,7 @@ package testserver import ( + "context" "net" "os" "testing" @@ -8,32 +9,33 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" - "gitlab.com/gitlab-org/gitaly/v14/internal/cache" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping" - "gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref" - "gitlab.com/gitlab-org/gitaly/v14/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/auth" - gitalylog "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config/log" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/hook" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/rubyserver" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/server" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/transaction" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v14/internal/middleware/limithandler" - praefectconfig "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/streamcache" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testdb" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/cache" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/housekeeping" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" + "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" + internalclient "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/client" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" + gitalylog "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/linguist" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/server" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + praefectconfig "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/streamcache" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testdb" "google.golang.org/grpc" "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" @@ -43,23 +45,25 @@ import ( // It accepts addition Registrar to register all required service instead of // calling service.RegisterAll explicitly because it creates a circular dependency // when the function is used in on of internal/gitaly/service/... packages. -func RunGitalyServer(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) string { - return StartGitalyServer(t, cfg, rubyServer, registrar, opts...).Address() +func RunGitalyServer(tb testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) string { + return StartGitalyServer(tb, cfg, rubyServer, registrar, opts...).Address() } // StartGitalyServer creates and runs gitaly (and praefect as a proxy) server. -func StartGitalyServer(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) GitalyServer { - gitalySrv, gitalyAddr, disablePraefect := runGitaly(t, cfg, rubyServer, registrar, opts...) +func StartGitalyServer(tb testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) GitalyServer { + gitalySrv, gitalyAddr, disablePraefect := runGitaly(tb, cfg, rubyServer, registrar, opts...) if !testhelper.IsPraefectEnabled() || disablePraefect { return GitalyServer{ + Server: gitalySrv, shutdown: gitalySrv.Stop, address: gitalyAddr, } } - praefectServer := runPraefectProxy(t, cfg, gitalyAddr) + praefectServer := runPraefectProxy(tb, cfg, gitalyAddr) return GitalyServer{ + Server: gitalySrv, shutdown: func() { praefectServer.Shutdown() gitalySrv.Stop() @@ -68,13 +72,13 @@ func StartGitalyServer(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Serv } } -func runPraefectProxy(t testing.TB, gitalyCfg config.Cfg, gitalyAddr string) PraefectServer { - return StartPraefect(t, praefectconfig.Config{ - SocketPath: testhelper.GetTemporaryGitalySocketFileName(t), +func runPraefectProxy(tb testing.TB, gitalyCfg config.Cfg, gitalyAddr string) PraefectServer { + return StartPraefect(tb, praefectconfig.Config{ + SocketPath: testhelper.GetTemporaryGitalySocketFileName(tb), Auth: auth.Config{ Token: gitalyCfg.Auth.Token, }, - DB: testdb.GetConfig(t, testdb.New(t).Name), + DB: testdb.GetConfig(tb, testdb.New(tb).Name), Failover: praefectconfig.Failover{ Enabled: true, ElectionStrategy: praefectconfig.ElectionStrategyLocal, @@ -82,7 +86,7 @@ func runPraefectProxy(t testing.TB, gitalyCfg config.Cfg, gitalyAddr string) Pra Replication: praefectconfig.DefaultReplicationConfig(), Logging: gitalylog.Config{ Format: "json", - Level: "panic", + Level: "info", }, VirtualStorages: []*praefectconfig.VirtualStorage{ { @@ -105,6 +109,7 @@ func runPraefectProxy(t testing.TB, gitalyCfg config.Cfg, gitalyAddr string) Pra // GitalyServer is a helper that carries additional info and // functionality about gitaly (+praefect) server. type GitalyServer struct { + Server *grpc.Server shutdown func() address string } @@ -119,71 +124,71 @@ func (gs GitalyServer) Address() string { return gs.address } -// waitHealthy waits until the server hosted at address becomes healthy. Times out after a fixed -// amount of time. -func waitHealthy(t testing.TB, addr string, authToken string) { +// waitHealthy waits until the server hosted at address becomes healthy. +func waitHealthy(ctx context.Context, tb testing.TB, addr string, authToken string) { grpcOpts := []grpc.DialOption{ grpc.WithBlock(), + internalclient.UnaryInterceptor(), + internalclient.StreamInterceptor(), } if authToken != "" { grpcOpts = append(grpcOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(authToken))) } - ctx := testhelper.Context(t) - conn, err := client.DialContext(ctx, addr, grpcOpts) - require.NoError(t, err) - defer testhelper.MustClose(t, conn) + require.NoError(tb, err) + defer testhelper.MustClose(tb, conn) healthClient := healthpb.NewHealthClient(conn) resp, err := healthClient.Check(ctx, &healthpb.HealthCheckRequest{}, grpc.WaitForReady(true)) - require.NoError(t, err) - require.Equal(t, healthpb.HealthCheckResponse_SERVING, resp.Status, "server not yet ready to serve") + require.NoError(tb, err) + require.Equal(tb, healthpb.HealthCheckResponse_SERVING, resp.Status, "server not yet ready to serve") } -func runGitaly(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) (*grpc.Server, string, bool) { - t.Helper() +func runGitaly(tb testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, registrar func(srv *grpc.Server, deps *service.Dependencies), opts ...GitalyServerOpt) (*grpc.Server, string, bool) { + tb.Helper() var gsd gitalyServerDeps for _, opt := range opts { gsd = opt(gsd) } - deps := gsd.createDependencies(t, cfg, rubyServer) - t.Cleanup(func() { gsd.conns.Close() }) + deps := gsd.createDependencies(tb, cfg, rubyServer) + tb.Cleanup(func() { gsd.conns.Close() }) serverFactory := server.NewGitalyServerFactory( cfg, - gsd.logger.WithField("test", t.Name()), + gsd.logger.WithField("test", tb.Name()), deps.GetBackchannelRegistry(), deps.GetDiskCache(), []*limithandler.LimiterMiddleware{deps.GetLimitHandler()}, ) - if cfg.InternalSocketDir != "" { + if cfg.RuntimeDir != "" { internalServer, err := serverFactory.CreateInternal() - require.NoError(t, err) - t.Cleanup(internalServer.Stop) + require.NoError(tb, err) + tb.Cleanup(internalServer.Stop) registrar(internalServer, deps) registerHealthServerIfNotRegistered(internalServer) - require.NoError(t, os.MkdirAll(cfg.InternalSocketDir, 0o700)) - t.Cleanup(func() { require.NoError(t, os.RemoveAll(cfg.InternalSocketDir)) }) + require.NoError(tb, os.MkdirAll(cfg.InternalSocketDir(), 0o700)) + tb.Cleanup(func() { require.NoError(tb, os.RemoveAll(cfg.InternalSocketDir())) }) - internalListener, err := net.Listen("unix", cfg.GitalyInternalSocketPath()) - require.NoError(t, err) + internalListener, err := net.Listen("unix", cfg.InternalSocketPath()) + require.NoError(tb, err) go func() { - assert.NoError(t, internalServer.Serve(internalListener), "failure to serve internal gRPC") + assert.NoError(tb, internalServer.Serve(internalListener), "failure to serve internal gRPC") }() - waitHealthy(t, "unix://"+internalListener.Addr().String(), cfg.Auth.Token) + ctx := testhelper.Context(tb) + waitHealthy(ctx, tb, "unix://"+internalListener.Addr().String(), cfg.Auth.Token) } externalServer, err := serverFactory.CreateExternal(cfg.TLS.CertPath != "" && cfg.TLS.KeyPath != "") - require.NoError(t, err) - t.Cleanup(externalServer.Stop) + require.NoError(tb, err) + tb.Cleanup(externalServer.Stop) registrar(externalServer, deps) registerHealthServerIfNotRegistered(externalServer) @@ -193,26 +198,27 @@ func runGitaly(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server, regi switch { case cfg.TLSListenAddr != "": listener, err = net.Listen("tcp", cfg.TLSListenAddr) - require.NoError(t, err) + require.NoError(tb, err) _, port, err := net.SplitHostPort(listener.Addr().String()) - require.NoError(t, err) + require.NoError(tb, err) addr = "tls://localhost:" + port case cfg.ListenAddr != "": listener, err = net.Listen("tcp", cfg.ListenAddr) - require.NoError(t, err) + require.NoError(tb, err) addr = "tcp://" + listener.Addr().String() default: - serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(t) + serverSocketPath := testhelper.GetTemporaryGitalySocketFileName(tb) listener, err = net.Listen("unix", serverSocketPath) - require.NoError(t, err) + require.NoError(tb, err) addr = "unix://" + serverSocketPath } go func() { - assert.NoError(t, externalServer.Serve(listener), "failure to serve external gRPC") + assert.NoError(tb, externalServer.Serve(listener), "failure to serve external gRPC") }() - waitHealthy(t, addr, cfg.Auth.Token) + ctx := testhelper.Context(tb) + waitHealthy(ctx, tb, addr, cfg.Auth.Token) return externalServer, addr, gsd.disablePraefect } @@ -226,32 +232,33 @@ func registerHealthServerIfNotRegistered(srv *grpc.Server) { } type gitalyServerDeps struct { - disablePraefect bool - logger *logrus.Logger - conns *client.Pool - locator storage.Locator - txMgr transaction.Manager - hookMgr hook.Manager - gitlabClient gitlab.Client - gitCmdFactory git.CommandFactory - linguist *linguist.Instance - backchannelReg *backchannel.Registry - catfileCache catfile.Cache - diskCache cache.Cache - packObjectsCache streamcache.Cache - limitHandler *limithandler.LimiterMiddleware - git2goExecutor *git2go.Executor - updaterWithHooks *updateref.UpdaterWithHooks - housekeepingManager housekeeping.Manager + disablePraefect bool + logger *logrus.Logger + conns *client.Pool + locator storage.Locator + txMgr transaction.Manager + hookMgr hook.Manager + gitlabClient gitlab.Client + gitCmdFactory git.CommandFactory + linguist *linguist.Instance + backchannelReg *backchannel.Registry + catfileCache catfile.Cache + diskCache cache.Cache + packObjectsCache streamcache.Cache + packObjectsConcurrencyTracker *hook.ConcurrencyTracker + limitHandler *limithandler.LimiterMiddleware + git2goExecutor *git2go.Executor + updaterWithHooks *updateref.UpdaterWithHooks + housekeepingManager housekeeping.Manager } -func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server) *service.Dependencies { +func (gsd *gitalyServerDeps) createDependencies(tb testing.TB, cfg config.Cfg, rubyServer *rubyserver.Server) *service.Dependencies { if gsd.logger == nil { - gsd.logger = testhelper.NewDiscardingLogger(t) + gsd.logger = testhelper.NewDiscardingLogger(tb) } if gsd.conns == nil { - gsd.conns = client.NewPool() + gsd.conns = client.NewPool(internalclient.UnaryInterceptor(), internalclient.StreamInterceptor()) } if gsd.locator == nil { @@ -260,7 +267,7 @@ func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, ru if gsd.gitlabClient == nil { gsd.gitlabClient = gitlab.NewMockClient( - t, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, + tb, gitlab.MockAllowed, gitlab.MockPreReceive, gitlab.MockPostReceive, ) } @@ -273,7 +280,7 @@ func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, ru } if gsd.gitCmdFactory == nil { - gsd.gitCmdFactory = gittest.NewCommandFactory(t, cfg) + gsd.gitCmdFactory = gittest.NewCommandFactory(tb, cfg) } if gsd.hookMgr == nil { @@ -283,13 +290,13 @@ func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, ru if gsd.linguist == nil { var err error gsd.linguist, err = linguist.New(cfg, gsd.gitCmdFactory) - require.NoError(t, err) + require.NoError(tb, err) } if gsd.catfileCache == nil { cache := catfile.NewCache(cfg) gsd.catfileCache = cache - t.Cleanup(cache.Stop) + tb.Cleanup(cache.Stop) } if gsd.diskCache == nil { @@ -298,7 +305,11 @@ func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, ru if gsd.packObjectsCache == nil { gsd.packObjectsCache = streamcache.New(cfg.PackObjectsCache, gsd.logger) - t.Cleanup(gsd.packObjectsCache.Stop) + tb.Cleanup(gsd.packObjectsCache.Stop) + } + + if gsd.packObjectsConcurrencyTracker == nil { + gsd.packObjectsConcurrencyTracker = hook.NewConcurrencyTracker() } if gsd.limitHandler == nil { @@ -318,23 +329,24 @@ func (gsd *gitalyServerDeps) createDependencies(t testing.TB, cfg config.Cfg, ru } return &service.Dependencies{ - Cfg: cfg, - RubyServer: rubyServer, - ClientPool: gsd.conns, - StorageLocator: gsd.locator, - TransactionManager: gsd.txMgr, - GitalyHookManager: gsd.hookMgr, - GitCmdFactory: gsd.gitCmdFactory, - Linguist: gsd.linguist, - BackchannelRegistry: gsd.backchannelReg, - GitlabClient: gsd.gitlabClient, - CatfileCache: gsd.catfileCache, - DiskCache: gsd.diskCache, - PackObjectsCache: gsd.packObjectsCache, - LimitHandler: gsd.limitHandler, - Git2goExecutor: gsd.git2goExecutor, - UpdaterWithHooks: gsd.updaterWithHooks, - HousekeepingManager: gsd.housekeepingManager, + Cfg: cfg, + RubyServer: rubyServer, + ClientPool: gsd.conns, + StorageLocator: gsd.locator, + TransactionManager: gsd.txMgr, + GitalyHookManager: gsd.hookMgr, + GitCmdFactory: gsd.gitCmdFactory, + Linguist: gsd.linguist, + BackchannelRegistry: gsd.backchannelReg, + GitlabClient: gsd.gitlabClient, + CatfileCache: gsd.catfileCache, + DiskCache: gsd.diskCache, + PackObjectsCache: gsd.packObjectsCache, + PackObjectsConcurrencyTracker: gsd.packObjectsConcurrencyTracker, + LimitHandler: gsd.limitHandler, + Git2goExecutor: gsd.git2goExecutor, + UpdaterWithHooks: gsd.updaterWithHooks, + HousekeepingManager: gsd.housekeepingManager, } } @@ -413,3 +425,12 @@ func WithDiskCache(diskCache cache.Cache) GitalyServerOpt { return deps } } + +// WithConcurrencyTracker sets the PackObjectsConcurrencyTracker that will be +// used for gitaly services initialization. +func WithConcurrencyTracker(tracker *hook.ConcurrencyTracker) GitalyServerOpt { + return func(deps gitalyServerDeps) gitalyServerDeps { + deps.packObjectsConcurrencyTracker = tracker + return deps + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/praefect.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/praefect.go similarity index 52% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/praefect.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/praefect.go index 7cad843273..8f4fc50405 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testserver/praefect.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver/praefect.go @@ -1,18 +1,22 @@ package testserver import ( + "bytes" + "context" "net" "os" "os/exec" "path/filepath" + "sync" "testing" + "time" - "github.com/pelletier/go-toml" + "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" - gitalycfg "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper/testcfg" + gitalycfg "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) // praefectSpawnTokens limits the number of concurrent Praefect instances we spawn. With parallel @@ -46,51 +50,92 @@ func (ps PraefectServer) Shutdown() { // StartPraefect creates and runs a Praefect proxy. This server is created by running the external // Praefect executable. -func StartPraefect(t testing.TB, cfg config.Config) PraefectServer { - t.Helper() +func StartPraefect(tb testing.TB, cfg config.Config) PraefectServer { + tb.Helper() praefectSpawnTokens <- struct{}{} - t.Cleanup(func() { + tb.Cleanup(func() { <-praefectSpawnTokens }) // We're precreating the Unix socket which we pass to Praefect. This closes a race where // the Unix socket didn't yet exist when we tried to dial the Praefect server. praefectServerSocket, err := net.Listen("unix", cfg.SocketPath) - require.NoError(t, err) - testhelper.MustClose(t, praefectServerSocket) - t.Cleanup(func() { require.NoError(t, os.RemoveAll(praefectServerSocket.Addr().String())) }) + require.NoError(tb, err) + testhelper.MustClose(tb, praefectServerSocket) + tb.Cleanup(func() { require.NoError(tb, os.RemoveAll(praefectServerSocket.Addr().String())) }) - tempDir := testhelper.TempDir(t) + tempDir := testhelper.TempDir(tb) configFilePath := filepath.Join(tempDir, "config.toml") configFile, err := os.Create(configFilePath) - require.NoError(t, err) - defer testhelper.MustClose(t, configFile) + require.NoError(tb, err) + defer testhelper.MustClose(tb, configFile) - require.NoError(t, toml.NewEncoder(configFile).Encode(&cfg)) - require.NoError(t, configFile.Sync()) + require.NoError(tb, toml.NewEncoder(configFile).Encode(&cfg)) + require.NoError(tb, configFile.Sync()) - binaryPath := testcfg.BuildPraefect(t, gitalycfg.Cfg{ + binaryPath := testcfg.BuildPraefect(tb, gitalycfg.Cfg{ BinDir: tempDir, }) cmd := exec.Command(binaryPath, "-config", configFilePath) - cmd.Stderr = os.Stderr + // Logs are written to stderr, we can ignore stdout. + var stderr bytes.Buffer + cmd.Stderr = &stderr cmd.Stdout = os.Stdout - require.NoError(t, cmd.Start()) + require.NoError(tb, cmd.Start()) + + var waitErr error + var waitOnce sync.Once + wait := func() error { + waitOnce.Do(func() { + waitErr = cmd.Wait() + }) + return waitErr + } praefectServer := PraefectServer{ address: "unix://" + praefectServerSocket.Addr().String(), shutdown: func() { _ = cmd.Process.Kill() - _ = cmd.Wait() + _ = wait() }, } - t.Cleanup(praefectServer.Shutdown) + tb.Cleanup(praefectServer.Shutdown) - waitHealthy(t, praefectServer.Address(), cfg.Auth.Token) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + + processExitedCh := make(chan error, 1) + go func() { + processExitedCh <- wait() + cancel() + }() + + // Ensure this runs even if context ends in waitHealthy. + defer func() { + // Check if the process has exited. This must not happen given that we need it to be + // up in order to connect to it. + select { + case <-processExitedCh: + require.FailNowf(tb, "Praefect has died", "%s", stderr.String()) + default: + } + + select { + case <-ctx.Done(): + switch ctx.Err() { + case context.DeadlineExceeded: + // Capture Praefect logs when waitHealthy takes too long. + require.FailNowf(tb, "Connecting to Praefect exceeded deadline", "%s", stderr.String()) + } + default: + } + }() + + waitHealthy(ctx, tb, praefectServer.Address(), cfg.Auth.Token) return praefectServer } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo/transaction.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo/transaction.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo/transaction.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo/transaction.go index 1d6ddea386..b71b35d2ea 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/txinfo/transaction.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo/transaction.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" "google.golang.org/grpc/metadata" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/phase.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/phase.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/phase.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/phase.go index fb3922a6c5..40750a39a0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/phase.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/phase.go @@ -3,7 +3,7 @@ package voting import ( "fmt" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) // Phase is the transactional phase a given vote can be cast on. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/testhelper_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/testhelper_test.go similarity index 50% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/testhelper_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/testhelper_test.go index 59ee6c4a8d..eecb0caaa5 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/testhelper_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/testhelper_test.go @@ -1,9 +1,11 @@ +//go:build !gitaly_test_sha256 + package voting import ( "testing" - "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestMain(m *testing.M) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/vote.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/vote.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/vote.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/vote.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/vote_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/vote_test.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/vote_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/vote_test.go index 98acfd5097..d49add84b7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/transaction/voting/vote_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting/vote_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package voting import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/version/gitaly_version.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/version/gitaly_version.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/version/gitaly_version.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/version/gitaly_version.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/common.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/common.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/common.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/common.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/pool.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/pool.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/pool.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/pool.go index c96a9db674..7030fb6383 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/pool.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/pool.go @@ -1,5 +1,4 @@ //go:build !darwin -// +build !darwin package x509 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/pool_darwin.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/pool_darwin.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/internal/x509/pool_darwin.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/internal/x509/pool_darwin.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries.go new file mode 100644 index 0000000000..fe3e435e08 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries.go @@ -0,0 +1,67 @@ +package gitaly + +import ( + "embed" + "fmt" + "io" + "os" + "path/filepath" +) + +// buildDir is the directory path where our build target places the built binaries. +const buildDir = "_build/bin" + +//go:embed _build/bin/gitaly-hooks _build/bin/gitaly-ssh _build/bin/gitaly-git2go _build/bin/gitaly-lfs-smudge +// +// packedBinariesFS contains embedded binaries. If you modify the above embeddings, you must also update +// GITALY_PACKED_EXECUTABLES in Makefile and packedBinaries in internal/gitaly/config/config.go. +var packedBinariesFS embed.FS + +// UnpackAuxiliaryBinaries unpacks the packed auxiliary binaries of Gitaly into destination directory. +// +// Gitaly invoking auxiliary binaries across different releases is a source of backwards compatibility issues. +// The calling protocol may change and cause issues if we don't carefully maintain the compatibility. Major version +// changing the module path also causes problems for gob encoding as it effectively changes the name of every type. +// To avoid having to maintain backwards compatibility between the different Gitaly binaries, we want to pin a given +// gitaly binary to only ever call the auxiliary binaries of the same build. We achieve this by packing the auxiliary +// binaries in the main gitaly binary and unpacking them on start to a temporary directory we can call them from. This +// way updating the gitaly binaries on the disk is atomic and a running gitaly can't call auxiliary binaries from a +// different version. +func UnpackAuxiliaryBinaries(destinationDir string) error { + entries, err := packedBinariesFS.ReadDir(buildDir) + if err != nil { + return fmt.Errorf("list packed binaries: %w", err) + } + + for _, entry := range entries { + if err := func() error { + packedPath := filepath.Join(buildDir, entry.Name()) + packedFile, err := packedBinariesFS.Open(packedPath) + if err != nil { + return fmt.Errorf("open packed binary %q: %w", packedPath, err) + } + defer packedFile.Close() + + unpackedPath := filepath.Join(destinationDir, entry.Name()) + unpackedFile, err := os.OpenFile(unpackedPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o700) + if err != nil { + return err + } + defer unpackedFile.Close() + + if _, err := io.Copy(unpackedFile, packedFile); err != nil { + return fmt.Errorf("unpack %q: %w", unpackedPath, err) + } + + if err := unpackedFile.Close(); err != nil { + return fmt.Errorf("close %q: %w", unpackedPath, err) + } + + return nil + }(); err != nil { + return err + } + } + + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries_test.go new file mode 100644 index 0000000000..d904ab28b8 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/packed_binaries_test.go @@ -0,0 +1,44 @@ +package gitaly + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestUnpackAuxiliaryBinaries_success(t *testing.T) { + destinationDir := t.TempDir() + require.NoError(t, UnpackAuxiliaryBinaries(destinationDir)) + + entries, err := os.ReadDir(destinationDir) + require.NoError(t, err) + + require.Greater(t, len(entries), 1, "expected multiple packed binaries present") + + for _, entry := range entries { + fileInfo, err := entry.Info() + require.NoError(t, err) + require.Equal(t, fileInfo.Mode(), os.FileMode(0o700), "expected the owner to have rwx permissions on the unpacked binary") + + sourceBinary, err := os.ReadFile(filepath.Join(buildDir, fileInfo.Name())) + require.NoError(t, err) + + unpackedBinary, err := os.ReadFile(filepath.Join(destinationDir, fileInfo.Name())) + require.NoError(t, err) + + require.Equal(t, sourceBinary, unpackedBinary, "unpacked binary does not match the source binary") + } +} + +func TestUnpackAuxiliaryBinaries_alreadyExists(t *testing.T) { + destinationDir := t.TempDir() + + existingFile := filepath.Join(destinationDir, "gitaly-hooks") + require.NoError(t, os.WriteFile(existingFile, []byte("existing file"), os.ModePerm)) + + err := UnpackAuxiliaryBinaries(destinationDir) + require.EqualError(t, err, fmt.Sprintf(`open %s: file exists`, existingFile), "expected unpacking to fail if destination binary already existed") +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/.protolint.yaml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/.protolint.yaml new file mode 100644 index 0000000000..1a53539c0b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/.protolint.yaml @@ -0,0 +1,16 @@ +--- +lint: + rules: + all_default: true + remove: + # We don't specify any line length limits. + - MAX_LINE_LENGTH + # We do not put comments in front of files. We already document services, + # and only have a single service per file, so there is not much of a + # point anyway. + - FILE_HAS_COMMENT + # Many of our fields and messages have prepositions in them, and + # furthermore this rule doesn't feel all that sensible after all. We thus + # disable it. + - FIELD_NAMES_EXCLUDE_PREPOSITIONS + - MESSAGE_NAMES_EXCLUDE_PREPOSITIONS diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/blob.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/blob.proto similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/blob.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/blob.proto index 4d6653bc4f..b07bb874fc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/blob.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/blob.proto @@ -2,12 +2,15 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// BlobService is a service which provides RPCs to retrieve Git blobs from a +// specific repository. service BlobService { + // GetBlob returns the contents of a blob object referenced by its object // ID. We use a stream to return a chunked arbitrarily large binary // response @@ -16,6 +19,8 @@ service BlobService { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc GetBlobs(GetBlobsRequest) returns (stream GetBlobsResponse) { option (op_type) = { op: ACCESSOR @@ -70,8 +75,9 @@ service BlobService { } +// This comment is left unintentionally blank. message GetBlobRequest { - + // This comment is left unintentionally blank. Repository repository = 1[(target_repository)=true]; // Object ID (SHA1) of the blob we want to get string oid = 2; @@ -79,6 +85,7 @@ message GetBlobRequest { int64 limit = 3; } +// This comment is left unintentionally blank. message GetBlobResponse { // Blob size; present only in first response message int64 size = 1; @@ -88,13 +95,17 @@ message GetBlobResponse { string oid = 3; } +// This comment is left unintentionally blank. message GetBlobsRequest { - + // This comment is left unintentionally blank. message RevisionPath { + // This comment is left unintentionally blank. string revision = 1; + // This comment is left unintentionally blank. bytes path = 2; } + // This comment is left unintentionally blank. Repository repository = 1[(target_repository)=true]; // Revision/Path pairs of the blobs we want to get. repeated RevisionPath revision_paths = 2; @@ -102,6 +113,7 @@ message GetBlobsRequest { int64 limit = 3; } +// This comment is left unintentionally blank. message GetBlobsResponse { // Blob size; present only on the first message per blob int64 size = 1; @@ -109,10 +121,15 @@ message GetBlobsResponse { bytes data = 2; // Object ID of the current blob. Only present on the first message per blob. Empty if no blob was found. string oid = 3; + // This comment is left unintentionally blank. bool is_submodule = 4; + // This comment is left unintentionally blank. int32 mode = 5; + // This comment is left unintentionally blank. string revision = 6; + // This comment is left unintentionally blank. bytes path = 7; + // This comment is left unintentionally blank. ObjectType type = 8; } @@ -212,9 +229,13 @@ message LFSPointer { string oid = 3; } +// This comment is left unintentionally blank. message NewBlobObject { + // This comment is left unintentionally blank. int64 size = 1; + // This comment is left unintentionally blank. string oid = 2; + // This comment is left unintentionally blank. bytes path = 3; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/cleanup.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/cleanup.proto similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/cleanup.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/cleanup.proto index bcce016e5a..92455c2b83 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/cleanup.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/cleanup.proto @@ -2,19 +2,24 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// CleanupService provides RPCs to clean up a repository's contents. service CleanupService { + + // This comment is left unintentionally blank. rpc ApplyBfgObjectMapStream(stream ApplyBfgObjectMapStreamRequest) returns (stream ApplyBfgObjectMapStreamResponse) { option (op_type) = { op: MUTATOR }; } + } +// This comment is left unintentionally blank. message ApplyBfgObjectMapStreamRequest { // Only available on the first message Repository repository = 1 [(target_repository)=true]; @@ -25,14 +30,19 @@ message ApplyBfgObjectMapStreamRequest { bytes object_map = 2; } +// This comment is left unintentionally blank. message ApplyBfgObjectMapStreamResponse { - // We send back each parsed entry in the request's object map so the client - // can take action - message Entry { - ObjectType type = 1; - string old_oid = 2; - string new_oid = 3; - } + // We send back each parsed entry in the request's object map so the client + // can take action + message Entry { + // This comment is left unintentionally blank. + ObjectType type = 1; + // This comment is left unintentionally blank. + string old_oid = 2; + // This comment is left unintentionally blank. + string new_oid = 3; + } - repeated Entry entries = 1; + // This comment is left unintentionally blank. + repeated Entry entries = 1; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/commit.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/commit.proto similarity index 55% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/commit.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/commit.proto index 405d54f5a3..a8843cc5b6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/commit.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/commit.proto @@ -2,12 +2,14 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - +import "google/protobuf/timestamp.proto"; import "lint.proto"; import "shared.proto"; -import "google/protobuf/timestamp.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// CommitService is a service which provides RPCs that interact with Git +// commits. service CommitService { // ListCommits lists all commits reachable via a set of references by doing a @@ -27,104 +29,141 @@ service CommitService { }; } + // This comment is left unintentionally blank. rpc CommitIsAncestor(CommitIsAncestorRequest) returns (CommitIsAncestorResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc TreeEntry(TreeEntryRequest) returns (stream TreeEntryResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CountCommits(CountCommitsRequest) returns (CountCommitsResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CountDivergingCommits(CountDivergingCommitsRequest) returns (CountDivergingCommitsResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc GetTreeEntries(GetTreeEntriesRequest) returns (stream GetTreeEntriesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ListFiles(ListFilesRequest) returns (stream ListFilesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindCommit(FindCommitRequest) returns (FindCommitResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CommitStats(CommitStatsRequest) returns (CommitStatsResponse) { option (op_type) = { op: ACCESSOR }; } + // Use a stream to paginate the result set rpc FindAllCommits(FindAllCommitsRequest) returns (stream FindAllCommitsResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindCommits(FindCommitsRequest) returns (stream FindCommitsResponse) { option (op_type) = { op: ACCESSOR }; } + + // CommitLanguages detects the source code languages of the whole tree for a + // given commit. Returns an error in case no languages could be detected. rpc CommitLanguages(CommitLanguagesRequest) returns (CommitLanguagesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc RawBlame(RawBlameRequest) returns (stream RawBlameResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc LastCommitForPath(LastCommitForPathRequest) returns (LastCommitForPathResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ListLastCommitsForTree(ListLastCommitsForTreeRequest) returns (stream ListLastCommitsForTreeResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CommitsByMessage(CommitsByMessageRequest) returns (stream CommitsByMessageResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ListCommitsByOid(ListCommitsByOidRequest) returns (stream ListCommitsByOidResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ListCommitsByRefName(ListCommitsByRefNameRequest) returns (stream ListCommitsByRefNameResponse) { option (op_type) = { op: ACCESSOR }; } + // This comment is left unintentionally blank. rpc FilterShasWithSignatures(stream FilterShasWithSignaturesRequest) returns (stream FilterShasWithSignaturesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc GetCommitSignatures(GetCommitSignaturesRequest) returns (stream GetCommitSignaturesResponse) { option (op_type) = { op: ACCESSOR }; } + // This comment is left unintentionally blank. rpc GetCommitMessages(GetCommitMessagesRequest) returns (stream GetCommitMessagesResponse) { option (op_type) = { op: ACCESSOR @@ -140,6 +179,7 @@ service CommitService { op: ACCESSOR }; } + } // ListCommitsRequest is a request for the ListCommits RPC. @@ -147,15 +187,15 @@ message ListCommitsRequest { // Order is the order in which commits shoud be traversed. enum Order { // NONE defaults to reverse chronological order. - NONE = 0; + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // TOPO order will cause no parents to be shown before all of its children // are shown. Furthermore, multiple lines of history will not be // intermixed. - TOPO = 1; + TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // DATE order will cause no parents to be shown before all of its children // are shown. Otherwise, commits are shown in commit timestamp order. This // can cause history to be shown intermixed. - DATE = 2; + DATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX }; // Repository is the repository in which commits should be searched for. @@ -202,6 +242,13 @@ message ListCommitsRequest { // Author will only list commits whose author matches the given pattern, // which is a regular expression. bytes author = 10; + + // IgnoreCase will apply case-sensitive behaviour while regex matching. + bool ignore_case = 12; + + // CommitMessagePatterns will only list commits whose commit message matches + // any of the given patterns. + repeated bytes commit_message_patterns = 13; } // ListCommitsResponse is a response for the ListCommits RPC. @@ -227,29 +274,43 @@ message ListAllCommitsResponse { repeated GitCommit commits = 1; } +// This comment is left unintentionally blank. message CommitStatsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; } +// This comment is left unintentionally blank. message CommitStatsResponse { // OID is the commit. Empty means not found string oid = 1; + // This comment is left unintentionally blank. int32 additions = 2; + // This comment is left unintentionally blank. int32 deletions = 3; } +// This comment is left unintentionally blank. message CommitIsAncestorRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string ancestor_id = 2; + // This comment is left unintentionally blank. string child_id = 3; } +// This comment is left unintentionally blank. message CommitIsAncestorResponse { + // This comment is left unintentionally blank. bool value = 1; } +// This comment is left unintentionally blank. message TreeEntryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // commit ID or refname bytes revision = 2; @@ -263,17 +324,25 @@ message TreeEntryRequest { int64 max_size = 5; } +// This comment is left unintentionally blank. message TreeEntryResponse { // TODO: Replace this enum with ObjectType in shared.proto enum ObjectType { - COMMIT = 0; - BLOB = 1; - TREE = 2; - TAG = 3; + // This comment is left unintentionally blank. + COMMIT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + BLOB = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TREE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TAG = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + + // This comment is left unintentionally blank. ObjectType type = 1; // SHA1 object ID string oid = 2; + // This comment is left unintentionally blank. int64 size = 3; // file mode int32 mode = 4; @@ -281,51 +350,76 @@ message TreeEntryResponse { bytes data = 5; } +// This comment is left unintentionally blank. message CountCommitsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. google.protobuf.Timestamp after = 3; + // This comment is left unintentionally blank. google.protobuf.Timestamp before = 4; + // This comment is left unintentionally blank. bytes path = 5; + // This comment is left unintentionally blank. int32 max_count = 6; // all and revision are mutually exclusive bool all = 7; + // This comment is left unintentionally blank. bool first_parent = 8; + // This comment is left unintentionally blank. GlobalOptions global_options = 9; } +// This comment is left unintentionally blank. message CountCommitsResponse { + // This comment is left unintentionally blank. int32 count = 1; } +// This comment is left unintentionally blank. message CountDivergingCommitsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes from = 2; + // This comment is left unintentionally blank. bytes to = 3; reserved 4; reserved 5; reserved 6; + // This comment is left unintentionally blank. int32 max_count = 7; } +// This comment is left unintentionally blank. message CountDivergingCommitsResponse { + // This comment is left unintentionally blank. int32 left_count = 1; + // This comment is left unintentionally blank. int32 right_count = 2; } +// This comment is left unintentionally blank. message TreeEntry { // TODO: Replace this enum with ObjectType in shared.proto enum EntryType { - BLOB = 0; - TREE = 1; - COMMIT = 3; + // This comment is left unintentionally blank. + BLOB = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TREE = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + COMMIT = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // OID of the object this tree entry points to string oid = 1; // OID of the tree attached to commit_oid string root_oid = 2; // Path relative to repository root bytes path = 3; + // This comment is left unintentionally blank. EntryType type = 4; // File mode e.g. 0644 int32 mode = 5; @@ -335,31 +429,46 @@ message TreeEntry { bytes flat_path = 7; } +// This comment is left unintentionally blank. message GetTreeEntriesRequest { - Repository repository = 1 [(target_repository)=true]; - bytes revision = 2; - bytes path = 3; - bool recursive = 4; - + // This comment is left unintentionally blank. enum SortBy { - DEFAULT = 0; // Preserve order of git ls-tree - TREES_FIRST = 1; // trees, blobs, submodules + // Preserve order of git ls-tree. + DEFAULT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // Trees, blobs, submodules. + TREES_FIRST = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + bytes revision = 2; + // This comment is left unintentionally blank. + bytes path = 3; + // This comment is left unintentionally blank. + bool recursive = 4; + // This comment is left unintentionally blank. SortBy sort = 5; // The page token is the last commit OID that was sent. It's expected to be the // full object ID to guard against ambigious OIDs. PaginationParameter pagination_params = 6; + // SkipFlatPath is an option to skip the expensive operation of populating flat paths. + bool skip_flat_paths = 7; } +// This comment is left unintentionally blank. message GetTreeEntriesResponse { + // This comment is left unintentionally blank. repeated TreeEntry entries = 1; - + // This comment is left unintentionally blank. PaginationCursor pagination_cursor = 2; } +// This comment is left unintentionally blank. message ListFilesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; } @@ -369,214 +478,343 @@ message ListFilesResponse { repeated bytes paths = 1; } +// This comment is left unintentionally blank. message FindCommitRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. bool trailers = 3; } +// This comment is left unintentionally blank. message FindCommitResponse { // commit is nil when the commit was not found GitCommit commit = 1; } +// This comment is left unintentionally blank. message ListCommitsByOidRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; - repeated string oid = 2; + // This comment is left unintentionally blank. + repeated string oid = 2; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED } +// This comment is left unintentionally blank. message ListCommitsByOidResponse { + // This comment is left unintentionally blank. repeated GitCommit commits = 1; } +// This comment is left unintentionally blank. message ListCommitsByRefNameRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. repeated bytes ref_names = 2; } +// This comment is left unintentionally blank. message ListCommitsByRefNameResponse { reserved 1; + // This comment is left unintentionally blank. message CommitForRef { + // This comment is left unintentionally blank. GitCommit commit = 1; + // This comment is left unintentionally blank. bytes ref_name = 2; } + // This comment is left unintentionally blank. repeated CommitForRef commit_refs = 2; } +// This comment is left unintentionally blank. message FindAllCommitsRequest { + // This comment is left unintentionally blank. + enum Order { + // This comment is left unintentionally blank. + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + DATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // When nil, return all commits reachable by any branch in the repo bytes revision = 2; + // This comment is left unintentionally blank. int32 max_count = 3; + // This comment is left unintentionally blank. int32 skip = 4; - enum Order { - NONE = 0; - TOPO = 1; - DATE = 2; - } + // This comment is left unintentionally blank. Order order = 5; } // A single 'page' of the result set message FindAllCommitsResponse { + // This comment is left unintentionally blank. repeated GitCommit commits = 1; } +// This comment is left unintentionally blank. message FindCommitsRequest { + // This comment is left unintentionally blank. + enum Order { + // This comment is left unintentionally blank. + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TOPO = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. int32 limit = 3; + // This comment is left unintentionally blank. int32 offset = 4; + // This comment is left unintentionally blank. repeated bytes paths = 5; + // This comment is left unintentionally blank. bool follow = 6; + // This comment is left unintentionally blank. bool skip_merges = 7; + // This comment is left unintentionally blank. bool disable_walk = 8; + // This comment is left unintentionally blank. google.protobuf.Timestamp after = 9; + // This comment is left unintentionally blank. google.protobuf.Timestamp before = 10; // all and revision are mutually exclusive bool all = 11; + // This comment is left unintentionally blank. bool first_parent = 12; + // This comment is left unintentionally blank. bytes author = 13; - enum Order { - NONE = 0; - TOPO = 1; - } + // This comment is left unintentionally blank. Order order = 14; + // This comment is left unintentionally blank. GlobalOptions global_options = 15; + // This comment is left unintentionally blank. bool trailers = 16; + // include_shortstat determines whether to include the number of lines and files + // changed in the commits. Populates the `short_stats` field. + bool include_shortstat = 17; } // A single 'page' of the result set message FindCommitsResponse { + // This comment is left unintentionally blank. repeated GitCommit commits = 1; } +// CommitLanguagesRequest requests to detect the source code languages. message CommitLanguagesRequest { + // Repository is the repository where to detect the languages in. Repository repository = 1 [(target_repository)=true]; + // Revision tells for which commit the languages should be detected. If it's + // omitted, the HEAD commit of the default branch is used. bytes revision = 2; } +// CommitLanguagesResponse returns the language statistics. message CommitLanguagesResponse { + // Language specifies the statistics for one language. message Language { + // Name is the name of the detected language, for example: Ruby, Go, HTML + // A full list of language names can be found at: + // https://github.com/github/linguist/blob/master/lib/linguist/languages.yml string name = 1; + // Share is the percentual share (value between 0 and 100) of this language + // in relation to other languages that exist in the given revision. float share = 2; + // Color specifies the associated color for this language, for example #3fd5e0. string color = 3; + // FileCount tells how many files with this language are found. uint32 file_count = 4; + // Bytes is the total amount of bytes written in this language uint64 bytes = 5; } + + // Languages is a set of all the detected languages and their statistics. repeated Language languages = 1; } +// This comment is left unintentionally blank. message RawBlameRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. bytes path = 3; // Comma-separated range of line numbers to perform the blame on: "1,1000". // Optional - if no range is provided, the whole file will be blamed. bytes range = 4; } +// This comment is left unintentionally blank. message RawBlameResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message LastCommitForPathRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. + // This comment is left unintentionally blank. + // This comment is left unintentionally blank. bytes path = 3; + // This comment is left unintentionally blank. bool literal_pathspec = 4; // Deprecate after Rails stops using this + // This comment is left unintentionally blank. GlobalOptions global_options = 5; } +// This comment is left unintentionally blank. message LastCommitForPathResponse { // commit is nil when the commit was not found GitCommit commit = 1; } +// This comment is left unintentionally blank. message ListLastCommitsForTreeRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string revision = 2; + // This comment is left unintentionally blank. bytes path = 3; + // This comment is left unintentionally blank. int32 limit = 4; + // This comment is left unintentionally blank. int32 offset = 5; + // This comment is left unintentionally blank. bool literal_pathspec = 6 [deprecated = true]; + // This comment is left unintentionally blank. GlobalOptions global_options = 7; } +// This comment is left unintentionally blank. message ListLastCommitsForTreeResponse { + // This comment is left unintentionally blank. message CommitForTree { reserved 1; + // This comment is left unintentionally blank. GitCommit commit = 2; reserved 3; + // This comment is left unintentionally blank. bytes path_bytes = 4; } + + // This comment is left unintentionally blank. repeated CommitForTree commits = 1; } +// This comment is left unintentionally blank. message CommitsByMessageRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; + // This comment is left unintentionally blank. int32 offset = 3; + // This comment is left unintentionally blank. int32 limit = 4; + // This comment is left unintentionally blank. bytes path = 5; + // This comment is left unintentionally blank. string query = 6; + // This comment is left unintentionally blank. GlobalOptions global_options = 7; } // One 'page' of the paginated response of CommitsByMessage message CommitsByMessageResponse { + // This comment is left unintentionally blank. repeated GitCommit commits = 1; } +// This comment is left unintentionally blank. message FilterShasWithSignaturesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. repeated bytes shas = 2; } +// This comment is left unintentionally blank. message FilterShasWithSignaturesResponse { + // This comment is left unintentionally blank. repeated bytes shas = 1; } +// This comment is left unintentionally blank. message ExtractCommitSignatureRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string commit_id = 2; } // Either of the 'signature' and 'signed_text' fields may be present. It // is up to the caller to stitch them together. message ExtractCommitSignatureResponse { + // This comment is left unintentionally blank. bytes signature = 1; + // This comment is left unintentionally blank. bytes signed_text = 2; } +// This comment is left unintentionally blank. message GetCommitSignaturesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. repeated string commit_ids = 2; } +// This comment is left unintentionally blank. message GetCommitSignaturesResponse { // Only present for a new commit signature data. string commit_id = 1; // See ExtractCommitSignatureResponse above for how these fields should be handled. bytes signature = 2; + // This comment is left unintentionally blank. bytes signed_text = 3; } +// This comment is left unintentionally blank. message GetCommitMessagesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. repeated string commit_ids = 2; } +// This comment is left unintentionally blank. message GetCommitMessagesResponse { // Only present for a new commit message string commit_id = 1; + // This comment is left unintentionally blank. bytes message = 2; } -// CheckObjectsExistRequest is a request for the CheckObjectsExist RPC. +// CheckObjectsExistRequest is a request for the CheckObjectsExist RPC. Only +// the initial request must contain a repository, the repository of all +// subsequent requests will be ignored. message CheckObjectsExistRequest { // Repository is the repository in which existence of objects and refs // are checked. @@ -586,11 +824,16 @@ message CheckObjectsExistRequest { repeated bytes revisions = 2; } +// This comment is left unintentionally blank. message CheckObjectsExistResponse { + // This comment is left unintentionally blank. message RevisionExistence { + // This comment is left unintentionally blank. bytes name = 1; + // This comment is left unintentionally blank. bool exists = 2; }; + // This comment is left unintentionally blank. repeated RevisionExistence revisions = 1; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/conflicts.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/conflicts.proto similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/conflicts.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/conflicts.proto index b8eedb8a11..4fd0a18f08 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/conflicts.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/conflicts.proto @@ -2,13 +2,18 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - +import "google/protobuf/timestamp.proto"; import "lint.proto"; import "shared.proto"; -import "google/protobuf/timestamp.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// ConflictsService is a service which provides RPCs to interact with conflicts +// resulting from a merge. service ConflictsService { + + // ListConflictFiles returns all conflicting files which result from a merge + // of two specified commit objects. rpc ListConflictFiles(ListConflictFilesRequest) returns (stream ListConflictFilesResponse) { option (op_type) = { op: ACCESSOR @@ -23,11 +28,16 @@ service ConflictsService { op: MUTATOR }; } + } +// This comment is left unintentionally blank. message ListConflictFilesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string our_commit_oid = 2; + // This comment is left unintentionally blank. string their_commit_oid = 3; // AllowTreeConflicts will not cause the request to fail in case there are // tree conflicts. If set to true, then responses may contain conflict files @@ -35,23 +45,34 @@ message ListConflictFilesRequest { bool allow_tree_conflicts = 4; } +// This comment is left unintentionally blank. message ConflictFileHeader { reserved 1; + // This comment is left unintentionally blank. string commit_oid = 2; + // This comment is left unintentionally blank. bytes their_path = 3; + // This comment is left unintentionally blank. bytes our_path = 4; + // This comment is left unintentionally blank. int32 our_mode = 5; + // This comment is left unintentionally blank. bytes ancestor_path = 6; } +// This comment is left unintentionally blank. message ConflictFile { oneof conflict_file_payload { + // This comment is left unintentionally blank. ConflictFileHeader header = 1; + // This comment is left unintentionally blank. bytes content = 2; } } +// This comment is left unintentionally blank. message ListConflictFilesResponse { + // This comment is left unintentionally blank. repeated ConflictFile files = 1; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/diff.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/diff.proto new file mode 100644 index 0000000000..3247ceb577 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/diff.proto @@ -0,0 +1,314 @@ +syntax = "proto3"; + +package gitaly; + +import "lint.proto"; +import "shared.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// DiffService is a service which provides RPCs to inspect differences +// introduced between a set of commits. +service DiffService { + + // Returns stream of CommitDiffResponse with patches chunked over messages + rpc CommitDiff(CommitDiffRequest) returns (stream CommitDiffResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // Return a stream so we can divide the response in chunks of deltas + rpc CommitDelta(CommitDeltaRequest) returns (stream CommitDeltaResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc RawDiff(RawDiffRequest) returns (stream RawDiffResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc RawPatch(RawPatchRequest) returns (stream RawPatchResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc DiffStats(DiffStatsRequest) returns (stream DiffStatsResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // Return a list of files changed along with the status of each file + rpc FindChangedPaths(FindChangedPathsRequest) returns (stream FindChangedPathsResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + +} + +// This comment is left unintentionally blank. +message CommitDiffRequest { + // This comment is left unintentionally blank. + enum DiffMode { + // DEFAULT is the standard diff mode and results in a linewise diff for textfiles. + DEFAULT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // WORDDIFF is a word diff and computes the diff for whitespace separated words instead of for whole lines. + WORDDIFF = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string left_commit_id = 2; + // This comment is left unintentionally blank. + string right_commit_id = 3; + // This comment is left unintentionally blank. + bool ignore_whitespace_change = 4; + // This comment is left unintentionally blank. + repeated bytes paths = 5; + // This comment is left unintentionally blank. + bool collapse_diffs = 6; + // This comment is left unintentionally blank. + bool enforce_limits = 7; + + // These limits are only enforced when enforce_limits == true. + int32 max_files = 8; + // This comment is left unintentionally blank. + int32 max_lines = 9; + // This comment is left unintentionally blank. + int32 max_bytes = 10; + // Limitation of a single diff patch, + // patches surpassing this limit are pruned by default. + // If this is 0 you will get back empty patches. + int32 max_patch_bytes = 14; + + // These limits are only enforced if collapse_diffs == true. + int32 safe_max_files = 11; + // This comment is left unintentionally blank. + int32 safe_max_lines = 12; + // This comment is left unintentionally blank. + int32 safe_max_bytes = 13; + + // DiffMode is the mode used for generating the diff. Please refer to the enum declaration for supported modes. + DiffMode diff_mode = 15; +} + +// A CommitDiffResponse corresponds to a single changed file in a commit. +message CommitDiffResponse { + reserved 8; + + // This comment is left unintentionally blank. + bytes from_path = 1; + // This comment is left unintentionally blank. + bytes to_path = 2; + // Blob ID as returned via `git diff --full-index` + string from_id = 3; + // This comment is left unintentionally blank. + string to_id = 4; + // This comment is left unintentionally blank. + int32 old_mode = 5; + // This comment is left unintentionally blank. + int32 new_mode = 6; + // This comment is left unintentionally blank. + bool binary = 7; + // This comment is left unintentionally blank. + bytes raw_patch_data = 9; + // This comment is left unintentionally blank. + bool end_of_patch = 10; + // Indicates the diff file at which we overflow according to the limitations sent, + // in which case only this attribute will be set. + bool overflow_marker = 11; + // Indicates the patch surpassed a "safe" limit and was therefore pruned, but + // the client may still request the full patch on a separate request. + bool collapsed = 12; + // Indicates the patch was pruned since it surpassed a hard limit, and can + // therefore not be expanded. + bool too_large = 13; +} + +// This comment is left unintentionally blank. +message CommitDeltaRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string left_commit_id = 2; + // This comment is left unintentionally blank. + string right_commit_id = 3; + // This comment is left unintentionally blank. + repeated bytes paths = 4; +} + +// This comment is left unintentionally blank. +message CommitDelta { + // This comment is left unintentionally blank. + bytes from_path = 1; + // This comment is left unintentionally blank. + bytes to_path = 2; + // Blob ID as returned via `git diff --full-index` + string from_id = 3; + // This comment is left unintentionally blank. + string to_id = 4; + // This comment is left unintentionally blank. + int32 old_mode = 5; + // This comment is left unintentionally blank. + int32 new_mode = 6; +} + +// This comment is left unintentionally blank. +message CommitDeltaResponse { + // This comment is left unintentionally blank. + repeated CommitDelta deltas = 1; +} + +// This comment is left unintentionally blank. +message RawDiffRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string left_commit_id = 2; + // This comment is left unintentionally blank. + string right_commit_id = 3; +} + +// This comment is left unintentionally blank. +message RawDiffResponse { + // This comment is left unintentionally blank. + bytes data = 1; +} + +// This comment is left unintentionally blank. +message RawPatchRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string left_commit_id = 2; + // This comment is left unintentionally blank. + string right_commit_id = 3; +} + +// This comment is left unintentionally blank. +message RawPatchResponse { + // This comment is left unintentionally blank. + bytes data = 1; +} + +// This comment is left unintentionally blank. +message DiffStatsRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string left_commit_id = 2; + // This comment is left unintentionally blank. + string right_commit_id = 3; +} + +// This comment is left unintentionally blank. +message DiffStats { + // This comment is left unintentionally blank. + bytes path = 1; + // This comment is left unintentionally blank. + int32 additions = 2; + // This comment is left unintentionally blank. + int32 deletions = 3; + // This comment is left unintentionally blank. + bytes old_path = 4; +} + +// This comment is left unintentionally blank. +message DiffStatsResponse { + // This comment is left unintentionally blank. + repeated DiffStats stats = 1; +} + +// Given a list of commits, return the files changed. Each commit is compared +// to its parent. Merge commits will show files which are different to all of +// its parents. +message FindChangedPathsRequest { + // Request is a single request to pass to git diff-tree. + message Request { + // TreeRequest compares two trees. + message TreeRequest { + // left_tree_revision is the revision of the left tree to compare. Accepts any revision that + // peels to a tree object. + string left_tree_revision = 1; + // right_tree_revision is the revision of the right tree to compare. Accepts any revision that + // peels to a tree object. + string right_tree_revision = 2; + } + + // CommitRequest compares a commit to its parents (or some other commits.) + message CommitRequest { + // commit_revision is the revision of the commit that should be compared. If no `parent_commit_revisions` + // are given, then the commit will be compared against its parents. The revision needs to peel to a + // commit object. + string commit_revision = 1; + // parent_commit_revisions are the revisions of commits to treat as the commit's parents. This is an + // optional field: if not specified, the actual parents of the commit referred to by `commit_revision` + // are used. + repeated string parent_commit_revisions = 2; + } + + oneof type { + // tree_request is a request comparing two trees with each other. + TreeRequest tree_request = 1; + // commit_request is a request comparing one or more commits with each other. + CommitRequest commit_request = 2; + } + } + + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // commits is the list of commits to compare to their parents. This field is deprecated. To adapt to the new calling + // convention you can create one `CommitRequest` per commit, where each `CommitRequest` has only the `commit_revision` + // field. + repeated string commits = 2 [deprecated=true]; + // requests specifies the requests of what to compare. + repeated Request requests = 3; +} + +// Returns a list of files that have been changed in the commits given +message FindChangedPathsResponse { + // This comment is left unintentionally blank. + repeated ChangedPaths paths = 1; +} + +// Includes the path of the file, and the status of the change +message ChangedPaths { + // This comment is left unintentionally blank. + enum Status { + // This comment is left unintentionally blank. + ADDED = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + MODIFIED = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + DELETED = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TYPE_CHANGE = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + COPIED = 4; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. + bytes path = 1; + // This comment is left unintentionally blank. + Status status = 2; + // old_mode is the mode of the changed path previous to the change. May be one of the following values: + // + // - 0o000000 if the path does not exist. + // - 0o100644 if the path refers to a normal file. + // - 0o100755 if the path refers to an executable file. + // - 0o040000 if the path refers to a tree entry. + // - 0o160000 if the path refers to a submodule. + int32 old_mode = 3; + // new_mode is the mode of the changed path after the change. Please refer to `old_mode` for a list of potential values. + int32 new_mode = 4; +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/errors.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/errors.proto new file mode 100644 index 0000000000..dbead8f0ec --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/errors.proto @@ -0,0 +1,134 @@ +syntax = "proto3"; + +package gitaly; + +import "google/protobuf/duration.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// AccessCheckError is an error returned by GitLab's `/internal/allowed` +// endpoint. +message AccessCheckError { + // ErrorMessage is the error message as returned by the endpoint. + string error_message = 1; + // Protocol is the protocol used. + string protocol = 2; + // UserId is the user ID as which changes had been pushed. + string user_id = 3; + // Changes is the set of changes which have failed the access check. + bytes changes = 4; +} + +// InvalidRefFormatError is an error returned when refs have an invalid format. +message InvalidRefFormatError { + // Refs are the offending refs with invalid formats. + repeated bytes refs = 2; +} + +// NotAncestorError is an error returned when parent_revision is not an ancestor +// of the child_revision. +message NotAncestorError { + // ParentRevision is the revision checked against ChildRevision for whether it + // is an ancestor of ChildRevision + bytes parent_revision = 1; + // ChildRevision is the revision checked against ParentRevision for whether + // it is a descendent of ChildRevision. + bytes child_revision = 2; +} + +// ChangesAlreadyAppliedError is an error returned when the operation would +// have resulted in no changes because these changes have already been applied. +message ChangesAlreadyAppliedError { +} + +// MergeConflictError is an error returned in the case when merging two commits +// fails due to a merge conflict. +message MergeConflictError { + // ConflictingFiles is the set of files which have been conflicting. If this + // field is empty, then there has still been a merge conflict, but it wasn't + // able to determine which files have been conflicting. + repeated bytes conflicting_files = 1; + // ConflictingCommitIds is the set of commit IDs that caused the conflict. In the general case, + // this should be set to two commit IDs. + repeated string conflicting_commit_ids = 2; +} + +// ReferencesLockedError is an error returned when an ref update fails because +// the references have already been locked by another process. +message ReferencesLockedError { + // Refs are the references that could not be locked. + repeated bytes refs = 1; +} + +// ReferenceExistsError is an error returned when a reference that ought not to exist does exist +// already. +message ReferenceExistsError { + // ReferenceName is the name of the reference that exists already. + bytes reference_name = 1; + // Oid is the object ID of the reference that preexists already. + string oid = 2; +} + +// ReferenceNotFoundError is an error retruned when a reference that ought to exist does not exist. +message ReferenceNotFoundError { + // ReferenceName is the name of the reference that does not exist. + bytes reference_name = 1; +} + +// ReferenceUpdateError is an error returned when updating a reference has +// failed. +message ReferenceUpdateError { + // ReferenceName is the name of the reference that failed to be updated. + bytes reference_name = 1; + // OldOid is the object ID the reference should have pointed to before the update. + string old_oid = 2; + // NewOid is the object ID the reference should have pointed to after the update. + string new_oid = 3; +} + +// ResolveRevisionError is an error returned when resolving a specific revision +// has failed. +message ResolveRevisionError { + // Revision is the name of the revision that was tried to be resolved. + bytes revision = 1; +} + +// LimitError is an error returned when Gitaly enforces request limits. +message LimitError { + // ErrorMessage provides context into why a limit was enforced. + string error_message = 1; + // RetryAfter provides the duration after which a retry is safe. + // 0 indicates non-retryable. + google.protobuf.Duration retry_after = 2; +} + +// CustomHookError is an error returned when Gitaly executes a custom hook and the hook returns +// a non-zero return code. +message CustomHookError { + // HookType is the type of the hook that has been running. Please consult githooks(5) for more + // information about the specific types. + enum HookType { + // HOOK_TYPE_UNSPECIFIED is the default hook type and should never be set. + HOOK_TYPE_UNSPECIFIED = 0; + // HOOK_TYPE_PRERECEIVE is executed after all changes have been written into a temporary staging + // directory, but before any references in the repository have been updated. It is executed with + // all references that are about to be updated at once. If this hook exits, then no references + // will have been updated in the repository and staged objects will have been discarded. + HOOK_TYPE_PRERECEIVE = 1; + // HOOK_TYPE_UPDATE is executed after the pre-receive hook. It is executed per reference that is + // about to be updated and can be used to reject only a subset of reference updates. If this + // hook error is raised then a subset of references may have already been updated. + HOOK_TYPE_UPDATE = 2; + // HOOK_TYPE_POSTRECEIVE is executed after objects have been migrated into the repository and + // after references have been updated. An error in this hook will not impact the changes + // anymore as everything has already been persisted. + HOOK_TYPE_POSTRECEIVE = 3; + }; + + // Stdout is the standard output of the hook that has failed, if any. Data may be truncated. + bytes stdout = 1; + // Stderr is the standard error of the hook that has failed, if any. Data may be truncated. + bytes stderr = 2; + // HookType is the type of the hook. + HookType hook_type = 3; +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob.pb.go index 5e1e0b4068..61f1e4b171 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: blob.proto package gitalypb @@ -20,11 +20,13 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type GetBlobRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Object ID (SHA1) of the blob we want to get Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` @@ -85,6 +87,7 @@ func (x *GetBlobRequest) GetLimit() int64 { return 0 } +// This comment is left unintentionally blank. type GetBlobResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -151,11 +154,13 @@ func (x *GetBlobResponse) GetOid() string { return "" } +// This comment is left unintentionally blank. type GetBlobsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Revision/Path pairs of the blobs we want to get. RevisionPaths []*GetBlobsRequest_RevisionPath `protobuf:"bytes,2,rep,name=revision_paths,json=revisionPaths,proto3" json:"revision_paths,omitempty"` @@ -216,6 +221,7 @@ func (x *GetBlobsRequest) GetLimit() int64 { return 0 } +// This comment is left unintentionally blank. type GetBlobsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -226,12 +232,17 @@ type GetBlobsResponse struct { // Chunk of blob data, could span over multiple messages. Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // Object ID of the current blob. Only present on the first message per blob. Empty if no blob was found. - Oid string `protobuf:"bytes,3,opt,name=oid,proto3" json:"oid,omitempty"` - IsSubmodule bool `protobuf:"varint,4,opt,name=is_submodule,json=isSubmodule,proto3" json:"is_submodule,omitempty"` - Mode int32 `protobuf:"varint,5,opt,name=mode,proto3" json:"mode,omitempty"` - Revision string `protobuf:"bytes,6,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,7,opt,name=path,proto3" json:"path,omitempty"` - Type ObjectType `protobuf:"varint,8,opt,name=type,proto3,enum=gitaly.ObjectType" json:"type,omitempty"` + Oid string `protobuf:"bytes,3,opt,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. + IsSubmodule bool `protobuf:"varint,4,opt,name=is_submodule,json=isSubmodule,proto3" json:"is_submodule,omitempty"` + // This comment is left unintentionally blank. + Mode int32 `protobuf:"varint,5,opt,name=mode,proto3" json:"mode,omitempty"` + // This comment is left unintentionally blank. + Revision string `protobuf:"bytes,6,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,7,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Type ObjectType `protobuf:"varint,8,opt,name=type,proto3,enum=gitaly.ObjectType" json:"type,omitempty"` } func (x *GetBlobsResponse) Reset() { @@ -660,13 +671,17 @@ func (x *LFSPointer) GetOid() string { return "" } +// This comment is left unintentionally blank. type NewBlobObject struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Size int64 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"` - Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. + Size int64 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"` + // This comment is left unintentionally blank. + Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` } @@ -1058,13 +1073,16 @@ func (x *ListAllLFSPointersResponse) GetLfsPointers() []*LFSPointer { return nil } +// This comment is left unintentionally blank. type GetBlobsRequest_RevisionPath struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Revision string `protobuf:"bytes,1,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` } func (x *GetBlobsRequest_RevisionPath) Reset() { @@ -1437,7 +1455,7 @@ var file_blob_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, - 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, + 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob_grpc.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob_grpc.pb.go index ffc48c0442..b8d710a8ac 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/blob_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/blob_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: blob.proto package gitalypb @@ -22,6 +26,7 @@ type BlobServiceClient interface { // ID. We use a stream to return a chunked arbitrarily large binary // response GetBlob(ctx context.Context, in *GetBlobRequest, opts ...grpc.CallOption) (BlobService_GetBlobClient, error) + // This comment is left unintentionally blank. GetBlobs(ctx context.Context, in *GetBlobsRequest, opts ...grpc.CallOption) (BlobService_GetBlobsClient, error) // ListBlobs will list all blobs reachable from a given set of revisions by // doing a graph walk. It is not valid to pass revisions which do not resolve @@ -286,6 +291,7 @@ type BlobServiceServer interface { // ID. We use a stream to return a chunked arbitrarily large binary // response GetBlob(*GetBlobRequest, BlobService_GetBlobServer) error + // This comment is left unintentionally blank. GetBlobs(*GetBlobsRequest, BlobService_GetBlobsServer) error // ListBlobs will list all blobs reachable from a given set of revisions by // doing a graph walk. It is not valid to pass revisions which do not resolve diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup.pb.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup.pb.go index 84c75b06b9..8abc524b21 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: cleanup.proto package gitalypb @@ -20,6 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type ApplyBfgObjectMapStreamRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -79,11 +80,13 @@ func (x *ApplyBfgObjectMapStreamRequest) GetObjectMap() []byte { return nil } +// This comment is left unintentionally blank. type ApplyBfgObjectMapStreamResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Entries []*ApplyBfgObjectMapStreamResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` } @@ -133,9 +136,12 @@ type ApplyBfgObjectMapStreamResponse_Entry struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type ObjectType `protobuf:"varint,1,opt,name=type,proto3,enum=gitaly.ObjectType" json:"type,omitempty"` - OldOid string `protobuf:"bytes,2,opt,name=old_oid,json=oldOid,proto3" json:"old_oid,omitempty"` - NewOid string `protobuf:"bytes,3,opt,name=new_oid,json=newOid,proto3" json:"new_oid,omitempty"` + // This comment is left unintentionally blank. + Type ObjectType `protobuf:"varint,1,opt,name=type,proto3,enum=gitaly.ObjectType" json:"type,omitempty"` + // This comment is left unintentionally blank. + OldOid string `protobuf:"bytes,2,opt,name=old_oid,json=oldOid,proto3" json:"old_oid,omitempty"` + // This comment is left unintentionally blank. + NewOid string `protobuf:"bytes,3,opt,name=new_oid,json=newOid,proto3" json:"new_oid,omitempty"` } func (x *ApplyBfgObjectMapStreamResponse_Entry) Reset() { @@ -228,7 +234,7 @@ var file_cleanup_proto_rawDesc = []byte{ 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, - 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup_grpc.pb.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup_grpc.pb.go index f49c5560c2..099c69e4ad 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/cleanup_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/cleanup_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: cleanup.proto package gitalypb @@ -18,6 +22,7 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type CleanupServiceClient interface { + // This comment is left unintentionally blank. ApplyBfgObjectMapStream(ctx context.Context, opts ...grpc.CallOption) (CleanupService_ApplyBfgObjectMapStreamClient, error) } @@ -64,6 +69,7 @@ func (x *cleanupServiceApplyBfgObjectMapStreamClient) Recv() (*ApplyBfgObjectMap // All implementations must embed UnimplementedCleanupServiceServer // for forward compatibility type CleanupServiceServer interface { + // This comment is left unintentionally blank. ApplyBfgObjectMapStream(CleanupService_ApplyBfgObjectMapStreamServer) error mustEmbedUnimplementedCleanupServiceServer() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit.pb.go similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit.pb.go index 4dd23e043d..f317908666 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: commit.proto package gitalypb @@ -26,15 +26,15 @@ type ListCommitsRequest_Order int32 const ( // NONE defaults to reverse chronological order. - ListCommitsRequest_NONE ListCommitsRequest_Order = 0 + ListCommitsRequest_NONE ListCommitsRequest_Order = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // TOPO order will cause no parents to be shown before all of its children // are shown. Furthermore, multiple lines of history will not be // intermixed. - ListCommitsRequest_TOPO ListCommitsRequest_Order = 1 + ListCommitsRequest_TOPO ListCommitsRequest_Order = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // DATE order will cause no parents to be shown before all of its children // are shown. Otherwise, commits are shown in commit timestamp order. This // can cause history to be shown intermixed. - ListCommitsRequest_DATE ListCommitsRequest_Order = 2 + ListCommitsRequest_DATE ListCommitsRequest_Order = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for ListCommitsRequest_Order. @@ -82,10 +82,14 @@ func (ListCommitsRequest_Order) EnumDescriptor() ([]byte, []int) { type TreeEntryResponse_ObjectType int32 const ( - TreeEntryResponse_COMMIT TreeEntryResponse_ObjectType = 0 - TreeEntryResponse_BLOB TreeEntryResponse_ObjectType = 1 - TreeEntryResponse_TREE TreeEntryResponse_ObjectType = 2 - TreeEntryResponse_TAG TreeEntryResponse_ObjectType = 3 + // This comment is left unintentionally blank. + TreeEntryResponse_COMMIT TreeEntryResponse_ObjectType = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TreeEntryResponse_BLOB TreeEntryResponse_ObjectType = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TreeEntryResponse_TREE TreeEntryResponse_ObjectType = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TreeEntryResponse_TAG TreeEntryResponse_ObjectType = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for TreeEntryResponse_ObjectType. @@ -135,9 +139,12 @@ func (TreeEntryResponse_ObjectType) EnumDescriptor() ([]byte, []int) { type TreeEntry_EntryType int32 const ( - TreeEntry_BLOB TreeEntry_EntryType = 0 - TreeEntry_TREE TreeEntry_EntryType = 1 - TreeEntry_COMMIT TreeEntry_EntryType = 3 + // This comment is left unintentionally blank. + TreeEntry_BLOB TreeEntry_EntryType = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TreeEntry_TREE TreeEntry_EntryType = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TreeEntry_COMMIT TreeEntry_EntryType = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for TreeEntry_EntryType. @@ -181,11 +188,14 @@ func (TreeEntry_EntryType) EnumDescriptor() ([]byte, []int) { return file_commit_proto_rawDescGZIP(), []int{14, 0} } +// This comment is left unintentionally blank. type GetTreeEntriesRequest_SortBy int32 const ( - GetTreeEntriesRequest_DEFAULT GetTreeEntriesRequest_SortBy = 0 // Preserve order of git ls-tree - GetTreeEntriesRequest_TREES_FIRST GetTreeEntriesRequest_SortBy = 1 // trees, blobs, submodules + // Preserve order of git ls-tree. + GetTreeEntriesRequest_DEFAULT GetTreeEntriesRequest_SortBy = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // Trees, blobs, submodules. + GetTreeEntriesRequest_TREES_FIRST GetTreeEntriesRequest_SortBy = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for GetTreeEntriesRequest_SortBy. @@ -227,12 +237,16 @@ func (GetTreeEntriesRequest_SortBy) EnumDescriptor() ([]byte, []int) { return file_commit_proto_rawDescGZIP(), []int{15, 0} } +// This comment is left unintentionally blank. type FindAllCommitsRequest_Order int32 const ( - FindAllCommitsRequest_NONE FindAllCommitsRequest_Order = 0 - FindAllCommitsRequest_TOPO FindAllCommitsRequest_Order = 1 - FindAllCommitsRequest_DATE FindAllCommitsRequest_Order = 2 + // This comment is left unintentionally blank. + FindAllCommitsRequest_NONE FindAllCommitsRequest_Order = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + FindAllCommitsRequest_TOPO FindAllCommitsRequest_Order = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + FindAllCommitsRequest_DATE FindAllCommitsRequest_Order = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for FindAllCommitsRequest_Order. @@ -276,11 +290,14 @@ func (FindAllCommitsRequest_Order) EnumDescriptor() ([]byte, []int) { return file_commit_proto_rawDescGZIP(), []int{25, 0} } +// This comment is left unintentionally blank. type FindCommitsRequest_Order int32 const ( - FindCommitsRequest_NONE FindCommitsRequest_Order = 0 - FindCommitsRequest_TOPO FindCommitsRequest_Order = 1 + // This comment is left unintentionally blank. + FindCommitsRequest_NONE FindCommitsRequest_Order = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + FindCommitsRequest_TOPO FindCommitsRequest_Order = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for FindCommitsRequest_Order. @@ -362,6 +379,11 @@ type ListCommitsRequest struct { // Author will only list commits whose author matches the given pattern, // which is a regular expression. Author []byte `protobuf:"bytes,10,opt,name=author,proto3" json:"author,omitempty"` + // IgnoreCase will apply case-sensitive behaviour while regex matching. + IgnoreCase bool `protobuf:"varint,12,opt,name=ignore_case,json=ignoreCase,proto3" json:"ignore_case,omitempty"` + // CommitMessagePatterns will only list commits whose commit message matches + // any of the given patterns. + CommitMessagePatterns [][]byte `protobuf:"bytes,13,rep,name=commit_message_patterns,json=commitMessagePatterns,proto3" json:"commit_message_patterns,omitempty"` } func (x *ListCommitsRequest) Reset() { @@ -473,6 +495,20 @@ func (x *ListCommitsRequest) GetAuthor() []byte { return nil } +func (x *ListCommitsRequest) GetIgnoreCase() bool { + if x != nil { + return x.IgnoreCase + } + return false +} + +func (x *ListCommitsRequest) GetCommitMessagePatterns() [][]byte { + if x != nil { + return x.CommitMessagePatterns + } + return nil +} + // ListCommitsResponse is a response for the ListCommits RPC. type ListCommitsResponse struct { state protoimpl.MessageState @@ -631,13 +667,16 @@ func (x *ListAllCommitsResponse) GetCommits() []*GitCommit { return nil } +// This comment is left unintentionally blank. type CommitStatsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` } func (x *CommitStatsRequest) Reset() { @@ -686,15 +725,18 @@ func (x *CommitStatsRequest) GetRevision() []byte { return nil } +// This comment is left unintentionally blank. type CommitStatsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // OID is the commit. Empty means not found - Oid string `protobuf:"bytes,1,opt,name=oid,proto3" json:"oid,omitempty"` - Additions int32 `protobuf:"varint,2,opt,name=additions,proto3" json:"additions,omitempty"` - Deletions int32 `protobuf:"varint,3,opt,name=deletions,proto3" json:"deletions,omitempty"` + Oid string `protobuf:"bytes,1,opt,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. + Additions int32 `protobuf:"varint,2,opt,name=additions,proto3" json:"additions,omitempty"` + // This comment is left unintentionally blank. + Deletions int32 `protobuf:"varint,3,opt,name=deletions,proto3" json:"deletions,omitempty"` } func (x *CommitStatsResponse) Reset() { @@ -750,14 +792,18 @@ func (x *CommitStatsResponse) GetDeletions() int32 { return 0 } +// This comment is left unintentionally blank. type CommitIsAncestorRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - AncestorId string `protobuf:"bytes,2,opt,name=ancestor_id,json=ancestorId,proto3" json:"ancestor_id,omitempty"` - ChildId string `protobuf:"bytes,3,opt,name=child_id,json=childId,proto3" json:"child_id,omitempty"` + // This comment is left unintentionally blank. + AncestorId string `protobuf:"bytes,2,opt,name=ancestor_id,json=ancestorId,proto3" json:"ancestor_id,omitempty"` + // This comment is left unintentionally blank. + ChildId string `protobuf:"bytes,3,opt,name=child_id,json=childId,proto3" json:"child_id,omitempty"` } func (x *CommitIsAncestorRequest) Reset() { @@ -813,11 +859,13 @@ func (x *CommitIsAncestorRequest) GetChildId() string { return "" } +// This comment is left unintentionally blank. type CommitIsAncestorResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` } @@ -860,11 +908,13 @@ func (x *CommitIsAncestorResponse) GetValue() bool { return false } +// This comment is left unintentionally blank. type TreeEntryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // commit ID or refname Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` @@ -945,15 +995,18 @@ func (x *TreeEntryRequest) GetMaxSize() int64 { return 0 } +// This comment is left unintentionally blank. type TreeEntryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Type TreeEntryResponse_ObjectType `protobuf:"varint,1,opt,name=type,proto3,enum=gitaly.TreeEntryResponse_ObjectType" json:"type,omitempty"` // SHA1 object ID - Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` - Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. + Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` // file mode Mode int32 `protobuf:"varint,4,opt,name=mode,proto3" json:"mode,omitempty"` // raw object contents @@ -1027,20 +1080,29 @@ func (x *TreeEntryResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type CountCommitsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - After *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=after,proto3" json:"after,omitempty"` - Before *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=before,proto3" json:"before,omitempty"` - Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` - MaxCount int32 `protobuf:"varint,6,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + After *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=after,proto3" json:"after,omitempty"` + // This comment is left unintentionally blank. + Before *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=before,proto3" json:"before,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + MaxCount int32 `protobuf:"varint,6,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` // all and revision are mutually exclusive - All bool `protobuf:"varint,7,opt,name=all,proto3" json:"all,omitempty"` - FirstParent bool `protobuf:"varint,8,opt,name=first_parent,json=firstParent,proto3" json:"first_parent,omitempty"` + All bool `protobuf:"varint,7,opt,name=all,proto3" json:"all,omitempty"` + // This comment is left unintentionally blank. + FirstParent bool `protobuf:"varint,8,opt,name=first_parent,json=firstParent,proto3" json:"first_parent,omitempty"` + // This comment is left unintentionally blank. GlobalOptions *GlobalOptions `protobuf:"bytes,9,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` } @@ -1139,11 +1201,13 @@ func (x *CountCommitsRequest) GetGlobalOptions() *GlobalOptions { return nil } +// This comment is left unintentionally blank. type CountCommitsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` } @@ -1186,15 +1250,20 @@ func (x *CountCommitsResponse) GetCount() int32 { return 0 } +// This comment is left unintentionally blank. type CountDivergingCommitsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - From []byte `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - To []byte `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` - MaxCount int32 `protobuf:"varint,7,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` + // This comment is left unintentionally blank. + From []byte `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + // This comment is left unintentionally blank. + To []byte `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + // This comment is left unintentionally blank. + MaxCount int32 `protobuf:"varint,7,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` } func (x *CountDivergingCommitsRequest) Reset() { @@ -1257,12 +1326,15 @@ func (x *CountDivergingCommitsRequest) GetMaxCount() int32 { return 0 } +// This comment is left unintentionally blank. type CountDivergingCommitsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - LeftCount int32 `protobuf:"varint,1,opt,name=left_count,json=leftCount,proto3" json:"left_count,omitempty"` + // This comment is left unintentionally blank. + LeftCount int32 `protobuf:"varint,1,opt,name=left_count,json=leftCount,proto3" json:"left_count,omitempty"` + // This comment is left unintentionally blank. RightCount int32 `protobuf:"varint,2,opt,name=right_count,json=rightCount,proto3" json:"right_count,omitempty"` } @@ -1312,6 +1384,7 @@ func (x *CountDivergingCommitsResponse) GetRightCount() int32 { return 0 } +// This comment is left unintentionally blank. type TreeEntry struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1322,7 +1395,8 @@ type TreeEntry struct { // OID of the tree attached to commit_oid RootOid string `protobuf:"bytes,2,opt,name=root_oid,json=rootOid,proto3" json:"root_oid,omitempty"` // Path relative to repository root - Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. Type TreeEntry_EntryType `protobuf:"varint,4,opt,name=type,proto3,enum=gitaly.TreeEntry_EntryType" json:"type,omitempty"` // File mode e.g. 0644 Mode int32 `protobuf:"varint,5,opt,name=mode,proto3" json:"mode,omitempty"` @@ -1413,19 +1487,27 @@ func (x *TreeEntry) GetFlatPath() []byte { return nil } +// This comment is left unintentionally blank. type GetTreeEntriesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - Recursive bool `protobuf:"varint,4,opt,name=recursive,proto3" json:"recursive,omitempty"` - Sort GetTreeEntriesRequest_SortBy `protobuf:"varint,5,opt,name=sort,proto3,enum=gitaly.GetTreeEntriesRequest_SortBy" json:"sort,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Recursive bool `protobuf:"varint,4,opt,name=recursive,proto3" json:"recursive,omitempty"` + // This comment is left unintentionally blank. + Sort GetTreeEntriesRequest_SortBy `protobuf:"varint,5,opt,name=sort,proto3,enum=gitaly.GetTreeEntriesRequest_SortBy" json:"sort,omitempty"` // The page token is the last commit OID that was sent. It's expected to be the // full object ID to guard against ambigious OIDs. PaginationParams *PaginationParameter `protobuf:"bytes,6,opt,name=pagination_params,json=paginationParams,proto3" json:"pagination_params,omitempty"` + // SkipFlatPath is an option to skip the expensive operation of populating flat paths. + SkipFlatPaths bool `protobuf:"varint,7,opt,name=skip_flat_paths,json=skipFlatPaths,proto3" json:"skip_flat_paths,omitempty"` } func (x *GetTreeEntriesRequest) Reset() { @@ -1502,12 +1584,22 @@ func (x *GetTreeEntriesRequest) GetPaginationParams() *PaginationParameter { return nil } +func (x *GetTreeEntriesRequest) GetSkipFlatPaths() bool { + if x != nil { + return x.SkipFlatPaths + } + return false +} + +// This comment is left unintentionally blank. type GetTreeEntriesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Entries []*TreeEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + // This comment is left unintentionally blank. + Entries []*TreeEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + // This comment is left unintentionally blank. PaginationCursor *PaginationCursor `protobuf:"bytes,2,opt,name=pagination_cursor,json=paginationCursor,proto3" json:"pagination_cursor,omitempty"` } @@ -1557,13 +1649,16 @@ func (x *GetTreeEntriesResponse) GetPaginationCursor() *PaginationCursor { return nil } +// This comment is left unintentionally blank. type ListFilesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` } func (x *ListFilesRequest) Reset() { @@ -1661,14 +1756,18 @@ func (x *ListFilesResponse) GetPaths() [][]byte { return nil } +// This comment is left unintentionally blank. type FindCommitRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Trailers bool `protobuf:"varint,3,opt,name=trailers,proto3" json:"trailers,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Trailers bool `protobuf:"varint,3,opt,name=trailers,proto3" json:"trailers,omitempty"` } func (x *FindCommitRequest) Reset() { @@ -1724,6 +1823,7 @@ func (x *FindCommitRequest) GetTrailers() bool { return false } +// This comment is left unintentionally blank. type FindCommitResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1772,13 +1872,16 @@ func (x *FindCommitResponse) GetCommit() *GitCommit { return nil } +// This comment is left unintentionally blank. type ListCommitsByOidRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Oid []string `protobuf:"bytes,2,rep,name=oid,proto3" json:"oid,omitempty"` + // This comment is left unintentionally blank. + Oid []string `protobuf:"bytes,2,rep,name=oid,proto3" json:"oid,omitempty"` // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED } func (x *ListCommitsByOidRequest) Reset() { @@ -1827,11 +1930,13 @@ func (x *ListCommitsByOidRequest) GetOid() []string { return nil } +// This comment is left unintentionally blank. type ListCommitsByOidResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commits []*GitCommit `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"` } @@ -1874,13 +1979,16 @@ func (x *ListCommitsByOidResponse) GetCommits() []*GitCommit { return nil } +// This comment is left unintentionally blank. type ListCommitsByRefNameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - RefNames [][]byte `protobuf:"bytes,2,rep,name=ref_names,json=refNames,proto3" json:"ref_names,omitempty"` + // This comment is left unintentionally blank. + RefNames [][]byte `protobuf:"bytes,2,rep,name=ref_names,json=refNames,proto3" json:"ref_names,omitempty"` } func (x *ListCommitsByRefNameRequest) Reset() { @@ -1929,11 +2037,13 @@ func (x *ListCommitsByRefNameRequest) GetRefNames() [][]byte { return nil } +// This comment is left unintentionally blank. type ListCommitsByRefNameResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. CommitRefs []*ListCommitsByRefNameResponse_CommitForRef `protobuf:"bytes,2,rep,name=commit_refs,json=commitRefs,proto3" json:"commit_refs,omitempty"` } @@ -1976,17 +2086,22 @@ func (x *ListCommitsByRefNameResponse) GetCommitRefs() []*ListCommitsByRefNameRe return nil } +// This comment is left unintentionally blank. type FindAllCommitsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // When nil, return all commits reachable by any branch in the repo - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - MaxCount int32 `protobuf:"varint,3,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` - Skip int32 `protobuf:"varint,4,opt,name=skip,proto3" json:"skip,omitempty"` - Order FindAllCommitsRequest_Order `protobuf:"varint,5,opt,name=order,proto3,enum=gitaly.FindAllCommitsRequest_Order" json:"order,omitempty"` + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + MaxCount int32 `protobuf:"varint,3,opt,name=max_count,json=maxCount,proto3" json:"max_count,omitempty"` + // This comment is left unintentionally blank. + Skip int32 `protobuf:"varint,4,opt,name=skip,proto3" json:"skip,omitempty"` + // This comment is left unintentionally blank. + Order FindAllCommitsRequest_Order `protobuf:"varint,5,opt,name=order,proto3,enum=gitaly.FindAllCommitsRequest_Order" json:"order,omitempty"` } func (x *FindAllCommitsRequest) Reset() { @@ -2062,6 +2177,7 @@ type FindAllCommitsResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commits []*GitCommit `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"` } @@ -2104,28 +2220,47 @@ func (x *FindAllCommitsResponse) GetCommits() []*GitCommit { return nil } +// This comment is left unintentionally blank. type FindCommitsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` - Offset int32 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"` - Paths [][]byte `protobuf:"bytes,5,rep,name=paths,proto3" json:"paths,omitempty"` - Follow bool `protobuf:"varint,6,opt,name=follow,proto3" json:"follow,omitempty"` - SkipMerges bool `protobuf:"varint,7,opt,name=skip_merges,json=skipMerges,proto3" json:"skip_merges,omitempty"` - DisableWalk bool `protobuf:"varint,8,opt,name=disable_walk,json=disableWalk,proto3" json:"disable_walk,omitempty"` - After *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=after,proto3" json:"after,omitempty"` - Before *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=before,proto3" json:"before,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + // This comment is left unintentionally blank. + Offset int32 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"` + // This comment is left unintentionally blank. + Paths [][]byte `protobuf:"bytes,5,rep,name=paths,proto3" json:"paths,omitempty"` + // This comment is left unintentionally blank. + Follow bool `protobuf:"varint,6,opt,name=follow,proto3" json:"follow,omitempty"` + // This comment is left unintentionally blank. + SkipMerges bool `protobuf:"varint,7,opt,name=skip_merges,json=skipMerges,proto3" json:"skip_merges,omitempty"` + // This comment is left unintentionally blank. + DisableWalk bool `protobuf:"varint,8,opt,name=disable_walk,json=disableWalk,proto3" json:"disable_walk,omitempty"` + // This comment is left unintentionally blank. + After *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=after,proto3" json:"after,omitempty"` + // This comment is left unintentionally blank. + Before *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=before,proto3" json:"before,omitempty"` // all and revision are mutually exclusive - All bool `protobuf:"varint,11,opt,name=all,proto3" json:"all,omitempty"` - FirstParent bool `protobuf:"varint,12,opt,name=first_parent,json=firstParent,proto3" json:"first_parent,omitempty"` - Author []byte `protobuf:"bytes,13,opt,name=author,proto3" json:"author,omitempty"` - Order FindCommitsRequest_Order `protobuf:"varint,14,opt,name=order,proto3,enum=gitaly.FindCommitsRequest_Order" json:"order,omitempty"` - GlobalOptions *GlobalOptions `protobuf:"bytes,15,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` - Trailers bool `protobuf:"varint,16,opt,name=trailers,proto3" json:"trailers,omitempty"` + All bool `protobuf:"varint,11,opt,name=all,proto3" json:"all,omitempty"` + // This comment is left unintentionally blank. + FirstParent bool `protobuf:"varint,12,opt,name=first_parent,json=firstParent,proto3" json:"first_parent,omitempty"` + // This comment is left unintentionally blank. + Author []byte `protobuf:"bytes,13,opt,name=author,proto3" json:"author,omitempty"` + // This comment is left unintentionally blank. + Order FindCommitsRequest_Order `protobuf:"varint,14,opt,name=order,proto3,enum=gitaly.FindCommitsRequest_Order" json:"order,omitempty"` + // This comment is left unintentionally blank. + GlobalOptions *GlobalOptions `protobuf:"bytes,15,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` + // This comment is left unintentionally blank. + Trailers bool `protobuf:"varint,16,opt,name=trailers,proto3" json:"trailers,omitempty"` + // include_shortstat determines whether to include the number of lines and files + // changed in the commits. Populates the `short_stats` field. + IncludeShortstat bool `protobuf:"varint,17,opt,name=include_shortstat,json=includeShortstat,proto3" json:"include_shortstat,omitempty"` } func (x *FindCommitsRequest) Reset() { @@ -2272,12 +2407,20 @@ func (x *FindCommitsRequest) GetTrailers() bool { return false } +func (x *FindCommitsRequest) GetIncludeShortstat() bool { + if x != nil { + return x.IncludeShortstat + } + return false +} + // A single 'page' of the result set type FindCommitsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commits []*GitCommit `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"` } @@ -2320,13 +2463,17 @@ func (x *FindCommitsResponse) GetCommits() []*GitCommit { return nil } +// CommitLanguagesRequest requests to detect the source code languages. type CommitLanguagesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Repository is the repository where to detect the languages in. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // Revision tells for which commit the languages should be detected. If it's + // omitted, the HEAD commit of the default branch is used. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` } func (x *CommitLanguagesRequest) Reset() { @@ -2375,11 +2522,13 @@ func (x *CommitLanguagesRequest) GetRevision() []byte { return nil } +// CommitLanguagesResponse returns the language statistics. type CommitLanguagesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Languages is a set of all the detected languages and their statistics. Languages []*CommitLanguagesResponse_Language `protobuf:"bytes,1,rep,name=languages,proto3" json:"languages,omitempty"` } @@ -2422,14 +2571,18 @@ func (x *CommitLanguagesResponse) GetLanguages() []*CommitLanguagesResponse_Lang return nil } +// This comment is left unintentionally blank. type RawBlameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` // Comma-separated range of line numbers to perform the blame on: "1,1000". // Optional - if no range is provided, the whole file will be blamed. Range []byte `protobuf:"bytes,4,opt,name=range,proto3" json:"range,omitempty"` @@ -2495,11 +2648,13 @@ func (x *RawBlameRequest) GetRange() []byte { return nil } +// This comment is left unintentionally blank. type RawBlameResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } @@ -2542,16 +2697,24 @@ func (x *RawBlameResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type LastCommitForPathRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - LiteralPathspec bool `protobuf:"varint,4,opt,name=literal_pathspec,json=literalPathspec,proto3" json:"literal_pathspec,omitempty"` // Deprecate after Rails stops using this - GlobalOptions *GlobalOptions `protobuf:"bytes,5,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + // This comment is left unintentionally blank. + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + LiteralPathspec bool `protobuf:"varint,4,opt,name=literal_pathspec,json=literalPathspec,proto3" json:"literal_pathspec,omitempty"` // Deprecate after Rails stops using this + // This comment is left unintentionally blank. + GlobalOptions *GlobalOptions `protobuf:"bytes,5,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` } func (x *LastCommitForPathRequest) Reset() { @@ -2621,6 +2784,7 @@ func (x *LastCommitForPathRequest) GetGlobalOptions() *GlobalOptions { return nil } +// This comment is left unintentionally blank. type LastCommitForPathResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2669,19 +2833,28 @@ func (x *LastCommitForPathResponse) GetCommit() *GitCommit { return nil } +// This comment is left unintentionally blank. type ListLastCommitsForTreeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` - Offset int32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + // This comment is left unintentionally blank. + Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + // This comment is left unintentionally blank. + Offset int32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + // This comment is left unintentionally blank. + // // Deprecated: Do not use. - LiteralPathspec bool `protobuf:"varint,6,opt,name=literal_pathspec,json=literalPathspec,proto3" json:"literal_pathspec,omitempty"` - GlobalOptions *GlobalOptions `protobuf:"bytes,7,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` + LiteralPathspec bool `protobuf:"varint,6,opt,name=literal_pathspec,json=literalPathspec,proto3" json:"literal_pathspec,omitempty"` + // This comment is left unintentionally blank. + GlobalOptions *GlobalOptions `protobuf:"bytes,7,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` } func (x *ListLastCommitsForTreeRequest) Reset() { @@ -2766,11 +2939,13 @@ func (x *ListLastCommitsForTreeRequest) GetGlobalOptions() *GlobalOptions { return nil } +// This comment is left unintentionally blank. type ListLastCommitsForTreeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commits []*ListLastCommitsForTreeResponse_CommitForTree `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"` } @@ -2813,17 +2988,25 @@ func (x *ListLastCommitsForTreeResponse) GetCommits() []*ListLastCommitsForTreeR return nil } +// This comment is left unintentionally blank. type CommitsByMessageRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` - Offset int32 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"` - Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` - Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` - Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Offset int32 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"` + // This comment is left unintentionally blank. + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"` + // This comment is left unintentionally blank. GlobalOptions *GlobalOptions `protobuf:"bytes,7,opt,name=global_options,json=globalOptions,proto3" json:"global_options,omitempty"` } @@ -2914,6 +3097,7 @@ type CommitsByMessageResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commits []*GitCommit `protobuf:"bytes,1,rep,name=commits,proto3" json:"commits,omitempty"` } @@ -2956,13 +3140,16 @@ func (x *CommitsByMessageResponse) GetCommits() []*GitCommit { return nil } +// This comment is left unintentionally blank. type FilterShasWithSignaturesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Shas [][]byte `protobuf:"bytes,2,rep,name=shas,proto3" json:"shas,omitempty"` + // This comment is left unintentionally blank. + Shas [][]byte `protobuf:"bytes,2,rep,name=shas,proto3" json:"shas,omitempty"` } func (x *FilterShasWithSignaturesRequest) Reset() { @@ -3011,11 +3198,13 @@ func (x *FilterShasWithSignaturesRequest) GetShas() [][]byte { return nil } +// This comment is left unintentionally blank. type FilterShasWithSignaturesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Shas [][]byte `protobuf:"bytes,1,rep,name=shas,proto3" json:"shas,omitempty"` } @@ -3058,13 +3247,16 @@ func (x *FilterShasWithSignaturesResponse) GetShas() [][]byte { return nil } +// This comment is left unintentionally blank. type ExtractCommitSignatureRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + // This comment is left unintentionally blank. + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` } func (x *ExtractCommitSignatureRequest) Reset() { @@ -3120,7 +3312,9 @@ type ExtractCommitSignatureResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + // This comment is left unintentionally blank. + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + // This comment is left unintentionally blank. SignedText []byte `protobuf:"bytes,2,opt,name=signed_text,json=signedText,proto3" json:"signed_text,omitempty"` } @@ -3170,13 +3364,16 @@ func (x *ExtractCommitSignatureResponse) GetSignedText() []byte { return nil } +// This comment is left unintentionally blank. type GetCommitSignaturesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitIds []string `protobuf:"bytes,2,rep,name=commit_ids,json=commitIds,proto3" json:"commit_ids,omitempty"` + // This comment is left unintentionally blank. + CommitIds []string `protobuf:"bytes,2,rep,name=commit_ids,json=commitIds,proto3" json:"commit_ids,omitempty"` } func (x *GetCommitSignaturesRequest) Reset() { @@ -3225,6 +3422,7 @@ func (x *GetCommitSignaturesRequest) GetCommitIds() []string { return nil } +// This comment is left unintentionally blank. type GetCommitSignaturesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3233,7 +3431,8 @@ type GetCommitSignaturesResponse struct { // Only present for a new commit signature data. CommitId string `protobuf:"bytes,1,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` // See ExtractCommitSignatureResponse above for how these fields should be handled. - Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + // This comment is left unintentionally blank. SignedText []byte `protobuf:"bytes,3,opt,name=signed_text,json=signedText,proto3" json:"signed_text,omitempty"` } @@ -3290,13 +3489,16 @@ func (x *GetCommitSignaturesResponse) GetSignedText() []byte { return nil } +// This comment is left unintentionally blank. type GetCommitMessagesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitIds []string `protobuf:"bytes,2,rep,name=commit_ids,json=commitIds,proto3" json:"commit_ids,omitempty"` + // This comment is left unintentionally blank. + CommitIds []string `protobuf:"bytes,2,rep,name=commit_ids,json=commitIds,proto3" json:"commit_ids,omitempty"` } func (x *GetCommitMessagesRequest) Reset() { @@ -3345,6 +3547,7 @@ func (x *GetCommitMessagesRequest) GetCommitIds() []string { return nil } +// This comment is left unintentionally blank. type GetCommitMessagesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3352,7 +3555,8 @@ type GetCommitMessagesResponse struct { // Only present for a new commit message CommitId string `protobuf:"bytes,1,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + // This comment is left unintentionally blank. + Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` } func (x *GetCommitMessagesResponse) Reset() { @@ -3401,7 +3605,9 @@ func (x *GetCommitMessagesResponse) GetMessage() []byte { return nil } -// CheckObjectsExistRequest is a request for the CheckObjectsExist RPC. +// CheckObjectsExistRequest is a request for the CheckObjectsExist RPC. Only +// the initial request must contain a repository, the repository of all +// subsequent requests will be ignored. type CheckObjectsExistRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3461,11 +3667,13 @@ func (x *CheckObjectsExistRequest) GetRevisions() [][]byte { return nil } +// This comment is left unintentionally blank. type CheckObjectsExistResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Revisions []*CheckObjectsExistResponse_RevisionExistence `protobuf:"bytes,1,rep,name=revisions,proto3" json:"revisions,omitempty"` } @@ -3508,13 +3716,16 @@ func (x *CheckObjectsExistResponse) GetRevisions() []*CheckObjectsExistResponse_ return nil } +// This comment is left unintentionally blank. type ListCommitsByRefNameResponse_CommitForRef struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Commit *GitCommit `protobuf:"bytes,1,opt,name=commit,proto3" json:"commit,omitempty"` - RefName []byte `protobuf:"bytes,2,opt,name=ref_name,json=refName,proto3" json:"ref_name,omitempty"` + // This comment is left unintentionally blank. + Commit *GitCommit `protobuf:"bytes,1,opt,name=commit,proto3" json:"commit,omitempty"` + // This comment is left unintentionally blank. + RefName []byte `protobuf:"bytes,2,opt,name=ref_name,json=refName,proto3" json:"ref_name,omitempty"` } func (x *ListCommitsByRefNameResponse_CommitForRef) Reset() { @@ -3563,16 +3774,25 @@ func (x *ListCommitsByRefNameResponse_CommitForRef) GetRefName() []byte { return nil } +// Language specifies the statistics for one language. type CommitLanguagesResponse_Language struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Share float32 `protobuf:"fixed32,2,opt,name=share,proto3" json:"share,omitempty"` - Color string `protobuf:"bytes,3,opt,name=color,proto3" json:"color,omitempty"` - FileCount uint32 `protobuf:"varint,4,opt,name=file_count,json=fileCount,proto3" json:"file_count,omitempty"` - Bytes uint64 `protobuf:"varint,5,opt,name=bytes,proto3" json:"bytes,omitempty"` + // Name is the name of the detected language, for example: Ruby, Go, HTML + // A full list of language names can be found at: + // https://github.com/github/linguist/blob/master/lib/linguist/languages.yml + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Share is the percentual share (value between 0 and 100) of this language + // in relation to other languages that exist in the given revision. + Share float32 `protobuf:"fixed32,2,opt,name=share,proto3" json:"share,omitempty"` + // Color specifies the associated color for this language, for example #3fd5e0. + Color string `protobuf:"bytes,3,opt,name=color,proto3" json:"color,omitempty"` + // FileCount tells how many files with this language are found. + FileCount uint32 `protobuf:"varint,4,opt,name=file_count,json=fileCount,proto3" json:"file_count,omitempty"` + // Bytes is the total amount of bytes written in this language + Bytes uint64 `protobuf:"varint,5,opt,name=bytes,proto3" json:"bytes,omitempty"` } func (x *CommitLanguagesResponse_Language) Reset() { @@ -3642,13 +3862,16 @@ func (x *CommitLanguagesResponse_Language) GetBytes() uint64 { return 0 } +// This comment is left unintentionally blank. type ListLastCommitsForTreeResponse_CommitForTree struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Commit *GitCommit `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` - PathBytes []byte `protobuf:"bytes,4,opt,name=path_bytes,json=pathBytes,proto3" json:"path_bytes,omitempty"` + // This comment is left unintentionally blank. + Commit *GitCommit `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` + // This comment is left unintentionally blank. + PathBytes []byte `protobuf:"bytes,4,opt,name=path_bytes,json=pathBytes,proto3" json:"path_bytes,omitempty"` } func (x *ListLastCommitsForTreeResponse_CommitForTree) Reset() { @@ -3697,13 +3920,16 @@ func (x *ListLastCommitsForTreeResponse_CommitForTree) GetPathBytes() []byte { return nil } +// This comment is left unintentionally blank. type CheckObjectsExistResponse_RevisionExistence struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Exists bool `protobuf:"varint,2,opt,name=exists,proto3" json:"exists,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Exists bool `protobuf:"varint,2,opt,name=exists,proto3" json:"exists,omitempty"` } func (x *CheckObjectsExistResponse_RevisionExistence) Reset() { @@ -3756,11 +3982,11 @@ var File_commit_proto protoreflect.FileDescriptor var file_commit_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x94, 0x04, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xed, 0x04, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, @@ -3791,598 +4017,609 @@ var file_commit_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x22, 0x25, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, - 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x12, 0x08, - 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x22, 0x42, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x9b, 0x01, 0x0a, - 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, - 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x45, 0x0a, 0x16, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, - 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x73, 0x22, 0x6a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x63, 0x0a, - 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x8f, 0x01, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, - 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, - 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xd2, 0x01, 0x0a, 0x11, 0x54, 0x72, 0x65, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x22, 0x35, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, - 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x03, 0x22, 0xf5, 0x02, 0x0a, 0x13, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x18, 0x03, 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, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, - 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x04, 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, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, - 0x6c, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x2c, 0x0a, 0x14, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0xab, 0x01, 0x0a, 0x1c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, - 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, - 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, - 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x04, 0x08, - 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, - 0x5f, 0x0a, 0x1d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, 0x65, 0x66, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x1f, 0x0a, 0x0b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0xfa, 0x01, 0x0a, 0x09, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, - 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, - 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, - 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x4f, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x61, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x6c, 0x61, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x22, 0x2b, 0x0a, 0x09, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, - 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, 0x10, - 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x22, 0xcb, 0x02, - 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x12, - 0x38, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, - 0x74, 0x42, 0x79, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x06, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, + 0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x0d, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x22, 0x25, 0x0a, 0x05, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, + 0x02, 0x22, 0x42, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x9b, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, + 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x22, 0x26, 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x0b, 0x0a, - 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x52, - 0x45, 0x45, 0x53, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x22, 0x8c, 0x01, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x68, 0x0a, 0x10, 0x4c, 0x69, - 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, - 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, - 0x85, 0x01, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, - 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, - 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x3f, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, - 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x65, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x22, - 0x47, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, - 0x4f, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x74, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xce, - 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, - 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x52, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, - 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x66, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x65, 0x66, 0x73, 0x1a, 0x54, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, - 0x52, 0x65, 0x66, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x72, 0x65, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x72, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, - 0x80, 0x02, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x6b, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, - 0x12, 0x39, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x25, 0x0a, 0x05, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, - 0x10, 0x02, 0x22, 0x45, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0xec, 0x04, 0x0a, 0x12, 0x46, 0x69, - 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x73, 0x22, 0x45, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x6a, 0x0a, 0x12, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, - 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6d, 0x65, 0x72, 0x67, 0x65, - 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x4d, 0x65, 0x72, - 0x67, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x77, - 0x61, 0x6c, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x57, 0x61, 0x6c, 0x6b, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, - 0x09, 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, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, - 0x72, 0x65, 0x18, 0x0a, 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, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x61, 0x6c, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x21, - 0x0a, 0x0c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x05, 0x6f, 0x72, 0x64, - 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, - 0x72, 0x12, 0x3c, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x0d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x1b, 0x0a, 0x05, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x22, 0x42, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x16, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x63, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8f, 0x01, 0x0a, 0x17, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x22, 0x30, 0x0a, + 0x18, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0xad, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x22, + 0xd2, 0x01, 0x0a, 0x11, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x35, 0x0a, + 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x43, + 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, + 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x54, + 0x41, 0x47, 0x10, 0x03, 0x22, 0xf5, 0x02, 0x0a, 0x13, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x03, 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, 0x05, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x04, + 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, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, + 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x3c, + 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2c, 0x0a, 0x14, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xab, 0x01, 0x0a, 0x1c, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, + 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, + 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x5f, 0x0a, 0x1d, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x65, 0x66, + 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, + 0x65, 0x66, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xfa, 0x01, 0x0a, 0x09, 0x54, 0x72, + 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6f, + 0x74, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, + 0x74, 0x4f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4f, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x66, 0x6c, 0x61, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x66, 0x6c, 0x61, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0x2b, 0x0a, 0x09, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, + 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x22, 0xf3, 0x02, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x72, + 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, + 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, + 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x04, 0x73, 0x6f, + 0x72, 0x74, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0f, + 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x6c, 0x61, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x6c, 0x61, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x73, 0x22, 0x26, 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x0b, + 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, + 0x52, 0x45, 0x45, 0x53, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x22, 0x8c, 0x01, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x68, 0x0a, 0x10, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, + 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, + 0x22, 0x85, 0x01, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe2, 0x01, 0x0a, - 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x6c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, - 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x52, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, - 0x1a, 0x7f, 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, - 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xed, 0x01, - 0x0a, 0x18, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, - 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x3f, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, + 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x65, 0x0a, 0x17, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, + 0x22, 0x47, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, + 0x79, 0x4f, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x74, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, + 0xce, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, + 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x52, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, + 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x66, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x66, 0x73, 0x1a, 0x54, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, + 0x72, 0x52, 0x65, 0x66, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, + 0x19, 0x0a, 0x08, 0x72, 0x65, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x72, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, + 0x22, 0x80, 0x02, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, - 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x12, - 0x3c, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, - 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x46, 0x0a, - 0x19, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, - 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0xa4, 0x02, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, - 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, - 0x2d, 0x0a, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, - 0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x6c, - 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3c, - 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd7, 0x01, 0x0a, - 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x34, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, - 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, - 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x1a, - 0x65, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, - 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, - 0x61, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x70, 0x61, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x3c, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x0d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x47, - 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x1f, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x04, 0x73, 0x68, 0x61, 0x73, 0x22, 0x36, 0x0a, 0x20, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x68, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x68, 0x61, 0x73, - 0x22, 0x76, 0x0a, 0x1d, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x6b, 0x69, + 0x70, 0x12, 0x39, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x25, 0x0a, 0x05, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, + 0x08, 0x0a, 0x04, 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, + 0x45, 0x10, 0x02, 0x22, 0x45, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x99, 0x05, 0x0a, 0x12, 0x46, + 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x1e, 0x45, 0x78, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x22, 0x75, 0x0a, 0x1a, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x73, - 0x22, 0x79, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x22, 0x73, 0x0a, 0x18, 0x47, - 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x73, - 0x22, 0x52, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x72, 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, + 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6d, 0x65, 0x72, 0x67, + 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x77, 0x61, 0x6c, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x57, 0x61, 0x6c, 0x6b, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x18, 0x09, 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, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x18, 0x0a, 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, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, + 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x05, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x11, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x73, 0x74, 0x61, + 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x53, 0x68, 0x6f, 0x72, 0x74, 0x73, 0x74, 0x61, 0x74, 0x22, 0x1b, 0x0a, 0x05, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x54, 0x4f, 0x50, 0x4f, 0x10, 0x01, 0x22, 0x42, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x16, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe2, 0x01, 0x0a, 0x17, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x52, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x7f, + 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, + 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, + 0x91, 0x01, 0x0a, 0x0f, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, + 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, + 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xed, 0x01, 0x0a, 0x18, + 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3c, 0x0a, + 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x46, 0x0a, 0x19, 0x4c, + 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x22, 0xa4, 0x02, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2d, 0x0a, + 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, + 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x6c, 0x69, 0x74, + 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3c, 0x0a, 0x0e, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd7, 0x01, 0x0a, 0x1e, 0x4c, + 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, + 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, + 0x54, 0x72, 0x65, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x1a, 0x65, 0x0a, + 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x12, 0x29, + 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, + 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, + 0x61, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, + 0x08, 0x03, 0x10, 0x04, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, + 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x72, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xaf, 0x01, 0x0a, 0x19, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, - 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x52, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x32, 0xf1, 0x10, 0x0a, 0x0d, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0b, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x59, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, - 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4a, 0x0a, 0x09, 0x54, 0x72, 0x65, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, - 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x6c, 0x0a, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, - 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x59, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, - 0x12, 0x4a, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x0a, - 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, - 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x59, 0x0a, 0x0e, 0x46, 0x69, 0x6e, - 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, - 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x12, 0x47, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x12, 0x17, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x60, 0x0a, 0x11, 0x4c, - 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, - 0x12, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x61, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x71, 0x0a, - 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x12, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, - 0x12, 0x5f, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, - 0x01, 0x12, 0x5f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x42, 0x79, 0x4f, 0x69, 0x64, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, - 0x30, 0x01, 0x12, 0x6b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, - 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, - 0x79, 0x0a, 0x18, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, - 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, - 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x68, 0x0a, 0x13, 0x47, 0x65, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x3c, + 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x47, 0x0a, 0x18, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x1f, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, + 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x04, 0x73, 0x68, 0x61, 0x73, 0x22, 0x36, 0x0a, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, + 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x68, 0x61, 0x73, 0x22, 0x76, + 0x0a, 0x1d, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x1e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x22, 0x75, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, - 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x73, 0x22, 0x79, + 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x22, 0x73, 0x0a, 0x18, 0x47, 0x65, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x73, 0x22, 0x52, + 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x72, 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xaf, 0x01, 0x0a, 0x19, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x52, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x32, 0xf1, 0x10, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x0e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1d, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x49, 0x73, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x73, 0x41, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, + 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4a, 0x0a, 0x09, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x30, 0x01, 0x12, 0x51, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x6c, 0x0a, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, + 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x24, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, + 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x12, 0x59, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, + 0x74, 0x54, 0x72, 0x65, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4a, + 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x46, 0x69, + 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x59, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x02, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x12, 0x47, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x61, 0x77, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x60, 0x0a, 0x11, 0x4c, 0x61, 0x73, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x71, 0x0a, 0x16, 0x4c, + 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, + 0x72, 0x54, 0x72, 0x65, 0x65, 0x12, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, + 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5f, + 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, + 0x5f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, + 0x4f, 0x69, 0x64, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x4f, 0x69, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, + 0x12, 0x6b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, + 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x42, 0x79, 0x52, + 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x73, 0x42, 0x79, 0x52, 0x65, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x79, 0x0a, + 0x18, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, + 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x53, 0x68, 0x61, 0x73, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, + 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x68, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, + 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x64, 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x12, 0x20, 0x2e, + 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, + 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x64, 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, - 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, - 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, - 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x74, 0x73, 0x45, 0x78, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, + 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, + 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit_grpc.pb.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit_grpc.pb.go index 0e1f603bde..4fb2773d28 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/commit_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/commit_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: commit.proto package gitalypb @@ -25,26 +29,46 @@ type CommitServiceClient interface { // ListAllCommits lists all commits present in the repository, including // those not reachable by any reference. ListAllCommits(ctx context.Context, in *ListAllCommitsRequest, opts ...grpc.CallOption) (CommitService_ListAllCommitsClient, error) + // This comment is left unintentionally blank. CommitIsAncestor(ctx context.Context, in *CommitIsAncestorRequest, opts ...grpc.CallOption) (*CommitIsAncestorResponse, error) + // This comment is left unintentionally blank. TreeEntry(ctx context.Context, in *TreeEntryRequest, opts ...grpc.CallOption) (CommitService_TreeEntryClient, error) + // This comment is left unintentionally blank. CountCommits(ctx context.Context, in *CountCommitsRequest, opts ...grpc.CallOption) (*CountCommitsResponse, error) + // This comment is left unintentionally blank. CountDivergingCommits(ctx context.Context, in *CountDivergingCommitsRequest, opts ...grpc.CallOption) (*CountDivergingCommitsResponse, error) + // This comment is left unintentionally blank. GetTreeEntries(ctx context.Context, in *GetTreeEntriesRequest, opts ...grpc.CallOption) (CommitService_GetTreeEntriesClient, error) + // This comment is left unintentionally blank. ListFiles(ctx context.Context, in *ListFilesRequest, opts ...grpc.CallOption) (CommitService_ListFilesClient, error) + // This comment is left unintentionally blank. FindCommit(ctx context.Context, in *FindCommitRequest, opts ...grpc.CallOption) (*FindCommitResponse, error) + // This comment is left unintentionally blank. CommitStats(ctx context.Context, in *CommitStatsRequest, opts ...grpc.CallOption) (*CommitStatsResponse, error) // Use a stream to paginate the result set FindAllCommits(ctx context.Context, in *FindAllCommitsRequest, opts ...grpc.CallOption) (CommitService_FindAllCommitsClient, error) + // This comment is left unintentionally blank. FindCommits(ctx context.Context, in *FindCommitsRequest, opts ...grpc.CallOption) (CommitService_FindCommitsClient, error) + // CommitLanguages detects the source code languages of the whole tree for a + // given commit. Returns an error in case no languages could be detected. CommitLanguages(ctx context.Context, in *CommitLanguagesRequest, opts ...grpc.CallOption) (*CommitLanguagesResponse, error) + // This comment is left unintentionally blank. RawBlame(ctx context.Context, in *RawBlameRequest, opts ...grpc.CallOption) (CommitService_RawBlameClient, error) + // This comment is left unintentionally blank. LastCommitForPath(ctx context.Context, in *LastCommitForPathRequest, opts ...grpc.CallOption) (*LastCommitForPathResponse, error) + // This comment is left unintentionally blank. ListLastCommitsForTree(ctx context.Context, in *ListLastCommitsForTreeRequest, opts ...grpc.CallOption) (CommitService_ListLastCommitsForTreeClient, error) + // This comment is left unintentionally blank. CommitsByMessage(ctx context.Context, in *CommitsByMessageRequest, opts ...grpc.CallOption) (CommitService_CommitsByMessageClient, error) + // This comment is left unintentionally blank. ListCommitsByOid(ctx context.Context, in *ListCommitsByOidRequest, opts ...grpc.CallOption) (CommitService_ListCommitsByOidClient, error) + // This comment is left unintentionally blank. ListCommitsByRefName(ctx context.Context, in *ListCommitsByRefNameRequest, opts ...grpc.CallOption) (CommitService_ListCommitsByRefNameClient, error) + // This comment is left unintentionally blank. FilterShasWithSignatures(ctx context.Context, opts ...grpc.CallOption) (CommitService_FilterShasWithSignaturesClient, error) + // This comment is left unintentionally blank. GetCommitSignatures(ctx context.Context, in *GetCommitSignaturesRequest, opts ...grpc.CallOption) (CommitService_GetCommitSignaturesClient, error) + // This comment is left unintentionally blank. GetCommitMessages(ctx context.Context, in *GetCommitMessagesRequest, opts ...grpc.CallOption) (CommitService_GetCommitMessagesClient, error) // CheckObjectsExist will check for the existence of revisions against a // repository. It returns two sets of data. An array containing the revisions @@ -645,26 +669,46 @@ type CommitServiceServer interface { // ListAllCommits lists all commits present in the repository, including // those not reachable by any reference. ListAllCommits(*ListAllCommitsRequest, CommitService_ListAllCommitsServer) error + // This comment is left unintentionally blank. CommitIsAncestor(context.Context, *CommitIsAncestorRequest) (*CommitIsAncestorResponse, error) + // This comment is left unintentionally blank. TreeEntry(*TreeEntryRequest, CommitService_TreeEntryServer) error + // This comment is left unintentionally blank. CountCommits(context.Context, *CountCommitsRequest) (*CountCommitsResponse, error) + // This comment is left unintentionally blank. CountDivergingCommits(context.Context, *CountDivergingCommitsRequest) (*CountDivergingCommitsResponse, error) + // This comment is left unintentionally blank. GetTreeEntries(*GetTreeEntriesRequest, CommitService_GetTreeEntriesServer) error + // This comment is left unintentionally blank. ListFiles(*ListFilesRequest, CommitService_ListFilesServer) error + // This comment is left unintentionally blank. FindCommit(context.Context, *FindCommitRequest) (*FindCommitResponse, error) + // This comment is left unintentionally blank. CommitStats(context.Context, *CommitStatsRequest) (*CommitStatsResponse, error) // Use a stream to paginate the result set FindAllCommits(*FindAllCommitsRequest, CommitService_FindAllCommitsServer) error + // This comment is left unintentionally blank. FindCommits(*FindCommitsRequest, CommitService_FindCommitsServer) error + // CommitLanguages detects the source code languages of the whole tree for a + // given commit. Returns an error in case no languages could be detected. CommitLanguages(context.Context, *CommitLanguagesRequest) (*CommitLanguagesResponse, error) + // This comment is left unintentionally blank. RawBlame(*RawBlameRequest, CommitService_RawBlameServer) error + // This comment is left unintentionally blank. LastCommitForPath(context.Context, *LastCommitForPathRequest) (*LastCommitForPathResponse, error) + // This comment is left unintentionally blank. ListLastCommitsForTree(*ListLastCommitsForTreeRequest, CommitService_ListLastCommitsForTreeServer) error + // This comment is left unintentionally blank. CommitsByMessage(*CommitsByMessageRequest, CommitService_CommitsByMessageServer) error + // This comment is left unintentionally blank. ListCommitsByOid(*ListCommitsByOidRequest, CommitService_ListCommitsByOidServer) error + // This comment is left unintentionally blank. ListCommitsByRefName(*ListCommitsByRefNameRequest, CommitService_ListCommitsByRefNameServer) error + // This comment is left unintentionally blank. FilterShasWithSignatures(CommitService_FilterShasWithSignaturesServer) error + // This comment is left unintentionally blank. GetCommitSignatures(*GetCommitSignaturesRequest, CommitService_GetCommitSignaturesServer) error + // This comment is left unintentionally blank. GetCommitMessages(*GetCommitMessagesRequest, CommitService_GetCommitMessagesServer) error // CheckObjectsExist will check for the existence of revisions against a // repository. It returns two sets of data. An array containing the revisions diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts.pb.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts.pb.go index ece9943b5b..669e0c2e42 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: conflicts.proto package gitalypb @@ -21,14 +21,18 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type ListConflictFilesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - OurCommitOid string `protobuf:"bytes,2,opt,name=our_commit_oid,json=ourCommitOid,proto3" json:"our_commit_oid,omitempty"` - TheirCommitOid string `protobuf:"bytes,3,opt,name=their_commit_oid,json=theirCommitOid,proto3" json:"their_commit_oid,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + OurCommitOid string `protobuf:"bytes,2,opt,name=our_commit_oid,json=ourCommitOid,proto3" json:"our_commit_oid,omitempty"` + // This comment is left unintentionally blank. + TheirCommitOid string `protobuf:"bytes,3,opt,name=their_commit_oid,json=theirCommitOid,proto3" json:"their_commit_oid,omitempty"` // AllowTreeConflicts will not cause the request to fail in case there are // tree conflicts. If set to true, then responses may contain conflict files // where some of the paths are unset. @@ -95,15 +99,21 @@ func (x *ListConflictFilesRequest) GetAllowTreeConflicts() bool { return false } +// This comment is left unintentionally blank. type ConflictFileHeader struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - CommitOid string `protobuf:"bytes,2,opt,name=commit_oid,json=commitOid,proto3" json:"commit_oid,omitempty"` - TheirPath []byte `protobuf:"bytes,3,opt,name=their_path,json=theirPath,proto3" json:"their_path,omitempty"` - OurPath []byte `protobuf:"bytes,4,opt,name=our_path,json=ourPath,proto3" json:"our_path,omitempty"` - OurMode int32 `protobuf:"varint,5,opt,name=our_mode,json=ourMode,proto3" json:"our_mode,omitempty"` + // This comment is left unintentionally blank. + CommitOid string `protobuf:"bytes,2,opt,name=commit_oid,json=commitOid,proto3" json:"commit_oid,omitempty"` + // This comment is left unintentionally blank. + TheirPath []byte `protobuf:"bytes,3,opt,name=their_path,json=theirPath,proto3" json:"their_path,omitempty"` + // This comment is left unintentionally blank. + OurPath []byte `protobuf:"bytes,4,opt,name=our_path,json=ourPath,proto3" json:"our_path,omitempty"` + // This comment is left unintentionally blank. + OurMode int32 `protobuf:"varint,5,opt,name=our_mode,json=ourMode,proto3" json:"our_mode,omitempty"` + // This comment is left unintentionally blank. AncestorPath []byte `protobuf:"bytes,6,opt,name=ancestor_path,json=ancestorPath,proto3" json:"ancestor_path,omitempty"` } @@ -174,6 +184,7 @@ func (x *ConflictFileHeader) GetAncestorPath() []byte { return nil } +// This comment is left unintentionally blank. type ConflictFile struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -243,10 +254,12 @@ type isConflictFile_ConflictFilePayload interface { } type ConflictFile_Header struct { + // This comment is left unintentionally blank. Header *ConflictFileHeader `protobuf:"bytes,1,opt,name=header,proto3,oneof"` } type ConflictFile_Content struct { + // This comment is left unintentionally blank. Content []byte `protobuf:"bytes,2,opt,name=content,proto3,oneof"` } @@ -254,11 +267,13 @@ func (*ConflictFile_Header) isConflictFile_ConflictFilePayload() {} func (*ConflictFile_Content) isConflictFile_ConflictFilePayload() {} +// This comment is left unintentionally blank. type ListConflictFilesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Files []*ConflictFile `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` } @@ -574,10 +589,10 @@ var File_conflicts_proto protoreflect.FileDescriptor var file_conflicts_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, @@ -673,7 +688,7 @@ var file_conflicts_proto_rawDesc = []byte{ 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts_grpc.pb.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts_grpc.pb.go index ec73fb129e..f34d69e2c1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/conflicts_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/conflicts_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: conflicts.proto package gitalypb @@ -18,6 +22,8 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ConflictsServiceClient interface { + // ListConflictFiles returns all conflicting files which result from a merge + // of two specified commit objects. ListConflictFiles(ctx context.Context, in *ListConflictFilesRequest, opts ...grpc.CallOption) (ConflictsService_ListConflictFilesClient, error) // ResolveConflicts tries to resolve a conflicting merge with a set of // user-provided merge resolutions. If resolving the conflict succeeds, the @@ -103,6 +109,8 @@ func (x *conflictsServiceResolveConflictsClient) CloseAndRecv() (*ResolveConflic // All implementations must embed UnimplementedConflictsServiceServer // for forward compatibility type ConflictsServiceServer interface { + // ListConflictFiles returns all conflicting files which result from a merge + // of two specified commit objects. ListConflictFiles(*ListConflictFilesRequest, ConflictsService_ListConflictFilesServer) error // ResolveConflicts tries to resolve a conflicting merge with a set of // user-provided merge resolutions. If resolving the conflict succeeds, the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff.pb.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff.pb.go index 2fa9602ad8..03b122eb41 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: diff.proto package gitalypb @@ -20,13 +20,14 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type CommitDiffRequest_DiffMode int32 const ( // DEFAULT is the standard diff mode and results in a linewise diff for textfiles. - CommitDiffRequest_DEFAULT CommitDiffRequest_DiffMode = 0 + CommitDiffRequest_DEFAULT CommitDiffRequest_DiffMode = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // WORDDIFF is a word diff and computes the diff for whitespace separated words instead of for whole lines. - CommitDiffRequest_WORDDIFF CommitDiffRequest_DiffMode = 1 + CommitDiffRequest_WORDDIFF CommitDiffRequest_DiffMode = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for CommitDiffRequest_DiffMode. @@ -68,14 +69,20 @@ func (CommitDiffRequest_DiffMode) EnumDescriptor() ([]byte, []int) { return file_diff_proto_rawDescGZIP(), []int{0, 0} } +// This comment is left unintentionally blank. type ChangedPaths_Status int32 const ( - ChangedPaths_ADDED ChangedPaths_Status = 0 - ChangedPaths_MODIFIED ChangedPaths_Status = 1 - ChangedPaths_DELETED ChangedPaths_Status = 2 - ChangedPaths_TYPE_CHANGE ChangedPaths_Status = 3 - ChangedPaths_COPIED ChangedPaths_Status = 4 + // This comment is left unintentionally blank. + ChangedPaths_ADDED ChangedPaths_Status = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ChangedPaths_MODIFIED ChangedPaths_Status = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ChangedPaths_DELETED ChangedPaths_Status = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ChangedPaths_TYPE_CHANGE ChangedPaths_Status = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ChangedPaths_COPIED ChangedPaths_Status = 4 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for ChangedPaths_Status. @@ -123,21 +130,31 @@ func (ChangedPaths_Status) EnumDescriptor() ([]byte, []int) { return file_diff_proto_rawDescGZIP(), []int{14, 0} } +// This comment is left unintentionally blank. type CommitDiffRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` - RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` - IgnoreWhitespaceChange bool `protobuf:"varint,4,opt,name=ignore_whitespace_change,json=ignoreWhitespaceChange,proto3" json:"ignore_whitespace_change,omitempty"` - Paths [][]byte `protobuf:"bytes,5,rep,name=paths,proto3" json:"paths,omitempty"` - CollapseDiffs bool `protobuf:"varint,6,opt,name=collapse_diffs,json=collapseDiffs,proto3" json:"collapse_diffs,omitempty"` - EnforceLimits bool `protobuf:"varint,7,opt,name=enforce_limits,json=enforceLimits,proto3" json:"enforce_limits,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` + // This comment is left unintentionally blank. + RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` + // This comment is left unintentionally blank. + IgnoreWhitespaceChange bool `protobuf:"varint,4,opt,name=ignore_whitespace_change,json=ignoreWhitespaceChange,proto3" json:"ignore_whitespace_change,omitempty"` + // This comment is left unintentionally blank. + Paths [][]byte `protobuf:"bytes,5,rep,name=paths,proto3" json:"paths,omitempty"` + // This comment is left unintentionally blank. + CollapseDiffs bool `protobuf:"varint,6,opt,name=collapse_diffs,json=collapseDiffs,proto3" json:"collapse_diffs,omitempty"` + // This comment is left unintentionally blank. + EnforceLimits bool `protobuf:"varint,7,opt,name=enforce_limits,json=enforceLimits,proto3" json:"enforce_limits,omitempty"` // These limits are only enforced when enforce_limits == true. MaxFiles int32 `protobuf:"varint,8,opt,name=max_files,json=maxFiles,proto3" json:"max_files,omitempty"` + // This comment is left unintentionally blank. MaxLines int32 `protobuf:"varint,9,opt,name=max_lines,json=maxLines,proto3" json:"max_lines,omitempty"` + // This comment is left unintentionally blank. MaxBytes int32 `protobuf:"varint,10,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` // Limitation of a single diff patch, // patches surpassing this limit are pruned by default. @@ -145,7 +162,9 @@ type CommitDiffRequest struct { MaxPatchBytes int32 `protobuf:"varint,14,opt,name=max_patch_bytes,json=maxPatchBytes,proto3" json:"max_patch_bytes,omitempty"` // These limits are only enforced if collapse_diffs == true. SafeMaxFiles int32 `protobuf:"varint,11,opt,name=safe_max_files,json=safeMaxFiles,proto3" json:"safe_max_files,omitempty"` + // This comment is left unintentionally blank. SafeMaxLines int32 `protobuf:"varint,12,opt,name=safe_max_lines,json=safeMaxLines,proto3" json:"safe_max_lines,omitempty"` + // This comment is left unintentionally blank. SafeMaxBytes int32 `protobuf:"varint,13,opt,name=safe_max_bytes,json=safeMaxBytes,proto3" json:"safe_max_bytes,omitempty"` // DiffMode is the mode used for generating the diff. Please refer to the enum declaration for supported modes. DiffMode CommitDiffRequest_DiffMode `protobuf:"varint,15,opt,name=diff_mode,json=diffMode,proto3,enum=gitaly.CommitDiffRequest_DiffMode" json:"diff_mode,omitempty"` @@ -294,16 +313,24 @@ type CommitDiffResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. FromPath []byte `protobuf:"bytes,1,opt,name=from_path,json=fromPath,proto3" json:"from_path,omitempty"` - ToPath []byte `protobuf:"bytes,2,opt,name=to_path,json=toPath,proto3" json:"to_path,omitempty"` + // This comment is left unintentionally blank. + ToPath []byte `protobuf:"bytes,2,opt,name=to_path,json=toPath,proto3" json:"to_path,omitempty"` // Blob ID as returned via `git diff --full-index` - FromId string `protobuf:"bytes,3,opt,name=from_id,json=fromId,proto3" json:"from_id,omitempty"` - ToId string `protobuf:"bytes,4,opt,name=to_id,json=toId,proto3" json:"to_id,omitempty"` - OldMode int32 `protobuf:"varint,5,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` - NewMode int32 `protobuf:"varint,6,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` - Binary bool `protobuf:"varint,7,opt,name=binary,proto3" json:"binary,omitempty"` + FromId string `protobuf:"bytes,3,opt,name=from_id,json=fromId,proto3" json:"from_id,omitempty"` + // This comment is left unintentionally blank. + ToId string `protobuf:"bytes,4,opt,name=to_id,json=toId,proto3" json:"to_id,omitempty"` + // This comment is left unintentionally blank. + OldMode int32 `protobuf:"varint,5,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` + // This comment is left unintentionally blank. + NewMode int32 `protobuf:"varint,6,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` + // This comment is left unintentionally blank. + Binary bool `protobuf:"varint,7,opt,name=binary,proto3" json:"binary,omitempty"` + // This comment is left unintentionally blank. RawPatchData []byte `protobuf:"bytes,9,opt,name=raw_patch_data,json=rawPatchData,proto3" json:"raw_patch_data,omitempty"` - EndOfPatch bool `protobuf:"varint,10,opt,name=end_of_patch,json=endOfPatch,proto3" json:"end_of_patch,omitempty"` + // This comment is left unintentionally blank. + EndOfPatch bool `protobuf:"varint,10,opt,name=end_of_patch,json=endOfPatch,proto3" json:"end_of_patch,omitempty"` // Indicates the diff file at which we overflow according to the limitations sent, // in which case only this attribute will be set. OverflowMarker bool `protobuf:"varint,11,opt,name=overflow_marker,json=overflowMarker,proto3" json:"overflow_marker,omitempty"` @@ -431,15 +458,20 @@ func (x *CommitDiffResponse) GetTooLarge() bool { return false } +// This comment is left unintentionally blank. type CommitDeltaRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` - RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` - Paths [][]byte `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` + // This comment is left unintentionally blank. + RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` + // This comment is left unintentionally blank. + Paths [][]byte `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"` } func (x *CommitDeltaRequest) Reset() { @@ -502,18 +534,24 @@ func (x *CommitDeltaRequest) GetPaths() [][]byte { return nil } +// This comment is left unintentionally blank. type CommitDelta struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. FromPath []byte `protobuf:"bytes,1,opt,name=from_path,json=fromPath,proto3" json:"from_path,omitempty"` - ToPath []byte `protobuf:"bytes,2,opt,name=to_path,json=toPath,proto3" json:"to_path,omitempty"` + // This comment is left unintentionally blank. + ToPath []byte `protobuf:"bytes,2,opt,name=to_path,json=toPath,proto3" json:"to_path,omitempty"` // Blob ID as returned via `git diff --full-index` - FromId string `protobuf:"bytes,3,opt,name=from_id,json=fromId,proto3" json:"from_id,omitempty"` - ToId string `protobuf:"bytes,4,opt,name=to_id,json=toId,proto3" json:"to_id,omitempty"` - OldMode int32 `protobuf:"varint,5,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` - NewMode int32 `protobuf:"varint,6,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` + FromId string `protobuf:"bytes,3,opt,name=from_id,json=fromId,proto3" json:"from_id,omitempty"` + // This comment is left unintentionally blank. + ToId string `protobuf:"bytes,4,opt,name=to_id,json=toId,proto3" json:"to_id,omitempty"` + // This comment is left unintentionally blank. + OldMode int32 `protobuf:"varint,5,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` + // This comment is left unintentionally blank. + NewMode int32 `protobuf:"varint,6,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` } func (x *CommitDelta) Reset() { @@ -590,11 +628,13 @@ func (x *CommitDelta) GetNewMode() int32 { return 0 } +// This comment is left unintentionally blank. type CommitDeltaResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Deltas []*CommitDelta `protobuf:"bytes,1,rep,name=deltas,proto3" json:"deltas,omitempty"` } @@ -637,14 +677,18 @@ func (x *CommitDeltaResponse) GetDeltas() []*CommitDelta { return nil } +// This comment is left unintentionally blank. type RawDiffRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` - RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` + // This comment is left unintentionally blank. + RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` } func (x *RawDiffRequest) Reset() { @@ -700,11 +744,13 @@ func (x *RawDiffRequest) GetRightCommitId() string { return "" } +// This comment is left unintentionally blank. type RawDiffResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } @@ -747,14 +793,18 @@ func (x *RawDiffResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type RawPatchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` - RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` + // This comment is left unintentionally blank. + RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` } func (x *RawPatchRequest) Reset() { @@ -810,11 +860,13 @@ func (x *RawPatchRequest) GetRightCommitId() string { return "" } +// This comment is left unintentionally blank. type RawPatchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } @@ -857,14 +909,18 @@ func (x *RawPatchResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type DiffStatsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` - RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId,proto3" json:"left_commit_id,omitempty"` + // This comment is left unintentionally blank. + RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId,proto3" json:"right_commit_id,omitempty"` } func (x *DiffStatsRequest) Reset() { @@ -920,15 +976,20 @@ func (x *DiffStatsRequest) GetRightCommitId() string { return "" } +// This comment is left unintentionally blank. type DiffStats struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - Additions int32 `protobuf:"varint,2,opt,name=additions,proto3" json:"additions,omitempty"` - Deletions int32 `protobuf:"varint,3,opt,name=deletions,proto3" json:"deletions,omitempty"` - OldPath []byte `protobuf:"bytes,4,opt,name=old_path,json=oldPath,proto3" json:"old_path,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Additions int32 `protobuf:"varint,2,opt,name=additions,proto3" json:"additions,omitempty"` + // This comment is left unintentionally blank. + Deletions int32 `protobuf:"varint,3,opt,name=deletions,proto3" json:"deletions,omitempty"` + // This comment is left unintentionally blank. + OldPath []byte `protobuf:"bytes,4,opt,name=old_path,json=oldPath,proto3" json:"old_path,omitempty"` } func (x *DiffStats) Reset() { @@ -991,11 +1052,13 @@ func (x *DiffStats) GetOldPath() []byte { return nil } +// This comment is left unintentionally blank. type DiffStatsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Stats []*DiffStats `protobuf:"bytes,1,rep,name=stats,proto3" json:"stats,omitempty"` } @@ -1046,8 +1109,16 @@ type FindChangedPathsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Commits []string `protobuf:"bytes,2,rep,name=commits,proto3" json:"commits,omitempty"` + // commits is the list of commits to compare to their parents. This field is deprecated. To adapt to the new calling + // convention you can create one `CommitRequest` per commit, where each `CommitRequest` has only the `commit_revision` + // field. + // + // Deprecated: Do not use. + Commits []string `protobuf:"bytes,2,rep,name=commits,proto3" json:"commits,omitempty"` + // requests specifies the requests of what to compare. + Requests []*FindChangedPathsRequest_Request `protobuf:"bytes,3,rep,name=requests,proto3" json:"requests,omitempty"` } func (x *FindChangedPathsRequest) Reset() { @@ -1089,6 +1160,7 @@ func (x *FindChangedPathsRequest) GetRepository() *Repository { return nil } +// Deprecated: Do not use. func (x *FindChangedPathsRequest) GetCommits() []string { if x != nil { return x.Commits @@ -1096,12 +1168,20 @@ func (x *FindChangedPathsRequest) GetCommits() []string { return nil } +func (x *FindChangedPathsRequest) GetRequests() []*FindChangedPathsRequest_Request { + if x != nil { + return x.Requests + } + return nil +} + // Returns a list of files that have been changed in the commits given type FindChangedPathsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Paths []*ChangedPaths `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` } @@ -1150,8 +1230,20 @@ type ChangedPaths struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. Status ChangedPaths_Status `protobuf:"varint,2,opt,name=status,proto3,enum=gitaly.ChangedPaths_Status" json:"status,omitempty"` + // old_mode is the mode of the changed path previous to the change. May be one of the following values: + // + // - 0o000000 if the path does not exist. + // - 0o100644 if the path refers to a normal file. + // - 0o100755 if the path refers to an executable file. + // - 0o040000 if the path refers to a tree entry. + // - 0o160000 if the path refers to a submodule. + OldMode int32 `protobuf:"varint,3,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` + // new_mode is the mode of the changed path after the change. Please refer to `old_mode` for a list of potential values. + NewMode int32 `protobuf:"varint,4,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` } func (x *ChangedPaths) Reset() { @@ -1200,6 +1292,225 @@ func (x *ChangedPaths) GetStatus() ChangedPaths_Status { return ChangedPaths_ADDED } +func (x *ChangedPaths) GetOldMode() int32 { + if x != nil { + return x.OldMode + } + return 0 +} + +func (x *ChangedPaths) GetNewMode() int32 { + if x != nil { + return x.NewMode + } + return 0 +} + +// Request is a single request to pass to git diff-tree. +type FindChangedPathsRequest_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Type: + // *FindChangedPathsRequest_Request_TreeRequest_ + // *FindChangedPathsRequest_Request_CommitRequest_ + Type isFindChangedPathsRequest_Request_Type `protobuf_oneof:"type"` +} + +func (x *FindChangedPathsRequest_Request) Reset() { + *x = FindChangedPathsRequest_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_diff_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindChangedPathsRequest_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindChangedPathsRequest_Request) ProtoMessage() {} + +func (x *FindChangedPathsRequest_Request) ProtoReflect() protoreflect.Message { + mi := &file_diff_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindChangedPathsRequest_Request.ProtoReflect.Descriptor instead. +func (*FindChangedPathsRequest_Request) Descriptor() ([]byte, []int) { + return file_diff_proto_rawDescGZIP(), []int{12, 0} +} + +func (m *FindChangedPathsRequest_Request) GetType() isFindChangedPathsRequest_Request_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *FindChangedPathsRequest_Request) GetTreeRequest() *FindChangedPathsRequest_Request_TreeRequest { + if x, ok := x.GetType().(*FindChangedPathsRequest_Request_TreeRequest_); ok { + return x.TreeRequest + } + return nil +} + +func (x *FindChangedPathsRequest_Request) GetCommitRequest() *FindChangedPathsRequest_Request_CommitRequest { + if x, ok := x.GetType().(*FindChangedPathsRequest_Request_CommitRequest_); ok { + return x.CommitRequest + } + return nil +} + +type isFindChangedPathsRequest_Request_Type interface { + isFindChangedPathsRequest_Request_Type() +} + +type FindChangedPathsRequest_Request_TreeRequest_ struct { + // tree_request is a request comparing two trees with each other. + TreeRequest *FindChangedPathsRequest_Request_TreeRequest `protobuf:"bytes,1,opt,name=tree_request,json=treeRequest,proto3,oneof"` +} + +type FindChangedPathsRequest_Request_CommitRequest_ struct { + // commit_request is a request comparing one or more commits with each other. + CommitRequest *FindChangedPathsRequest_Request_CommitRequest `protobuf:"bytes,2,opt,name=commit_request,json=commitRequest,proto3,oneof"` +} + +func (*FindChangedPathsRequest_Request_TreeRequest_) isFindChangedPathsRequest_Request_Type() {} + +func (*FindChangedPathsRequest_Request_CommitRequest_) isFindChangedPathsRequest_Request_Type() {} + +// TreeRequest compares two trees. +type FindChangedPathsRequest_Request_TreeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // left_tree_revision is the revision of the left tree to compare. Accepts any revision that + // peels to a tree object. + LeftTreeRevision string `protobuf:"bytes,1,opt,name=left_tree_revision,json=leftTreeRevision,proto3" json:"left_tree_revision,omitempty"` + // right_tree_revision is the revision of the right tree to compare. Accepts any revision that + // peels to a tree object. + RightTreeRevision string `protobuf:"bytes,2,opt,name=right_tree_revision,json=rightTreeRevision,proto3" json:"right_tree_revision,omitempty"` +} + +func (x *FindChangedPathsRequest_Request_TreeRequest) Reset() { + *x = FindChangedPathsRequest_Request_TreeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_diff_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindChangedPathsRequest_Request_TreeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindChangedPathsRequest_Request_TreeRequest) ProtoMessage() {} + +func (x *FindChangedPathsRequest_Request_TreeRequest) ProtoReflect() protoreflect.Message { + mi := &file_diff_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindChangedPathsRequest_Request_TreeRequest.ProtoReflect.Descriptor instead. +func (*FindChangedPathsRequest_Request_TreeRequest) Descriptor() ([]byte, []int) { + return file_diff_proto_rawDescGZIP(), []int{12, 0, 0} +} + +func (x *FindChangedPathsRequest_Request_TreeRequest) GetLeftTreeRevision() string { + if x != nil { + return x.LeftTreeRevision + } + return "" +} + +func (x *FindChangedPathsRequest_Request_TreeRequest) GetRightTreeRevision() string { + if x != nil { + return x.RightTreeRevision + } + return "" +} + +// CommitRequest compares a commit to its parents (or some other commits.) +type FindChangedPathsRequest_Request_CommitRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // commit_revision is the revision of the commit that should be compared. If no `parent_commit_revisions` + // are given, then the commit will be compared against its parents. The revision needs to peel to a + // commit object. + CommitRevision string `protobuf:"bytes,1,opt,name=commit_revision,json=commitRevision,proto3" json:"commit_revision,omitempty"` + // parent_commit_revisions are the revisions of commits to treat as the commit's parents. This is an + // optional field: if not specified, the actual parents of the commit referred to by `commit_revision` + // are used. + ParentCommitRevisions []string `protobuf:"bytes,2,rep,name=parent_commit_revisions,json=parentCommitRevisions,proto3" json:"parent_commit_revisions,omitempty"` +} + +func (x *FindChangedPathsRequest_Request_CommitRequest) Reset() { + *x = FindChangedPathsRequest_Request_CommitRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_diff_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindChangedPathsRequest_Request_CommitRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindChangedPathsRequest_Request_CommitRequest) ProtoMessage() {} + +func (x *FindChangedPathsRequest_Request_CommitRequest) ProtoReflect() protoreflect.Message { + mi := &file_diff_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindChangedPathsRequest_Request_CommitRequest.ProtoReflect.Descriptor instead. +func (*FindChangedPathsRequest_Request_CommitRequest) Descriptor() ([]byte, []int) { + return file_diff_proto_rawDescGZIP(), []int{12, 0, 1} +} + +func (x *FindChangedPathsRequest_Request_CommitRequest) GetCommitRevision() string { + if x != nil { + return x.CommitRevision + } + return "" +} + +func (x *FindChangedPathsRequest_Request_CommitRequest) GetParentCommitRevisions() []string { + if x != nil { + return x.ParentCommitRevisions + } + return nil +} + var File_diff_proto protoreflect.FileDescriptor var file_diff_proto_rawDesc = []byte{ @@ -1342,64 +1653,98 @@ var file_diff_proto_rawDesc = []byte{ 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x6d, 0x0a, 0x17, 0x46, 0x69, - 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x46, 0x0a, 0x18, 0x46, 0x69, 0x6e, - 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, - 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, - 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4b, 0x0a, 0x06, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x4f, 0x50, 0x49, 0x45, 0x44, 0x10, 0x04, 0x32, 0xea, 0x03, 0x0a, 0x0b, 0x44, 0x69, 0x66, - 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x07, 0x52, 0x61, 0x77, - 0x44, 0x69, 0x66, 0x66, 0x12, 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, - 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, - 0x47, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x17, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, - 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x69, 0x66, 0x66, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, - 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, - 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, - 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x02, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0xe3, 0x04, 0x0a, 0x17, 0x46, + 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, + 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x12, 0x1c, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x43, + 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x73, 0x1a, 0xaa, 0x03, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x58, 0x0a, 0x0c, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, + 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x74, 0x72, + 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x6b, 0x0a, 0x0b, 0x54, 0x72, 0x65, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x66, 0x74, + 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x66, 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x69, 0x67, 0x68, 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x70, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x46, 0x0a, 0x18, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, + 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x05, + 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, + 0x73, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, 0xda, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x33, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, + 0x74, 0x68, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x6e, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x4b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x50, + 0x49, 0x45, 0x44, 0x10, 0x04, 0x32, 0xea, 0x03, 0x0a, 0x0b, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, + 0x69, 0x66, 0x66, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x02, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, + 0x6c, 0x74, 0x61, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, + 0x65, 0x6c, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, + 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x07, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, + 0x66, 0x12, 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x47, 0x0a, 0x08, + 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, + 0x01, 0x12, 0x5f, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1415,56 +1760,62 @@ func file_diff_proto_rawDescGZIP() []byte { } var file_diff_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_diff_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_diff_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_diff_proto_goTypes = []interface{}{ - (CommitDiffRequest_DiffMode)(0), // 0: gitaly.CommitDiffRequest.DiffMode - (ChangedPaths_Status)(0), // 1: gitaly.ChangedPaths.Status - (*CommitDiffRequest)(nil), // 2: gitaly.CommitDiffRequest - (*CommitDiffResponse)(nil), // 3: gitaly.CommitDiffResponse - (*CommitDeltaRequest)(nil), // 4: gitaly.CommitDeltaRequest - (*CommitDelta)(nil), // 5: gitaly.CommitDelta - (*CommitDeltaResponse)(nil), // 6: gitaly.CommitDeltaResponse - (*RawDiffRequest)(nil), // 7: gitaly.RawDiffRequest - (*RawDiffResponse)(nil), // 8: gitaly.RawDiffResponse - (*RawPatchRequest)(nil), // 9: gitaly.RawPatchRequest - (*RawPatchResponse)(nil), // 10: gitaly.RawPatchResponse - (*DiffStatsRequest)(nil), // 11: gitaly.DiffStatsRequest - (*DiffStats)(nil), // 12: gitaly.DiffStats - (*DiffStatsResponse)(nil), // 13: gitaly.DiffStatsResponse - (*FindChangedPathsRequest)(nil), // 14: gitaly.FindChangedPathsRequest - (*FindChangedPathsResponse)(nil), // 15: gitaly.FindChangedPathsResponse - (*ChangedPaths)(nil), // 16: gitaly.ChangedPaths - (*Repository)(nil), // 17: gitaly.Repository + (CommitDiffRequest_DiffMode)(0), // 0: gitaly.CommitDiffRequest.DiffMode + (ChangedPaths_Status)(0), // 1: gitaly.ChangedPaths.Status + (*CommitDiffRequest)(nil), // 2: gitaly.CommitDiffRequest + (*CommitDiffResponse)(nil), // 3: gitaly.CommitDiffResponse + (*CommitDeltaRequest)(nil), // 4: gitaly.CommitDeltaRequest + (*CommitDelta)(nil), // 5: gitaly.CommitDelta + (*CommitDeltaResponse)(nil), // 6: gitaly.CommitDeltaResponse + (*RawDiffRequest)(nil), // 7: gitaly.RawDiffRequest + (*RawDiffResponse)(nil), // 8: gitaly.RawDiffResponse + (*RawPatchRequest)(nil), // 9: gitaly.RawPatchRequest + (*RawPatchResponse)(nil), // 10: gitaly.RawPatchResponse + (*DiffStatsRequest)(nil), // 11: gitaly.DiffStatsRequest + (*DiffStats)(nil), // 12: gitaly.DiffStats + (*DiffStatsResponse)(nil), // 13: gitaly.DiffStatsResponse + (*FindChangedPathsRequest)(nil), // 14: gitaly.FindChangedPathsRequest + (*FindChangedPathsResponse)(nil), // 15: gitaly.FindChangedPathsResponse + (*ChangedPaths)(nil), // 16: gitaly.ChangedPaths + (*FindChangedPathsRequest_Request)(nil), // 17: gitaly.FindChangedPathsRequest.Request + (*FindChangedPathsRequest_Request_TreeRequest)(nil), // 18: gitaly.FindChangedPathsRequest.Request.TreeRequest + (*FindChangedPathsRequest_Request_CommitRequest)(nil), // 19: gitaly.FindChangedPathsRequest.Request.CommitRequest + (*Repository)(nil), // 20: gitaly.Repository } var file_diff_proto_depIdxs = []int32{ - 17, // 0: gitaly.CommitDiffRequest.repository:type_name -> gitaly.Repository + 20, // 0: gitaly.CommitDiffRequest.repository:type_name -> gitaly.Repository 0, // 1: gitaly.CommitDiffRequest.diff_mode:type_name -> gitaly.CommitDiffRequest.DiffMode - 17, // 2: gitaly.CommitDeltaRequest.repository:type_name -> gitaly.Repository + 20, // 2: gitaly.CommitDeltaRequest.repository:type_name -> gitaly.Repository 5, // 3: gitaly.CommitDeltaResponse.deltas:type_name -> gitaly.CommitDelta - 17, // 4: gitaly.RawDiffRequest.repository:type_name -> gitaly.Repository - 17, // 5: gitaly.RawPatchRequest.repository:type_name -> gitaly.Repository - 17, // 6: gitaly.DiffStatsRequest.repository:type_name -> gitaly.Repository + 20, // 4: gitaly.RawDiffRequest.repository:type_name -> gitaly.Repository + 20, // 5: gitaly.RawPatchRequest.repository:type_name -> gitaly.Repository + 20, // 6: gitaly.DiffStatsRequest.repository:type_name -> gitaly.Repository 12, // 7: gitaly.DiffStatsResponse.stats:type_name -> gitaly.DiffStats - 17, // 8: gitaly.FindChangedPathsRequest.repository:type_name -> gitaly.Repository - 16, // 9: gitaly.FindChangedPathsResponse.paths:type_name -> gitaly.ChangedPaths - 1, // 10: gitaly.ChangedPaths.status:type_name -> gitaly.ChangedPaths.Status - 2, // 11: gitaly.DiffService.CommitDiff:input_type -> gitaly.CommitDiffRequest - 4, // 12: gitaly.DiffService.CommitDelta:input_type -> gitaly.CommitDeltaRequest - 7, // 13: gitaly.DiffService.RawDiff:input_type -> gitaly.RawDiffRequest - 9, // 14: gitaly.DiffService.RawPatch:input_type -> gitaly.RawPatchRequest - 11, // 15: gitaly.DiffService.DiffStats:input_type -> gitaly.DiffStatsRequest - 14, // 16: gitaly.DiffService.FindChangedPaths:input_type -> gitaly.FindChangedPathsRequest - 3, // 17: gitaly.DiffService.CommitDiff:output_type -> gitaly.CommitDiffResponse - 6, // 18: gitaly.DiffService.CommitDelta:output_type -> gitaly.CommitDeltaResponse - 8, // 19: gitaly.DiffService.RawDiff:output_type -> gitaly.RawDiffResponse - 10, // 20: gitaly.DiffService.RawPatch:output_type -> gitaly.RawPatchResponse - 13, // 21: gitaly.DiffService.DiffStats:output_type -> gitaly.DiffStatsResponse - 15, // 22: gitaly.DiffService.FindChangedPaths:output_type -> gitaly.FindChangedPathsResponse - 17, // [17:23] is the sub-list for method output_type - 11, // [11:17] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 20, // 8: gitaly.FindChangedPathsRequest.repository:type_name -> gitaly.Repository + 17, // 9: gitaly.FindChangedPathsRequest.requests:type_name -> gitaly.FindChangedPathsRequest.Request + 16, // 10: gitaly.FindChangedPathsResponse.paths:type_name -> gitaly.ChangedPaths + 1, // 11: gitaly.ChangedPaths.status:type_name -> gitaly.ChangedPaths.Status + 18, // 12: gitaly.FindChangedPathsRequest.Request.tree_request:type_name -> gitaly.FindChangedPathsRequest.Request.TreeRequest + 19, // 13: gitaly.FindChangedPathsRequest.Request.commit_request:type_name -> gitaly.FindChangedPathsRequest.Request.CommitRequest + 2, // 14: gitaly.DiffService.CommitDiff:input_type -> gitaly.CommitDiffRequest + 4, // 15: gitaly.DiffService.CommitDelta:input_type -> gitaly.CommitDeltaRequest + 7, // 16: gitaly.DiffService.RawDiff:input_type -> gitaly.RawDiffRequest + 9, // 17: gitaly.DiffService.RawPatch:input_type -> gitaly.RawPatchRequest + 11, // 18: gitaly.DiffService.DiffStats:input_type -> gitaly.DiffStatsRequest + 14, // 19: gitaly.DiffService.FindChangedPaths:input_type -> gitaly.FindChangedPathsRequest + 3, // 20: gitaly.DiffService.CommitDiff:output_type -> gitaly.CommitDiffResponse + 6, // 21: gitaly.DiffService.CommitDelta:output_type -> gitaly.CommitDeltaResponse + 8, // 22: gitaly.DiffService.RawDiff:output_type -> gitaly.RawDiffResponse + 10, // 23: gitaly.DiffService.RawPatch:output_type -> gitaly.RawPatchResponse + 13, // 24: gitaly.DiffService.DiffStats:output_type -> gitaly.DiffStatsResponse + 15, // 25: gitaly.DiffService.FindChangedPaths:output_type -> gitaly.FindChangedPathsResponse + 20, // [20:26] is the sub-list for method output_type + 14, // [14:20] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_diff_proto_init() } @@ -1655,6 +2006,46 @@ func file_diff_proto_init() { return nil } } + file_diff_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindChangedPathsRequest_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_diff_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindChangedPathsRequest_Request_TreeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_diff_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindChangedPathsRequest_Request_CommitRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_diff_proto_msgTypes[15].OneofWrappers = []interface{}{ + (*FindChangedPathsRequest_Request_TreeRequest_)(nil), + (*FindChangedPathsRequest_Request_CommitRequest_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1662,7 +2053,7 @@ func file_diff_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_diff_proto_rawDesc, NumEnums: 2, - NumMessages: 15, + NumMessages: 18, NumExtensions: 0, NumServices: 1, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff_grpc.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff_grpc.pb.go index 7fdc2a73c9..29ae827d3b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/diff_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/diff_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: diff.proto package gitalypb @@ -22,8 +26,11 @@ type DiffServiceClient interface { CommitDiff(ctx context.Context, in *CommitDiffRequest, opts ...grpc.CallOption) (DiffService_CommitDiffClient, error) // Return a stream so we can divide the response in chunks of deltas CommitDelta(ctx context.Context, in *CommitDeltaRequest, opts ...grpc.CallOption) (DiffService_CommitDeltaClient, error) + // This comment is left unintentionally blank. RawDiff(ctx context.Context, in *RawDiffRequest, opts ...grpc.CallOption) (DiffService_RawDiffClient, error) + // This comment is left unintentionally blank. RawPatch(ctx context.Context, in *RawPatchRequest, opts ...grpc.CallOption) (DiffService_RawPatchClient, error) + // This comment is left unintentionally blank. DiffStats(ctx context.Context, in *DiffStatsRequest, opts ...grpc.CallOption) (DiffService_DiffStatsClient, error) // Return a list of files changed along with the status of each file FindChangedPaths(ctx context.Context, in *FindChangedPathsRequest, opts ...grpc.CallOption) (DiffService_FindChangedPathsClient, error) @@ -237,8 +244,11 @@ type DiffServiceServer interface { CommitDiff(*CommitDiffRequest, DiffService_CommitDiffServer) error // Return a stream so we can divide the response in chunks of deltas CommitDelta(*CommitDeltaRequest, DiffService_CommitDeltaServer) error + // This comment is left unintentionally blank. RawDiff(*RawDiffRequest, DiffService_RawDiffServer) error + // This comment is left unintentionally blank. RawPatch(*RawPatchRequest, DiffService_RawPatchServer) error + // This comment is left unintentionally blank. DiffStats(*DiffStatsRequest, DiffService_DiffStatsServer) error // Return a list of files changed along with the status of each file FindChangedPaths(*FindChangedPathsRequest, DiffService_FindChangedPathsServer) error diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/errors.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/errors.pb.go new file mode 100644 index 0000000000..af8b3b04d5 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/errors.pb.go @@ -0,0 +1,1075 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.21.1 +// source: errors.proto + +package gitalypb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// HookType is the type of the hook that has been running. Please consult githooks(5) for more +// information about the specific types. +type CustomHookError_HookType int32 + +const ( + // HOOK_TYPE_UNSPECIFIED is the default hook type and should never be set. + CustomHookError_HOOK_TYPE_UNSPECIFIED CustomHookError_HookType = 0 + // HOOK_TYPE_PRERECEIVE is executed after all changes have been written into a temporary staging + // directory, but before any references in the repository have been updated. It is executed with + // all references that are about to be updated at once. If this hook exits, then no references + // will have been updated in the repository and staged objects will have been discarded. + CustomHookError_HOOK_TYPE_PRERECEIVE CustomHookError_HookType = 1 + // HOOK_TYPE_UPDATE is executed after the pre-receive hook. It is executed per reference that is + // about to be updated and can be used to reject only a subset of reference updates. If this + // hook error is raised then a subset of references may have already been updated. + CustomHookError_HOOK_TYPE_UPDATE CustomHookError_HookType = 2 + // HOOK_TYPE_POSTRECEIVE is executed after objects have been migrated into the repository and + // after references have been updated. An error in this hook will not impact the changes + // anymore as everything has already been persisted. + CustomHookError_HOOK_TYPE_POSTRECEIVE CustomHookError_HookType = 3 +) + +// Enum value maps for CustomHookError_HookType. +var ( + CustomHookError_HookType_name = map[int32]string{ + 0: "HOOK_TYPE_UNSPECIFIED", + 1: "HOOK_TYPE_PRERECEIVE", + 2: "HOOK_TYPE_UPDATE", + 3: "HOOK_TYPE_POSTRECEIVE", + } + CustomHookError_HookType_value = map[string]int32{ + "HOOK_TYPE_UNSPECIFIED": 0, + "HOOK_TYPE_PRERECEIVE": 1, + "HOOK_TYPE_UPDATE": 2, + "HOOK_TYPE_POSTRECEIVE": 3, + } +) + +func (x CustomHookError_HookType) Enum() *CustomHookError_HookType { + p := new(CustomHookError_HookType) + *p = x + return p +} + +func (x CustomHookError_HookType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CustomHookError_HookType) Descriptor() protoreflect.EnumDescriptor { + return file_errors_proto_enumTypes[0].Descriptor() +} + +func (CustomHookError_HookType) Type() protoreflect.EnumType { + return &file_errors_proto_enumTypes[0] +} + +func (x CustomHookError_HookType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CustomHookError_HookType.Descriptor instead. +func (CustomHookError_HookType) EnumDescriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{11, 0} +} + +// AccessCheckError is an error returned by GitLab's `/internal/allowed` +// endpoint. +type AccessCheckError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ErrorMessage is the error message as returned by the endpoint. + ErrorMessage string `protobuf:"bytes,1,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + // Protocol is the protocol used. + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + // UserId is the user ID as which changes had been pushed. + UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // Changes is the set of changes which have failed the access check. + Changes []byte `protobuf:"bytes,4,opt,name=changes,proto3" json:"changes,omitempty"` +} + +func (x *AccessCheckError) Reset() { + *x = AccessCheckError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessCheckError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessCheckError) ProtoMessage() {} + +func (x *AccessCheckError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessCheckError.ProtoReflect.Descriptor instead. +func (*AccessCheckError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{0} +} + +func (x *AccessCheckError) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +func (x *AccessCheckError) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *AccessCheckError) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *AccessCheckError) GetChanges() []byte { + if x != nil { + return x.Changes + } + return nil +} + +// InvalidRefFormatError is an error returned when refs have an invalid format. +type InvalidRefFormatError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Refs are the offending refs with invalid formats. + Refs [][]byte `protobuf:"bytes,2,rep,name=refs,proto3" json:"refs,omitempty"` +} + +func (x *InvalidRefFormatError) Reset() { + *x = InvalidRefFormatError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvalidRefFormatError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvalidRefFormatError) ProtoMessage() {} + +func (x *InvalidRefFormatError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvalidRefFormatError.ProtoReflect.Descriptor instead. +func (*InvalidRefFormatError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{1} +} + +func (x *InvalidRefFormatError) GetRefs() [][]byte { + if x != nil { + return x.Refs + } + return nil +} + +// NotAncestorError is an error returned when parent_revision is not an ancestor +// of the child_revision. +type NotAncestorError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ParentRevision is the revision checked against ChildRevision for whether it + // is an ancestor of ChildRevision + ParentRevision []byte `protobuf:"bytes,1,opt,name=parent_revision,json=parentRevision,proto3" json:"parent_revision,omitempty"` + // ChildRevision is the revision checked against ParentRevision for whether + // it is a descendent of ChildRevision. + ChildRevision []byte `protobuf:"bytes,2,opt,name=child_revision,json=childRevision,proto3" json:"child_revision,omitempty"` +} + +func (x *NotAncestorError) Reset() { + *x = NotAncestorError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotAncestorError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotAncestorError) ProtoMessage() {} + +func (x *NotAncestorError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotAncestorError.ProtoReflect.Descriptor instead. +func (*NotAncestorError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{2} +} + +func (x *NotAncestorError) GetParentRevision() []byte { + if x != nil { + return x.ParentRevision + } + return nil +} + +func (x *NotAncestorError) GetChildRevision() []byte { + if x != nil { + return x.ChildRevision + } + return nil +} + +// ChangesAlreadyAppliedError is an error returned when the operation would +// have resulted in no changes because these changes have already been applied. +type ChangesAlreadyAppliedError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ChangesAlreadyAppliedError) Reset() { + *x = ChangesAlreadyAppliedError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChangesAlreadyAppliedError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChangesAlreadyAppliedError) ProtoMessage() {} + +func (x *ChangesAlreadyAppliedError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChangesAlreadyAppliedError.ProtoReflect.Descriptor instead. +func (*ChangesAlreadyAppliedError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{3} +} + +// MergeConflictError is an error returned in the case when merging two commits +// fails due to a merge conflict. +type MergeConflictError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ConflictingFiles is the set of files which have been conflicting. If this + // field is empty, then there has still been a merge conflict, but it wasn't + // able to determine which files have been conflicting. + ConflictingFiles [][]byte `protobuf:"bytes,1,rep,name=conflicting_files,json=conflictingFiles,proto3" json:"conflicting_files,omitempty"` + // ConflictingCommitIds is the set of commit IDs that caused the conflict. In the general case, + // this should be set to two commit IDs. + ConflictingCommitIds []string `protobuf:"bytes,2,rep,name=conflicting_commit_ids,json=conflictingCommitIds,proto3" json:"conflicting_commit_ids,omitempty"` +} + +func (x *MergeConflictError) Reset() { + *x = MergeConflictError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MergeConflictError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MergeConflictError) ProtoMessage() {} + +func (x *MergeConflictError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MergeConflictError.ProtoReflect.Descriptor instead. +func (*MergeConflictError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{4} +} + +func (x *MergeConflictError) GetConflictingFiles() [][]byte { + if x != nil { + return x.ConflictingFiles + } + return nil +} + +func (x *MergeConflictError) GetConflictingCommitIds() []string { + if x != nil { + return x.ConflictingCommitIds + } + return nil +} + +// ReferencesLockedError is an error returned when an ref update fails because +// the references have already been locked by another process. +type ReferencesLockedError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Refs are the references that could not be locked. + Refs [][]byte `protobuf:"bytes,1,rep,name=refs,proto3" json:"refs,omitempty"` +} + +func (x *ReferencesLockedError) Reset() { + *x = ReferencesLockedError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReferencesLockedError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReferencesLockedError) ProtoMessage() {} + +func (x *ReferencesLockedError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReferencesLockedError.ProtoReflect.Descriptor instead. +func (*ReferencesLockedError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{5} +} + +func (x *ReferencesLockedError) GetRefs() [][]byte { + if x != nil { + return x.Refs + } + return nil +} + +// ReferenceExistsError is an error returned when a reference that ought not to exist does exist +// already. +type ReferenceExistsError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ReferenceName is the name of the reference that exists already. + ReferenceName []byte `protobuf:"bytes,1,opt,name=reference_name,json=referenceName,proto3" json:"reference_name,omitempty"` + // Oid is the object ID of the reference that preexists already. + Oid string `protobuf:"bytes,2,opt,name=oid,proto3" json:"oid,omitempty"` +} + +func (x *ReferenceExistsError) Reset() { + *x = ReferenceExistsError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReferenceExistsError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReferenceExistsError) ProtoMessage() {} + +func (x *ReferenceExistsError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReferenceExistsError.ProtoReflect.Descriptor instead. +func (*ReferenceExistsError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{6} +} + +func (x *ReferenceExistsError) GetReferenceName() []byte { + if x != nil { + return x.ReferenceName + } + return nil +} + +func (x *ReferenceExistsError) GetOid() string { + if x != nil { + return x.Oid + } + return "" +} + +// ReferenceNotFoundError is an error retruned when a reference that ought to exist does not exist. +type ReferenceNotFoundError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ReferenceName is the name of the reference that does not exist. + ReferenceName []byte `protobuf:"bytes,1,opt,name=reference_name,json=referenceName,proto3" json:"reference_name,omitempty"` +} + +func (x *ReferenceNotFoundError) Reset() { + *x = ReferenceNotFoundError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReferenceNotFoundError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReferenceNotFoundError) ProtoMessage() {} + +func (x *ReferenceNotFoundError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReferenceNotFoundError.ProtoReflect.Descriptor instead. +func (*ReferenceNotFoundError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{7} +} + +func (x *ReferenceNotFoundError) GetReferenceName() []byte { + if x != nil { + return x.ReferenceName + } + return nil +} + +// ReferenceUpdateError is an error returned when updating a reference has +// failed. +type ReferenceUpdateError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ReferenceName is the name of the reference that failed to be updated. + ReferenceName []byte `protobuf:"bytes,1,opt,name=reference_name,json=referenceName,proto3" json:"reference_name,omitempty"` + // OldOid is the object ID the reference should have pointed to before the update. + OldOid string `protobuf:"bytes,2,opt,name=old_oid,json=oldOid,proto3" json:"old_oid,omitempty"` + // NewOid is the object ID the reference should have pointed to after the update. + NewOid string `protobuf:"bytes,3,opt,name=new_oid,json=newOid,proto3" json:"new_oid,omitempty"` +} + +func (x *ReferenceUpdateError) Reset() { + *x = ReferenceUpdateError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReferenceUpdateError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReferenceUpdateError) ProtoMessage() {} + +func (x *ReferenceUpdateError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReferenceUpdateError.ProtoReflect.Descriptor instead. +func (*ReferenceUpdateError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{8} +} + +func (x *ReferenceUpdateError) GetReferenceName() []byte { + if x != nil { + return x.ReferenceName + } + return nil +} + +func (x *ReferenceUpdateError) GetOldOid() string { + if x != nil { + return x.OldOid + } + return "" +} + +func (x *ReferenceUpdateError) GetNewOid() string { + if x != nil { + return x.NewOid + } + return "" +} + +// ResolveRevisionError is an error returned when resolving a specific revision +// has failed. +type ResolveRevisionError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Revision is the name of the revision that was tried to be resolved. + Revision []byte `protobuf:"bytes,1,opt,name=revision,proto3" json:"revision,omitempty"` +} + +func (x *ResolveRevisionError) Reset() { + *x = ResolveRevisionError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveRevisionError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveRevisionError) ProtoMessage() {} + +func (x *ResolveRevisionError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolveRevisionError.ProtoReflect.Descriptor instead. +func (*ResolveRevisionError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{9} +} + +func (x *ResolveRevisionError) GetRevision() []byte { + if x != nil { + return x.Revision + } + return nil +} + +// LimitError is an error returned when Gitaly enforces request limits. +type LimitError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ErrorMessage provides context into why a limit was enforced. + ErrorMessage string `protobuf:"bytes,1,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + // RetryAfter provides the duration after which a retry is safe. + // 0 indicates non-retryable. + RetryAfter *durationpb.Duration `protobuf:"bytes,2,opt,name=retry_after,json=retryAfter,proto3" json:"retry_after,omitempty"` +} + +func (x *LimitError) Reset() { + *x = LimitError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LimitError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LimitError) ProtoMessage() {} + +func (x *LimitError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LimitError.ProtoReflect.Descriptor instead. +func (*LimitError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{10} +} + +func (x *LimitError) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +func (x *LimitError) GetRetryAfter() *durationpb.Duration { + if x != nil { + return x.RetryAfter + } + return nil +} + +// CustomHookError is an error returned when Gitaly executes a custom hook and the hook returns +// a non-zero return code. +type CustomHookError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Stdout is the standard output of the hook that has failed, if any. Data may be truncated. + Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + // Stderr is the standard error of the hook that has failed, if any. Data may be truncated. + Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // HookType is the type of the hook. + HookType CustomHookError_HookType `protobuf:"varint,3,opt,name=hook_type,json=hookType,proto3,enum=gitaly.CustomHookError_HookType" json:"hook_type,omitempty"` +} + +func (x *CustomHookError) Reset() { + *x = CustomHookError{} + if protoimpl.UnsafeEnabled { + mi := &file_errors_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomHookError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomHookError) ProtoMessage() {} + +func (x *CustomHookError) ProtoReflect() protoreflect.Message { + mi := &file_errors_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomHookError.ProtoReflect.Descriptor instead. +func (*CustomHookError) Descriptor() ([]byte, []int) { + return file_errors_proto_rawDescGZIP(), []int{11} +} + +func (x *CustomHookError) GetStdout() []byte { + if x != nil { + return x.Stdout + } + return nil +} + +func (x *CustomHookError) GetStderr() []byte { + if x != nil { + return x.Stderr + } + return nil +} + +func (x *CustomHookError) GetHookType() CustomHookError_HookType { + if x != nil { + return x.HookType + } + return CustomHookError_HOOK_TYPE_UNSPECIFIED +} + +var File_errors_proto protoreflect.FileDescriptor + +var file_errors_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x17, 0x0a, 0x07, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, + 0x2b, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x66, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x22, 0x62, 0x0a, 0x10, + 0x4e, 0x6f, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x41, 0x6c, 0x72, 0x65, 0x61, + 0x64, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x77, + 0x0a, 0x12, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x73, 0x22, 0x2b, 0x0a, 0x15, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, + 0x72, 0x65, 0x66, 0x73, 0x22, 0x4f, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6f, 0x69, 0x64, 0x22, 0x3f, 0x0a, 0x16, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, + 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x6c, 0x64, 0x5f, 0x6f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x6c, 0x64, 0x4f, 0x69, 0x64, 0x12, 0x17, + 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x6e, 0x65, 0x77, 0x4f, 0x69, 0x64, 0x22, 0x32, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x6d, 0x0a, 0x0a, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, + 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, + 0x72, 0x65, 0x74, 0x72, 0x79, 0x41, 0x66, 0x74, 0x65, 0x72, 0x22, 0xf2, 0x01, 0x0a, 0x0f, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x3d, + 0x0a, 0x09, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x08, 0x68, 0x6f, 0x6f, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x22, 0x70, 0x0a, + 0x08, 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x4f, 0x4f, + 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x4f, 0x4f, 0x4b, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x14, + 0x0a, 0x10, 0x48, 0x4f, 0x4f, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x4f, 0x4f, 0x4b, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x10, 0x03, 0x42, + 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, + 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, + 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_errors_proto_rawDescOnce sync.Once + file_errors_proto_rawDescData = file_errors_proto_rawDesc +) + +func file_errors_proto_rawDescGZIP() []byte { + file_errors_proto_rawDescOnce.Do(func() { + file_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_errors_proto_rawDescData) + }) + return file_errors_proto_rawDescData +} + +var file_errors_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_errors_proto_goTypes = []interface{}{ + (CustomHookError_HookType)(0), // 0: gitaly.CustomHookError.HookType + (*AccessCheckError)(nil), // 1: gitaly.AccessCheckError + (*InvalidRefFormatError)(nil), // 2: gitaly.InvalidRefFormatError + (*NotAncestorError)(nil), // 3: gitaly.NotAncestorError + (*ChangesAlreadyAppliedError)(nil), // 4: gitaly.ChangesAlreadyAppliedError + (*MergeConflictError)(nil), // 5: gitaly.MergeConflictError + (*ReferencesLockedError)(nil), // 6: gitaly.ReferencesLockedError + (*ReferenceExistsError)(nil), // 7: gitaly.ReferenceExistsError + (*ReferenceNotFoundError)(nil), // 8: gitaly.ReferenceNotFoundError + (*ReferenceUpdateError)(nil), // 9: gitaly.ReferenceUpdateError + (*ResolveRevisionError)(nil), // 10: gitaly.ResolveRevisionError + (*LimitError)(nil), // 11: gitaly.LimitError + (*CustomHookError)(nil), // 12: gitaly.CustomHookError + (*durationpb.Duration)(nil), // 13: google.protobuf.Duration +} +var file_errors_proto_depIdxs = []int32{ + 13, // 0: gitaly.LimitError.retry_after:type_name -> google.protobuf.Duration + 0, // 1: gitaly.CustomHookError.hook_type:type_name -> gitaly.CustomHookError.HookType + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_errors_proto_init() } +func file_errors_proto_init() { + if File_errors_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_errors_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessCheckError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvalidRefFormatError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotAncestorError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChangesAlreadyAppliedError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MergeConflictError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReferencesLockedError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReferenceExistsError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReferenceNotFoundError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReferenceUpdateError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveRevisionError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LimitError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_errors_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomHookError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_errors_proto_rawDesc, + NumEnums: 1, + NumMessages: 12, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_errors_proto_goTypes, + DependencyIndexes: file_errors_proto_depIdxs, + EnumInfos: file_errors_proto_enumTypes, + MessageInfos: file_errors_proto_msgTypes, + }.Build() + File_errors_proto = out.File + file_errors_proto_rawDesc = nil + file_errors_proto_goTypes = nil + file_errors_proto_depIdxs = nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook.pb.go similarity index 69% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook.pb.go index 349ccc9bca..5512db0733 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: hook.proto package gitalypb @@ -20,12 +20,16 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type ReferenceTransactionHookRequest_State int32 const ( - ReferenceTransactionHookRequest_PREPARED ReferenceTransactionHookRequest_State = 0 - ReferenceTransactionHookRequest_COMMITTED ReferenceTransactionHookRequest_State = 1 - ReferenceTransactionHookRequest_ABORTED ReferenceTransactionHookRequest_State = 2 + // This comment is left unintentionally blank. + ReferenceTransactionHookRequest_PREPARED ReferenceTransactionHookRequest_State = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ReferenceTransactionHookRequest_COMMITTED ReferenceTransactionHookRequest_State = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ReferenceTransactionHookRequest_ABORTED ReferenceTransactionHookRequest_State = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for ReferenceTransactionHookRequest_State. @@ -69,15 +73,20 @@ func (ReferenceTransactionHookRequest_State) EnumDescriptor() ([]byte, []int) { return file_hook_proto_rawDescGZIP(), []int{6, 0} } +// This comment is left unintentionally blank. type PreReceiveHookRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` - Stdin []byte `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"` - GitPushOptions []string `protobuf:"bytes,5,rep,name=git_push_options,json=gitPushOptions,proto3" json:"git_push_options,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` + // This comment is left unintentionally blank. + Stdin []byte `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"` + // This comment is left unintentionally blank. + GitPushOptions []string `protobuf:"bytes,5,rep,name=git_push_options,json=gitPushOptions,proto3" json:"git_push_options,omitempty"` } func (x *PreReceiveHookRequest) Reset() { @@ -140,13 +149,17 @@ func (x *PreReceiveHookRequest) GetGitPushOptions() []string { return nil } +// This comment is left unintentionally blank. type PreReceiveHookResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. + Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + // This comment is left unintentionally blank. + Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. ExitStatus *ExitStatus `protobuf:"bytes,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` } @@ -203,15 +216,20 @@ func (x *PreReceiveHookResponse) GetExitStatus() *ExitStatus { return nil } +// This comment is left unintentionally blank. type PostReceiveHookRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` - Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` - GitPushOptions []string `protobuf:"bytes,4,rep,name=git_push_options,json=gitPushOptions,proto3" json:"git_push_options,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` + // This comment is left unintentionally blank. + Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` + // This comment is left unintentionally blank. + GitPushOptions []string `protobuf:"bytes,4,rep,name=git_push_options,json=gitPushOptions,proto3" json:"git_push_options,omitempty"` } func (x *PostReceiveHookRequest) Reset() { @@ -274,13 +292,17 @@ func (x *PostReceiveHookRequest) GetGitPushOptions() []string { return nil } +// This comment is left unintentionally blank. type PostReceiveHookResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. + Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + // This comment is left unintentionally blank. + Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. ExitStatus *ExitStatus `protobuf:"bytes,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` } @@ -337,16 +359,22 @@ func (x *PostReceiveHookResponse) GetExitStatus() *ExitStatus { return nil } +// This comment is left unintentionally blank. type UpdateHookRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` - Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` - OldValue string `protobuf:"bytes,4,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` - NewValue string `protobuf:"bytes,5,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` + // This comment is left unintentionally blank. + Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` + // This comment is left unintentionally blank. + OldValue string `protobuf:"bytes,4,opt,name=old_value,json=oldValue,proto3" json:"old_value,omitempty"` + // This comment is left unintentionally blank. + NewValue string `protobuf:"bytes,5,opt,name=new_value,json=newValue,proto3" json:"new_value,omitempty"` } func (x *UpdateHookRequest) Reset() { @@ -416,13 +444,17 @@ func (x *UpdateHookRequest) GetNewValue() string { return "" } +// This comment is left unintentionally blank. type UpdateHookResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. + Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + // This comment is left unintentionally blank. + Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. ExitStatus *ExitStatus `protobuf:"bytes,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` } @@ -479,15 +511,20 @@ func (x *UpdateHookResponse) GetExitStatus() *ExitStatus { return nil } +// This comment is left unintentionally blank. type ReferenceTransactionHookRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` - Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` - State ReferenceTransactionHookRequest_State `protobuf:"varint,4,opt,name=state,proto3,enum=gitaly.ReferenceTransactionHookRequest_State" json:"state,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + EnvironmentVariables []string `protobuf:"bytes,2,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` + // This comment is left unintentionally blank. + Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` + // This comment is left unintentionally blank. + State ReferenceTransactionHookRequest_State `protobuf:"varint,4,opt,name=state,proto3,enum=gitaly.ReferenceTransactionHookRequest_State" json:"state,omitempty"` } func (x *ReferenceTransactionHookRequest) Reset() { @@ -550,13 +587,17 @@ func (x *ReferenceTransactionHookRequest) GetState() ReferenceTransactionHookReq return ReferenceTransactionHookRequest_PREPARED } +// This comment is left unintentionally blank. type ReferenceTransactionHookResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. + Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + // This comment is left unintentionally blank. + Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + // This comment is left unintentionally blank. ExitStatus *ExitStatus `protobuf:"bytes,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` } @@ -613,142 +654,28 @@ func (x *ReferenceTransactionHookResponse) GetExitStatus() *ExitStatus { return nil } -type PackObjectsHookRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - // args contains the arguments passed to the pack-objects hook, without the leading "git" - Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"` - // stdin is meant for consumption by git-pack-objects - Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` -} - -func (x *PackObjectsHookRequest) Reset() { - *x = PackObjectsHookRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_hook_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PackObjectsHookRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PackObjectsHookRequest) ProtoMessage() {} - -func (x *PackObjectsHookRequest) ProtoReflect() protoreflect.Message { - mi := &file_hook_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PackObjectsHookRequest.ProtoReflect.Descriptor instead. -func (*PackObjectsHookRequest) Descriptor() ([]byte, []int) { - return file_hook_proto_rawDescGZIP(), []int{8} -} - -func (x *PackObjectsHookRequest) GetRepository() *Repository { - if x != nil { - return x.Repository - } - return nil -} - -func (x *PackObjectsHookRequest) GetArgs() []string { - if x != nil { - return x.Args - } - return nil -} - -func (x *PackObjectsHookRequest) GetStdin() []byte { - if x != nil { - return x.Stdin - } - return nil -} - -type PackObjectsHookResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // stdout contains packfile data - Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` - // stderr contains progress messages (such as "Enumerating objects ...") - Stderr []byte `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` -} - -func (x *PackObjectsHookResponse) Reset() { - *x = PackObjectsHookResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_hook_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PackObjectsHookResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PackObjectsHookResponse) ProtoMessage() {} - -func (x *PackObjectsHookResponse) ProtoReflect() protoreflect.Message { - mi := &file_hook_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PackObjectsHookResponse.ProtoReflect.Descriptor instead. -func (*PackObjectsHookResponse) Descriptor() ([]byte, []int) { - return file_hook_proto_rawDescGZIP(), []int{9} -} - -func (x *PackObjectsHookResponse) GetStdout() []byte { - if x != nil { - return x.Stdout - } - return nil -} - -func (x *PackObjectsHookResponse) GetStderr() []byte { - if x != nil { - return x.Stderr - } - return nil -} - +// This comment is left unintentionally blank. type PackObjectsHookWithSidechannelRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // args contains the arguments passed to the pack-objects hook, without the leading "git" Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"` + // GlId is the user id of the initator of the fetch + GlId string `protobuf:"bytes,3,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + // GlUsername is the username of the initator of the fetch + GlUsername string `protobuf:"bytes,5,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` + // GitProtocol is the protocol used for the fetch + GitProtocol string `protobuf:"bytes,6,opt,name=git_protocol,json=gitProtocol,proto3" json:"git_protocol,omitempty"` } func (x *PackObjectsHookWithSidechannelRequest) Reset() { *x = PackObjectsHookWithSidechannelRequest{} if protoimpl.UnsafeEnabled { - mi := &file_hook_proto_msgTypes[10] + mi := &file_hook_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -761,7 +688,7 @@ func (x *PackObjectsHookWithSidechannelRequest) String() string { func (*PackObjectsHookWithSidechannelRequest) ProtoMessage() {} func (x *PackObjectsHookWithSidechannelRequest) ProtoReflect() protoreflect.Message { - mi := &file_hook_proto_msgTypes[10] + mi := &file_hook_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -774,7 +701,7 @@ func (x *PackObjectsHookWithSidechannelRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use PackObjectsHookWithSidechannelRequest.ProtoReflect.Descriptor instead. func (*PackObjectsHookWithSidechannelRequest) Descriptor() ([]byte, []int) { - return file_hook_proto_rawDescGZIP(), []int{10} + return file_hook_proto_rawDescGZIP(), []int{8} } func (x *PackObjectsHookWithSidechannelRequest) GetRepository() *Repository { @@ -791,6 +718,28 @@ func (x *PackObjectsHookWithSidechannelRequest) GetArgs() []string { return nil } +func (x *PackObjectsHookWithSidechannelRequest) GetGlId() string { + if x != nil { + return x.GlId + } + return "" +} + +func (x *PackObjectsHookWithSidechannelRequest) GetGlUsername() string { + if x != nil { + return x.GlUsername + } + return "" +} + +func (x *PackObjectsHookWithSidechannelRequest) GetGitProtocol() string { + if x != nil { + return x.GitProtocol + } + return "" +} + +// This comment is left unintentionally blank. type PackObjectsHookWithSidechannelResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -800,7 +749,7 @@ type PackObjectsHookWithSidechannelResponse struct { func (x *PackObjectsHookWithSidechannelResponse) Reset() { *x = PackObjectsHookWithSidechannelResponse{} if protoimpl.UnsafeEnabled { - mi := &file_hook_proto_msgTypes[11] + mi := &file_hook_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -813,7 +762,7 @@ func (x *PackObjectsHookWithSidechannelResponse) String() string { func (*PackObjectsHookWithSidechannelResponse) ProtoMessage() {} func (x *PackObjectsHookWithSidechannelResponse) ProtoReflect() protoreflect.Message { - mi := &file_hook_proto_msgTypes[11] + mi := &file_hook_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -826,7 +775,7 @@ func (x *PackObjectsHookWithSidechannelResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use PackObjectsHookWithSidechannelResponse.ProtoReflect.Descriptor instead. func (*PackObjectsHookWithSidechannelResponse) Descriptor() ([]byte, []int) { - return file_hook_proto_rawDescGZIP(), []int{11} + return file_hook_proto_rawDescGZIP(), []int{9} } var File_hook_proto protoreflect.FileDescriptor @@ -923,74 +872,61 @@ var file_hook_proto_rawDesc = []byte{ 0x72, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x45, 0x78, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x65, 0x78, 0x69, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7c, 0x0a, 0x16, 0x50, 0x61, 0x63, 0x6b, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x25, 0x50, 0x61, 0x63, 0x6b, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x73, 0x74, 0x64, 0x69, 0x6e, 0x22, 0x49, 0x0a, 0x17, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, - 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, - 0x22, 0x75, 0x0a, 0x25, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, - 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x61, 0x63, 0x6b, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, - 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0x81, 0x05, 0x0a, 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, - 0x6f, 0x6f, 0x6b, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x72, 0x65, + 0x13, 0x0a, 0x05, 0x67, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x67, 0x6c, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x6c, 0x55, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x67, 0x69, 0x74, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x61, 0x63, 0x6b, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x32, 0x9e, 0x04, 0x0a, 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x72, + 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x72, 0x65, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x5e, 0x0a, 0x0f, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, + 0x6f, 0x6b, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x72, 0x65, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5e, - 0x0a, 0x0f, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, - 0x6b, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4d, - 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x19, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x79, 0x0a, - 0x18, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x0f, 0x50, 0x61, 0x63, 0x6b, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x1e, 0x2e, 0x67, 0x69, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x6f, 0x73, 0x74, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x19, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x79, + 0x0a, 0x18, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x27, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x87, 0x01, 0x0a, 0x1e, 0x50, 0x61, + 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, + 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x2d, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x09, 0x88, 0x02, - 0x01, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x12, 0x87, 0x01, 0x0a, 0x1e, - 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, - 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x2d, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x48, 0x6f, 0x6f, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x63, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, + 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1006,7 +942,7 @@ func file_hook_proto_rawDescGZIP() []byte { } var file_hook_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_hook_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_hook_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_hook_proto_goTypes = []interface{}{ (ReferenceTransactionHookRequest_State)(0), // 0: gitaly.ReferenceTransactionHookRequest.State (*PreReceiveHookRequest)(nil), // 1: gitaly.PreReceiveHookRequest @@ -1017,42 +953,37 @@ var file_hook_proto_goTypes = []interface{}{ (*UpdateHookResponse)(nil), // 6: gitaly.UpdateHookResponse (*ReferenceTransactionHookRequest)(nil), // 7: gitaly.ReferenceTransactionHookRequest (*ReferenceTransactionHookResponse)(nil), // 8: gitaly.ReferenceTransactionHookResponse - (*PackObjectsHookRequest)(nil), // 9: gitaly.PackObjectsHookRequest - (*PackObjectsHookResponse)(nil), // 10: gitaly.PackObjectsHookResponse - (*PackObjectsHookWithSidechannelRequest)(nil), // 11: gitaly.PackObjectsHookWithSidechannelRequest - (*PackObjectsHookWithSidechannelResponse)(nil), // 12: gitaly.PackObjectsHookWithSidechannelResponse - (*Repository)(nil), // 13: gitaly.Repository - (*ExitStatus)(nil), // 14: gitaly.ExitStatus + (*PackObjectsHookWithSidechannelRequest)(nil), // 9: gitaly.PackObjectsHookWithSidechannelRequest + (*PackObjectsHookWithSidechannelResponse)(nil), // 10: gitaly.PackObjectsHookWithSidechannelResponse + (*Repository)(nil), // 11: gitaly.Repository + (*ExitStatus)(nil), // 12: gitaly.ExitStatus } var file_hook_proto_depIdxs = []int32{ - 13, // 0: gitaly.PreReceiveHookRequest.repository:type_name -> gitaly.Repository - 14, // 1: gitaly.PreReceiveHookResponse.exit_status:type_name -> gitaly.ExitStatus - 13, // 2: gitaly.PostReceiveHookRequest.repository:type_name -> gitaly.Repository - 14, // 3: gitaly.PostReceiveHookResponse.exit_status:type_name -> gitaly.ExitStatus - 13, // 4: gitaly.UpdateHookRequest.repository:type_name -> gitaly.Repository - 14, // 5: gitaly.UpdateHookResponse.exit_status:type_name -> gitaly.ExitStatus - 13, // 6: gitaly.ReferenceTransactionHookRequest.repository:type_name -> gitaly.Repository + 11, // 0: gitaly.PreReceiveHookRequest.repository:type_name -> gitaly.Repository + 12, // 1: gitaly.PreReceiveHookResponse.exit_status:type_name -> gitaly.ExitStatus + 11, // 2: gitaly.PostReceiveHookRequest.repository:type_name -> gitaly.Repository + 12, // 3: gitaly.PostReceiveHookResponse.exit_status:type_name -> gitaly.ExitStatus + 11, // 4: gitaly.UpdateHookRequest.repository:type_name -> gitaly.Repository + 12, // 5: gitaly.UpdateHookResponse.exit_status:type_name -> gitaly.ExitStatus + 11, // 6: gitaly.ReferenceTransactionHookRequest.repository:type_name -> gitaly.Repository 0, // 7: gitaly.ReferenceTransactionHookRequest.state:type_name -> gitaly.ReferenceTransactionHookRequest.State - 14, // 8: gitaly.ReferenceTransactionHookResponse.exit_status:type_name -> gitaly.ExitStatus - 13, // 9: gitaly.PackObjectsHookRequest.repository:type_name -> gitaly.Repository - 13, // 10: gitaly.PackObjectsHookWithSidechannelRequest.repository:type_name -> gitaly.Repository - 1, // 11: gitaly.HookService.PreReceiveHook:input_type -> gitaly.PreReceiveHookRequest - 3, // 12: gitaly.HookService.PostReceiveHook:input_type -> gitaly.PostReceiveHookRequest - 5, // 13: gitaly.HookService.UpdateHook:input_type -> gitaly.UpdateHookRequest - 7, // 14: gitaly.HookService.ReferenceTransactionHook:input_type -> gitaly.ReferenceTransactionHookRequest - 9, // 15: gitaly.HookService.PackObjectsHook:input_type -> gitaly.PackObjectsHookRequest - 11, // 16: gitaly.HookService.PackObjectsHookWithSidechannel:input_type -> gitaly.PackObjectsHookWithSidechannelRequest - 2, // 17: gitaly.HookService.PreReceiveHook:output_type -> gitaly.PreReceiveHookResponse - 4, // 18: gitaly.HookService.PostReceiveHook:output_type -> gitaly.PostReceiveHookResponse - 6, // 19: gitaly.HookService.UpdateHook:output_type -> gitaly.UpdateHookResponse - 8, // 20: gitaly.HookService.ReferenceTransactionHook:output_type -> gitaly.ReferenceTransactionHookResponse - 10, // 21: gitaly.HookService.PackObjectsHook:output_type -> gitaly.PackObjectsHookResponse - 12, // 22: gitaly.HookService.PackObjectsHookWithSidechannel:output_type -> gitaly.PackObjectsHookWithSidechannelResponse - 17, // [17:23] is the sub-list for method output_type - 11, // [11:17] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 12, // 8: gitaly.ReferenceTransactionHookResponse.exit_status:type_name -> gitaly.ExitStatus + 11, // 9: gitaly.PackObjectsHookWithSidechannelRequest.repository:type_name -> gitaly.Repository + 1, // 10: gitaly.HookService.PreReceiveHook:input_type -> gitaly.PreReceiveHookRequest + 3, // 11: gitaly.HookService.PostReceiveHook:input_type -> gitaly.PostReceiveHookRequest + 5, // 12: gitaly.HookService.UpdateHook:input_type -> gitaly.UpdateHookRequest + 7, // 13: gitaly.HookService.ReferenceTransactionHook:input_type -> gitaly.ReferenceTransactionHookRequest + 9, // 14: gitaly.HookService.PackObjectsHookWithSidechannel:input_type -> gitaly.PackObjectsHookWithSidechannelRequest + 2, // 15: gitaly.HookService.PreReceiveHook:output_type -> gitaly.PreReceiveHookResponse + 4, // 16: gitaly.HookService.PostReceiveHook:output_type -> gitaly.PostReceiveHookResponse + 6, // 17: gitaly.HookService.UpdateHook:output_type -> gitaly.UpdateHookResponse + 8, // 18: gitaly.HookService.ReferenceTransactionHook:output_type -> gitaly.ReferenceTransactionHookResponse + 10, // 19: gitaly.HookService.PackObjectsHookWithSidechannel:output_type -> gitaly.PackObjectsHookWithSidechannelResponse + 15, // [15:20] is the sub-list for method output_type + 10, // [10:15] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_hook_proto_init() } @@ -1160,30 +1091,6 @@ func file_hook_proto_init() { } } file_hook_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackObjectsHookRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hook_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackObjectsHookResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hook_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PackObjectsHookWithSidechannelRequest); i { case 0: return &v.state @@ -1195,7 +1102,7 @@ func file_hook_proto_init() { return nil } } - file_hook_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_hook_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PackObjectsHookWithSidechannelResponse); i { case 0: return &v.state @@ -1214,7 +1121,7 @@ func file_hook_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_hook_proto_rawDesc, NumEnums: 1, - NumMessages: 12, + NumMessages: 10, NumExtensions: 0, NumServices: 1, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook_grpc.pb.go similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook_grpc.pb.go index 4f71dde2b1..6f5eba4742 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/hook_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/hook_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: hook.proto package gitalypb @@ -18,13 +22,14 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type HookServiceClient interface { + // This comment is left unintentionally blank. PreReceiveHook(ctx context.Context, opts ...grpc.CallOption) (HookService_PreReceiveHookClient, error) + // This comment is left unintentionally blank. PostReceiveHook(ctx context.Context, opts ...grpc.CallOption) (HookService_PostReceiveHookClient, error) + // This comment is left unintentionally blank. UpdateHook(ctx context.Context, in *UpdateHookRequest, opts ...grpc.CallOption) (HookService_UpdateHookClient, error) + // This comment is left unintentionally blank. ReferenceTransactionHook(ctx context.Context, opts ...grpc.CallOption) (HookService_ReferenceTransactionHookClient, error) - // Deprecated: Do not use. - // PackObjectsHook has been replaced by PackObjectsHookWithSidechannel. Remove in 15.0. - PackObjectsHook(ctx context.Context, opts ...grpc.CallOption) (HookService_PackObjectsHookClient, error) // PackObjectsHookWithSidechannel is an optimized version of PackObjectsHook that uses // a unix socket side channel. PackObjectsHookWithSidechannel(ctx context.Context, in *PackObjectsHookWithSidechannelRequest, opts ...grpc.CallOption) (*PackObjectsHookWithSidechannelResponse, error) @@ -163,38 +168,6 @@ func (x *hookServiceReferenceTransactionHookClient) Recv() (*ReferenceTransactio return m, nil } -// Deprecated: Do not use. -func (c *hookServiceClient) PackObjectsHook(ctx context.Context, opts ...grpc.CallOption) (HookService_PackObjectsHookClient, error) { - stream, err := c.cc.NewStream(ctx, &HookService_ServiceDesc.Streams[4], "/gitaly.HookService/PackObjectsHook", opts...) - if err != nil { - return nil, err - } - x := &hookServicePackObjectsHookClient{stream} - return x, nil -} - -type HookService_PackObjectsHookClient interface { - Send(*PackObjectsHookRequest) error - Recv() (*PackObjectsHookResponse, error) - grpc.ClientStream -} - -type hookServicePackObjectsHookClient struct { - grpc.ClientStream -} - -func (x *hookServicePackObjectsHookClient) Send(m *PackObjectsHookRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *hookServicePackObjectsHookClient) Recv() (*PackObjectsHookResponse, error) { - m := new(PackObjectsHookResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func (c *hookServiceClient) PackObjectsHookWithSidechannel(ctx context.Context, in *PackObjectsHookWithSidechannelRequest, opts ...grpc.CallOption) (*PackObjectsHookWithSidechannelResponse, error) { out := new(PackObjectsHookWithSidechannelResponse) err := c.cc.Invoke(ctx, "/gitaly.HookService/PackObjectsHookWithSidechannel", in, out, opts...) @@ -208,13 +181,14 @@ func (c *hookServiceClient) PackObjectsHookWithSidechannel(ctx context.Context, // All implementations must embed UnimplementedHookServiceServer // for forward compatibility type HookServiceServer interface { + // This comment is left unintentionally blank. PreReceiveHook(HookService_PreReceiveHookServer) error + // This comment is left unintentionally blank. PostReceiveHook(HookService_PostReceiveHookServer) error + // This comment is left unintentionally blank. UpdateHook(*UpdateHookRequest, HookService_UpdateHookServer) error + // This comment is left unintentionally blank. ReferenceTransactionHook(HookService_ReferenceTransactionHookServer) error - // Deprecated: Do not use. - // PackObjectsHook has been replaced by PackObjectsHookWithSidechannel. Remove in 15.0. - PackObjectsHook(HookService_PackObjectsHookServer) error // PackObjectsHookWithSidechannel is an optimized version of PackObjectsHook that uses // a unix socket side channel. PackObjectsHookWithSidechannel(context.Context, *PackObjectsHookWithSidechannelRequest) (*PackObjectsHookWithSidechannelResponse, error) @@ -237,9 +211,6 @@ func (UnimplementedHookServiceServer) UpdateHook(*UpdateHookRequest, HookService func (UnimplementedHookServiceServer) ReferenceTransactionHook(HookService_ReferenceTransactionHookServer) error { return status.Errorf(codes.Unimplemented, "method ReferenceTransactionHook not implemented") } -func (UnimplementedHookServiceServer) PackObjectsHook(HookService_PackObjectsHookServer) error { - return status.Errorf(codes.Unimplemented, "method PackObjectsHook not implemented") -} func (UnimplementedHookServiceServer) PackObjectsHookWithSidechannel(context.Context, *PackObjectsHookWithSidechannelRequest) (*PackObjectsHookWithSidechannelResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PackObjectsHookWithSidechannel not implemented") } @@ -355,32 +326,6 @@ func (x *hookServiceReferenceTransactionHookServer) Recv() (*ReferenceTransactio return m, nil } -func _HookService_PackObjectsHook_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(HookServiceServer).PackObjectsHook(&hookServicePackObjectsHookServer{stream}) -} - -type HookService_PackObjectsHookServer interface { - Send(*PackObjectsHookResponse) error - Recv() (*PackObjectsHookRequest, error) - grpc.ServerStream -} - -type hookServicePackObjectsHookServer struct { - grpc.ServerStream -} - -func (x *hookServicePackObjectsHookServer) Send(m *PackObjectsHookResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *hookServicePackObjectsHookServer) Recv() (*PackObjectsHookRequest, error) { - m := new(PackObjectsHookRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func _HookService_PackObjectsHookWithSidechannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PackObjectsHookWithSidechannelRequest) if err := dec(in); err != nil { @@ -435,12 +380,6 @@ var HookService_ServiceDesc = grpc.ServiceDesc{ ServerStreams: true, ClientStreams: true, }, - { - StreamName: "PackObjectsHook", - Handler: _HookService_PackObjectsHook_Handler, - ServerStreams: true, - ClientStreams: true, - }, }, Metadata: "hook.proto", } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal.pb.go similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal.pb.go index d7b604b54e..cf98846766 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: internal.proto package gitalypb @@ -21,11 +21,13 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type WalkReposRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` } @@ -68,11 +70,13 @@ func (x *WalkReposRequest) GetStorageName() string { return "" } +// This comment is left unintentionally blank. type WalkReposResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. RelativePath string `protobuf:"bytes,1,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` // modification_time is the modification time of the repository directory. // This can be used as a proxy for when the repository was last @@ -130,9 +134,9 @@ var File_internal_proto protoreflect.FileDescriptor var file_internal_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, + 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3b, 0x0a, 0x10, 0x57, 0x61, 0x6c, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, @@ -153,7 +157,7 @@ var file_internal_proto_rawDesc = []byte{ 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, 0x02, 0x10, 0x02, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal_grpc.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal_grpc.pb.go index 6b5b3564c5..ea93368a85 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/internal_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/internal_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: internal.proto package gitalypb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/lint.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/lint.pb.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/lint.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/lint.pb.go index 13c98757d9..c34bdb4a2b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/lint.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/lint.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: lint.proto package gitalypb @@ -21,13 +21,18 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type OperationMsg_Operation int32 const ( - OperationMsg_UNKNOWN OperationMsg_Operation = 0 - OperationMsg_MUTATOR OperationMsg_Operation = 1 - OperationMsg_ACCESSOR OperationMsg_Operation = 2 - OperationMsg_MAINTENANCE OperationMsg_Operation = 3 + // This comment is left unintentionally blank. + OperationMsg_UNKNOWN OperationMsg_Operation = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + OperationMsg_MUTATOR OperationMsg_Operation = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + OperationMsg_ACCESSOR OperationMsg_Operation = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + OperationMsg_MAINTENANCE OperationMsg_Operation = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for OperationMsg_Operation. @@ -73,11 +78,14 @@ func (OperationMsg_Operation) EnumDescriptor() ([]byte, []int) { return file_lint_proto_rawDescGZIP(), []int{0, 0} } +// This comment is left unintentionally blank. type OperationMsg_Scope int32 const ( - OperationMsg_REPOSITORY OperationMsg_Scope = 0 - OperationMsg_STORAGE OperationMsg_Scope = 2 + // This comment is left unintentionally blank. + OperationMsg_REPOSITORY OperationMsg_Scope = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + OperationMsg_STORAGE OperationMsg_Scope = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for OperationMsg_Scope. @@ -119,11 +127,13 @@ func (OperationMsg_Scope) EnumDescriptor() ([]byte, []int) { return file_lint_proto_rawDescGZIP(), []int{0, 1} } +// This comment is left unintentionally blank. type OperationMsg struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Op OperationMsg_Operation `protobuf:"varint,1,opt,name=op,proto3,enum=gitaly.OperationMsg_Operation" json:"op,omitempty"` // Scope level indicates what level an RPC interacts with a server: // - REPOSITORY: scoped to only a single repo @@ -341,7 +351,7 @@ var file_lint_proto_rawDesc = []byte{ 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace.pb.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace.pb.go index 1fb49c9c17..ef6a213754 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: namespace.proto package gitalypb @@ -20,13 +20,16 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type AddNamespaceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (x *AddNamespaceRequest) Reset() { @@ -75,13 +78,16 @@ func (x *AddNamespaceRequest) GetName() string { return "" } +// This comment is left unintentionally blank. type RemoveNamespaceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (x *RemoveNamespaceRequest) Reset() { @@ -130,14 +136,18 @@ func (x *RemoveNamespaceRequest) GetName() string { return "" } +// This comment is left unintentionally blank. type RenameNamespaceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + // This comment is left unintentionally blank. + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + // This comment is left unintentionally blank. + To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` } func (x *RenameNamespaceRequest) Reset() { @@ -193,13 +203,16 @@ func (x *RenameNamespaceRequest) GetTo() string { return "" } +// This comment is left unintentionally blank. type NamespaceExistsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (x *NamespaceExistsRequest) Reset() { @@ -248,11 +261,13 @@ func (x *NamespaceExistsRequest) GetName() string { return "" } +// This comment is left unintentionally blank. type NamespaceExistsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` } @@ -295,6 +310,7 @@ func (x *NamespaceExistsResponse) GetExists() bool { return false } +// This comment is left unintentionally blank. type AddNamespaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -333,6 +349,7 @@ func (*AddNamespaceResponse) Descriptor() ([]byte, []int) { return file_namespace_proto_rawDescGZIP(), []int{5} } +// This comment is left unintentionally blank. type RemoveNamespaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -371,6 +388,7 @@ func (*RemoveNamespaceResponse) Descriptor() ([]byte, []int) { return file_namespace_proto_rawDescGZIP(), []int{6} } +// This comment is left unintentionally blank. type RenameNamespaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -471,7 +489,7 @@ var file_namespace_proto_rawDesc = []byte{ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, 0x02, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, + 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace_grpc.pb.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace_grpc.pb.go index 33ff20ee33..f0cad47044 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/namespace_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/namespace_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: namespace.proto package gitalypb @@ -18,9 +22,13 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type NamespaceServiceClient interface { + // This comment is left unintentionally blank. AddNamespace(ctx context.Context, in *AddNamespaceRequest, opts ...grpc.CallOption) (*AddNamespaceResponse, error) + // This comment is left unintentionally blank. RemoveNamespace(ctx context.Context, in *RemoveNamespaceRequest, opts ...grpc.CallOption) (*RemoveNamespaceResponse, error) + // This comment is left unintentionally blank. RenameNamespace(ctx context.Context, in *RenameNamespaceRequest, opts ...grpc.CallOption) (*RenameNamespaceResponse, error) + // This comment is left unintentionally blank. NamespaceExists(ctx context.Context, in *NamespaceExistsRequest, opts ...grpc.CallOption) (*NamespaceExistsResponse, error) } @@ -72,9 +80,13 @@ func (c *namespaceServiceClient) NamespaceExists(ctx context.Context, in *Namesp // All implementations must embed UnimplementedNamespaceServiceServer // for forward compatibility type NamespaceServiceServer interface { + // This comment is left unintentionally blank. AddNamespace(context.Context, *AddNamespaceRequest) (*AddNamespaceResponse, error) + // This comment is left unintentionally blank. RemoveNamespace(context.Context, *RemoveNamespaceRequest) (*RemoveNamespaceResponse, error) + // This comment is left unintentionally blank. RenameNamespace(context.Context, *RenameNamespaceRequest) (*RenameNamespaceResponse, error) + // This comment is left unintentionally blank. NamespaceExists(context.Context, *NamespaceExistsRequest) (*NamespaceExistsResponse, error) mustEmbedUnimplementedNamespaceServiceServer() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool.pb.go similarity index 83% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool.pb.go index 460cb87e85..6f052357b3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: objectpool.proto package gitalypb @@ -27,8 +27,10 @@ type CreateObjectPoolRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. ObjectPool *ObjectPool `protobuf:"bytes,1,opt,name=object_pool,json=objectPool,proto3" json:"object_pool,omitempty"` - Origin *Repository `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` + // This comment is left unintentionally blank. + Origin *Repository `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` } func (x *CreateObjectPoolRequest) Reset() { @@ -77,6 +79,7 @@ func (x *CreateObjectPoolRequest) GetOrigin() *Repository { return nil } +// This comment is left unintentionally blank. type CreateObjectPoolResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -122,6 +125,7 @@ type DeleteObjectPoolRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. ObjectPool *ObjectPool `protobuf:"bytes,1,opt,name=object_pool,json=objectPool,proto3" json:"object_pool,omitempty"` } @@ -164,6 +168,7 @@ func (x *DeleteObjectPoolRequest) GetObjectPool() *ObjectPool { return nil } +// This comment is left unintentionally blank. type DeleteObjectPoolResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -202,12 +207,15 @@ func (*DeleteObjectPoolResponse) Descriptor() ([]byte, []int) { return file_objectpool_proto_rawDescGZIP(), []int{3} } +// This comment is left unintentionally blank. type LinkRepositoryToObjectPoolRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. ObjectPool *ObjectPool `protobuf:"bytes,1,opt,name=object_pool,json=objectPool,proto3" json:"object_pool,omitempty"` + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,2,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -257,6 +265,7 @@ func (x *LinkRepositoryToObjectPoolRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type LinkRepositoryToObjectPoolResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -295,11 +304,13 @@ func (*LinkRepositoryToObjectPoolResponse) Descriptor() ([]byte, []int) { return file_objectpool_proto_rawDescGZIP(), []int{5} } +// This comment is left unintentionally blank. type ReduplicateRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -342,6 +353,7 @@ func (x *ReduplicateRepositoryRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type ReduplicateRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -380,11 +392,13 @@ func (*ReduplicateRepositoryResponse) Descriptor() ([]byte, []int) { return file_objectpool_proto_rawDescGZIP(), []int{7} } +// This comment is left unintentionally blank. type DisconnectGitAlternatesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -427,6 +441,7 @@ func (x *DisconnectGitAlternatesRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type DisconnectGitAlternatesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -465,14 +480,16 @@ func (*DisconnectGitAlternatesResponse) Descriptor() ([]byte, []int) { return file_objectpool_proto_rawDescGZIP(), []int{9} } +// FetchIntoObjectPoolRequest is a request for the FetchIntoObjectPool RPC. type FetchIntoObjectPoolRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Origin *Repository `protobuf:"bytes,1,opt,name=origin,proto3" json:"origin,omitempty"` + // Origin is the repository to fetch changes from. + Origin *Repository `protobuf:"bytes,1,opt,name=origin,proto3" json:"origin,omitempty"` + // ObjectPool is the repository to fetch changes into. ObjectPool *ObjectPool `protobuf:"bytes,2,opt,name=object_pool,json=objectPool,proto3" json:"object_pool,omitempty"` - Repack bool `protobuf:"varint,3,opt,name=repack,proto3" json:"repack,omitempty"` } func (x *FetchIntoObjectPoolRequest) Reset() { @@ -521,13 +538,7 @@ func (x *FetchIntoObjectPoolRequest) GetObjectPool() *ObjectPool { return nil } -func (x *FetchIntoObjectPoolRequest) GetRepack() bool { - if x != nil { - return x.Repack - } - return false -} - +// FetchIntoObjectPoolResponse is a response for the FetchIntoObjectPool RPC. type FetchIntoObjectPoolResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -566,11 +577,13 @@ func (*FetchIntoObjectPoolResponse) Descriptor() ([]byte, []int) { return file_objectpool_proto_rawDescGZIP(), []int{11} } +// This comment is left unintentionally blank. type GetObjectPoolRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -613,11 +626,13 @@ func (x *GetObjectPoolRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type GetObjectPoolResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. ObjectPool *ObjectPool `protobuf:"bytes,1,opt,name=object_pool,json=objectPool,proto3" json:"object_pool,omitempty"` } @@ -711,7 +726,7 @@ var file_objectpool_proto_rawDesc = []byte{ 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x21, 0x0a, 0x1f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x74, 0x63, 0x68, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, @@ -720,71 +735,70 @@ var file_objectpool_proto_rawDesc = []byte{ 0x74, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, - 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x22, 0x1d, 0x0a, 0x1b, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, - 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x4c, 0x0a, 0x15, 0x47, - 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x70, - 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x0a, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x32, 0xee, 0x05, 0x0a, 0x11, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x5d, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, - 0x6f, 0x6f, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, - 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, - 0x6f, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x7b, 0x0a, - 0x1a, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, - 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x29, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x6c, 0x0a, 0x15, 0x52, 0x65, - 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x64, - 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x72, 0x0a, 0x17, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x74, 0x65, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, - 0x69, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x66, 0x0a, 0x13, - 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, - 0x6f, 0x6f, 0x6c, 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x6f, 0x6c, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x06, 0x72, 0x65, 0x70, 0x61, 0x63, 0x6b, + 0x22, 0x1d, 0x0a, 0x1b, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x22, 0x4c, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, + 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x6f, 0x6f, 0x6c, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x32, + 0xee, 0x05, 0x0a, 0x11, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, - 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, + 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, + 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, + 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x01, 0x12, 0x7b, 0x0a, 0x1a, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, + 0x6c, 0x12, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, + 0x12, 0x6c, 0x0a, 0x15, 0x52, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x72, + 0x0a, 0x17, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, 0x41, + 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, + 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x47, 0x69, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x01, 0x12, 0x66, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x6f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, - 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x47, 0x65, + 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, + 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, + 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool_grpc.pb.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool_grpc.pb.go index b46a4bc1c6..4acbe3aa14 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/objectpool_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/objectpool_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: objectpool.proto package gitalypb @@ -18,13 +22,22 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ObjectPoolServiceClient interface { + // This comment is left unintentionally blank. CreateObjectPool(ctx context.Context, in *CreateObjectPoolRequest, opts ...grpc.CallOption) (*CreateObjectPoolResponse, error) + // This comment is left unintentionally blank. DeleteObjectPool(ctx context.Context, in *DeleteObjectPoolRequest, opts ...grpc.CallOption) (*DeleteObjectPoolResponse, error) // Repositories are assumed to be stored on the same disk LinkRepositoryToObjectPool(ctx context.Context, in *LinkRepositoryToObjectPoolRequest, opts ...grpc.CallOption) (*LinkRepositoryToObjectPoolResponse, error) + // This comment is left unintentionally blank. ReduplicateRepository(ctx context.Context, in *ReduplicateRepositoryRequest, opts ...grpc.CallOption) (*ReduplicateRepositoryResponse, error) + // This comment is left unintentionally blank. DisconnectGitAlternates(ctx context.Context, in *DisconnectGitAlternatesRequest, opts ...grpc.CallOption) (*DisconnectGitAlternatesResponse, error) + // FetchIntoObjectPool fetches all references from a pool member into an object pool so that + // objects shared between this repository and other pool members can be deduplicated. This RPC + // will perform housekeeping tasks after the object pool has been updated to ensure that the pool + // is in an optimal state. FetchIntoObjectPool(ctx context.Context, in *FetchIntoObjectPoolRequest, opts ...grpc.CallOption) (*FetchIntoObjectPoolResponse, error) + // This comment is left unintentionally blank. GetObjectPool(ctx context.Context, in *GetObjectPoolRequest, opts ...grpc.CallOption) (*GetObjectPoolResponse, error) } @@ -103,13 +116,22 @@ func (c *objectPoolServiceClient) GetObjectPool(ctx context.Context, in *GetObje // All implementations must embed UnimplementedObjectPoolServiceServer // for forward compatibility type ObjectPoolServiceServer interface { + // This comment is left unintentionally blank. CreateObjectPool(context.Context, *CreateObjectPoolRequest) (*CreateObjectPoolResponse, error) + // This comment is left unintentionally blank. DeleteObjectPool(context.Context, *DeleteObjectPoolRequest) (*DeleteObjectPoolResponse, error) // Repositories are assumed to be stored on the same disk LinkRepositoryToObjectPool(context.Context, *LinkRepositoryToObjectPoolRequest) (*LinkRepositoryToObjectPoolResponse, error) + // This comment is left unintentionally blank. ReduplicateRepository(context.Context, *ReduplicateRepositoryRequest) (*ReduplicateRepositoryResponse, error) + // This comment is left unintentionally blank. DisconnectGitAlternates(context.Context, *DisconnectGitAlternatesRequest) (*DisconnectGitAlternatesResponse, error) + // FetchIntoObjectPool fetches all references from a pool member into an object pool so that + // objects shared between this repository and other pool members can be deduplicated. This RPC + // will perform housekeeping tasks after the object pool has been updated to ensure that the pool + // is in an optimal state. FetchIntoObjectPool(context.Context, *FetchIntoObjectPoolRequest) (*FetchIntoObjectPoolResponse, error) + // This comment is left unintentionally blank. GetObjectPool(context.Context, *GetObjectPoolRequest) (*GetObjectPoolResponse, error) mustEmbedUnimplementedObjectPoolServiceServer() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations.pb.go similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations.pb.go index 5914d5aaf3..2c9ca206dc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: operations.proto package gitalypb @@ -27,12 +27,12 @@ type UserCherryPickResponse_CreateTreeError int32 const ( // NONE denotes that no error occurred. - UserCherryPickResponse_NONE UserCherryPickResponse_CreateTreeError = 0 + UserCherryPickResponse_NONE UserCherryPickResponse_CreateTreeError = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // EMPTY denotes that the cherry-pick would've resulted in an empty commit, // typically because it has already been applied to the target branch. - UserCherryPickResponse_EMPTY UserCherryPickResponse_CreateTreeError = 1 + UserCherryPickResponse_EMPTY UserCherryPickResponse_CreateTreeError = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CONFLICT denotes that the cherry-pick resulted in a conflict. - UserCherryPickResponse_CONFLICT UserCherryPickResponse_CreateTreeError = 2 + UserCherryPickResponse_CONFLICT UserCherryPickResponse_CreateTreeError = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for UserCherryPickResponse_CreateTreeError. @@ -73,7 +73,7 @@ func (x UserCherryPickResponse_CreateTreeError) Number() protoreflect.EnumNumber // Deprecated: Use UserCherryPickResponse_CreateTreeError.Descriptor instead. func (UserCherryPickResponse_CreateTreeError) EnumDescriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{19, 0} + return file_operations_proto_rawDescGZIP(), []int{22, 0} } // CreateTreeError represents an error which happened when computing the @@ -82,12 +82,12 @@ type UserRevertResponse_CreateTreeError int32 const ( // NONE denotes that no error occurred. - UserRevertResponse_NONE UserRevertResponse_CreateTreeError = 0 + UserRevertResponse_NONE UserRevertResponse_CreateTreeError = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // EMPTY denotes that the revert would've resulted in an empty commit, // typically because it has already been applied to the target branch. - UserRevertResponse_EMPTY UserRevertResponse_CreateTreeError = 1 + UserRevertResponse_EMPTY UserRevertResponse_CreateTreeError = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CONFLICT denotes that the revert resulted in a conflict. - UserRevertResponse_CONFLICT UserRevertResponse_CreateTreeError = 2 + UserRevertResponse_CONFLICT UserRevertResponse_CreateTreeError = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for UserRevertResponse_CreateTreeError. @@ -128,24 +128,25 @@ func (x UserRevertResponse_CreateTreeError) Number() protoreflect.EnumNumber { // Deprecated: Use UserRevertResponse_CreateTreeError.Descriptor instead. func (UserRevertResponse_CreateTreeError) EnumDescriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{21, 0} + return file_operations_proto_rawDescGZIP(), []int{25, 0} } +// This comment is left unintentionally blank. type UserCommitFilesActionHeader_ActionType int32 const ( // CREATE creates a new file. - UserCommitFilesActionHeader_CREATE UserCommitFilesActionHeader_ActionType = 0 + UserCommitFilesActionHeader_CREATE UserCommitFilesActionHeader_ActionType = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // CREATE_DIR creates a new directory. - UserCommitFilesActionHeader_CREATE_DIR UserCommitFilesActionHeader_ActionType = 1 + UserCommitFilesActionHeader_CREATE_DIR UserCommitFilesActionHeader_ActionType = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // UPDATE updates an existing file. - UserCommitFilesActionHeader_UPDATE UserCommitFilesActionHeader_ActionType = 2 + UserCommitFilesActionHeader_UPDATE UserCommitFilesActionHeader_ActionType = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // MOVE moves an existing file to a new path. - UserCommitFilesActionHeader_MOVE UserCommitFilesActionHeader_ActionType = 3 + UserCommitFilesActionHeader_MOVE UserCommitFilesActionHeader_ActionType = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // DELETE deletes an existing file. - UserCommitFilesActionHeader_DELETE UserCommitFilesActionHeader_ActionType = 4 + UserCommitFilesActionHeader_DELETE UserCommitFilesActionHeader_ActionType = 4 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CHMOD changes the permissions of an existing file. - UserCommitFilesActionHeader_CHMOD UserCommitFilesActionHeader_ActionType = 5 + UserCommitFilesActionHeader_CHMOD UserCommitFilesActionHeader_ActionType = 5 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for UserCommitFilesActionHeader_ActionType. @@ -192,18 +193,23 @@ func (x UserCommitFilesActionHeader_ActionType) Number() protoreflect.EnumNumber // Deprecated: Use UserCommitFilesActionHeader_ActionType.Descriptor instead. func (UserCommitFilesActionHeader_ActionType) EnumDescriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{22, 0} + return file_operations_proto_rawDescGZIP(), []int{26, 0} } +// This comment is left unintentionally blank. type UserCreateBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` - StartPoint []byte `protobuf:"bytes,4,opt,name=start_point,json=startPoint,proto3" json:"start_point,omitempty"` + // This comment is left unintentionally blank. + BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` + // This comment is left unintentionally blank. + User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + // This comment is left unintentionally blank. + StartPoint []byte `protobuf:"bytes,4,opt,name=start_point,json=startPoint,proto3" json:"start_point,omitempty"` } func (x *UserCreateBranchRequest) Reset() { @@ -266,11 +272,13 @@ func (x *UserCreateBranchRequest) GetStartPoint() []byte { return nil } +// This comment is left unintentionally blank. type UserCreateBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Branch *Branch `protobuf:"bytes,1,opt,name=branch,proto3" json:"branch,omitempty"` // Error returned by the pre-receive hook. If no error was thrown, // it's the empty string ("") @@ -323,22 +331,98 @@ func (x *UserCreateBranchResponse) GetPreReceiveError() string { return "" } +// UserCreateBranchError is an error returned by the UserCreateBranch RPC in some specific well +// defined error cases. +type UserCreateBranchError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *UserCreateBranchError_CustomHook + Error isUserCreateBranchError_Error `protobuf_oneof:"error"` +} + +func (x *UserCreateBranchError) Reset() { + *x = UserCreateBranchError{} + if protoimpl.UnsafeEnabled { + mi := &file_operations_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserCreateBranchError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserCreateBranchError) ProtoMessage() {} + +func (x *UserCreateBranchError) ProtoReflect() protoreflect.Message { + mi := &file_operations_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserCreateBranchError.ProtoReflect.Descriptor instead. +func (*UserCreateBranchError) Descriptor() ([]byte, []int) { + return file_operations_proto_rawDescGZIP(), []int{2} +} + +func (m *UserCreateBranchError) GetError() isUserCreateBranchError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *UserCreateBranchError) GetCustomHook() *CustomHookError { + if x, ok := x.GetError().(*UserCreateBranchError_CustomHook); ok { + return x.CustomHook + } + return nil +} + +type isUserCreateBranchError_Error interface { + isUserCreateBranchError_Error() +} + +type UserCreateBranchError_CustomHook struct { + // CustomHookError is set if any custom hook which has running as part of + // this RPC call has returned a non-zero exit code. + CustomHook *CustomHookError `protobuf:"bytes,1,opt,name=custom_hook,json=customHook,proto3,oneof"` +} + +func (*UserCreateBranchError_CustomHook) isUserCreateBranchError_Error() {} + +// This comment is left unintentionally blank. type UserUpdateBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` - Newrev []byte `protobuf:"bytes,4,opt,name=newrev,proto3" json:"newrev,omitempty"` - Oldrev []byte `protobuf:"bytes,5,opt,name=oldrev,proto3" json:"oldrev,omitempty"` + // This comment is left unintentionally blank. + BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` + // This comment is left unintentionally blank. + User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + // This comment is left unintentionally blank. + Newrev []byte `protobuf:"bytes,4,opt,name=newrev,proto3" json:"newrev,omitempty"` + // This comment is left unintentionally blank. + Oldrev []byte `protobuf:"bytes,5,opt,name=oldrev,proto3" json:"oldrev,omitempty"` } func (x *UserUpdateBranchRequest) Reset() { *x = UserUpdateBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[2] + mi := &file_operations_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -351,7 +435,7 @@ func (x *UserUpdateBranchRequest) String() string { func (*UserUpdateBranchRequest) ProtoMessage() {} func (x *UserUpdateBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[2] + mi := &file_operations_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -364,7 +448,7 @@ func (x *UserUpdateBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserUpdateBranchRequest.ProtoReflect.Descriptor instead. func (*UserUpdateBranchRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{2} + return file_operations_proto_rawDescGZIP(), []int{3} } func (x *UserUpdateBranchRequest) GetRepository() *Repository { @@ -402,18 +486,20 @@ func (x *UserUpdateBranchRequest) GetOldrev() []byte { return nil } +// This comment is left unintentionally blank. type UserUpdateBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. PreReceiveError string `protobuf:"bytes,1,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserUpdateBranchResponse) Reset() { *x = UserUpdateBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[3] + mi := &file_operations_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -426,7 +512,7 @@ func (x *UserUpdateBranchResponse) String() string { func (*UserUpdateBranchResponse) ProtoMessage() {} func (x *UserUpdateBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[3] + mi := &file_operations_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -439,7 +525,7 @@ func (x *UserUpdateBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserUpdateBranchResponse.ProtoReflect.Descriptor instead. func (*UserUpdateBranchResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{3} + return file_operations_proto_rawDescGZIP(), []int{4} } func (x *UserUpdateBranchResponse) GetPreReceiveError() string { @@ -449,20 +535,28 @@ func (x *UserUpdateBranchResponse) GetPreReceiveError() string { return "" } +// UserDeleteBranchRequest is a request for the UserDeleteBranch RPC. type UserDeleteBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Repository is the repository to delete the branch in. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + // BranchName is the name of the branch that shall be deleted. This is expected to be the branch + // name only, e.g. in case you want to delete `refs/heads/main` the request needs to only contain + // `main` as the branch name. + BranchName []byte `protobuf:"bytes,2,opt,name=branch_name,json=branchName,proto3" json:"branch_name,omitempty"` + // User is the user on whose behalf we should delete the branch. This information is used to + // perform access checks against the Rails `/internal/allowed` API. This user is also exposed to + // any custom hooks executed as part of this RPC call. + User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` } func (x *UserDeleteBranchRequest) Reset() { *x = UserDeleteBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[4] + mi := &file_operations_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -475,7 +569,7 @@ func (x *UserDeleteBranchRequest) String() string { func (*UserDeleteBranchRequest) ProtoMessage() {} func (x *UserDeleteBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[4] + mi := &file_operations_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -488,7 +582,7 @@ func (x *UserDeleteBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserDeleteBranchRequest.ProtoReflect.Descriptor instead. func (*UserDeleteBranchRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{4} + return file_operations_proto_rawDescGZIP(), []int{5} } func (x *UserDeleteBranchRequest) GetRepository() *Repository { @@ -512,18 +606,23 @@ func (x *UserDeleteBranchRequest) GetUser() *User { return nil } +// UserDeleteBranchResponse is a response for the UserDeleteBranch RPC. type UserDeleteBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // PreReceiveError is never set anymore. This RPC will instead return a UserDeleteBranchError for + // a subset of well-defined error cases. + // + // Deprecated: Do not use. PreReceiveError string `protobuf:"bytes,1,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserDeleteBranchResponse) Reset() { *x = UserDeleteBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[5] + mi := &file_operations_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -536,7 +635,7 @@ func (x *UserDeleteBranchResponse) String() string { func (*UserDeleteBranchResponse) ProtoMessage() {} func (x *UserDeleteBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[5] + mi := &file_operations_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -549,9 +648,10 @@ func (x *UserDeleteBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserDeleteBranchResponse.ProtoReflect.Descriptor instead. func (*UserDeleteBranchResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{5} + return file_operations_proto_rawDescGZIP(), []int{6} } +// Deprecated: Do not use. func (x *UserDeleteBranchResponse) GetPreReceiveError() string { if x != nil { return x.PreReceiveError @@ -559,20 +659,125 @@ func (x *UserDeleteBranchResponse) GetPreReceiveError() string { return "" } +// UserDeleteBranchError is an error returned by the UserDeleteBranch RPC in some specific well +// defined error cases. +type UserDeleteBranchError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *UserDeleteBranchError_AccessCheck + // *UserDeleteBranchError_ReferenceUpdate + // *UserDeleteBranchError_CustomHook + Error isUserDeleteBranchError_Error `protobuf_oneof:"error"` +} + +func (x *UserDeleteBranchError) Reset() { + *x = UserDeleteBranchError{} + if protoimpl.UnsafeEnabled { + mi := &file_operations_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserDeleteBranchError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserDeleteBranchError) ProtoMessage() {} + +func (x *UserDeleteBranchError) ProtoReflect() protoreflect.Message { + mi := &file_operations_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserDeleteBranchError.ProtoReflect.Descriptor instead. +func (*UserDeleteBranchError) Descriptor() ([]byte, []int) { + return file_operations_proto_rawDescGZIP(), []int{7} +} + +func (m *UserDeleteBranchError) GetError() isUserDeleteBranchError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *UserDeleteBranchError) GetAccessCheck() *AccessCheckError { + if x, ok := x.GetError().(*UserDeleteBranchError_AccessCheck); ok { + return x.AccessCheck + } + return nil +} + +func (x *UserDeleteBranchError) GetReferenceUpdate() *ReferenceUpdateError { + if x, ok := x.GetError().(*UserDeleteBranchError_ReferenceUpdate); ok { + return x.ReferenceUpdate + } + return nil +} + +func (x *UserDeleteBranchError) GetCustomHook() *CustomHookError { + if x, ok := x.GetError().(*UserDeleteBranchError_CustomHook); ok { + return x.CustomHook + } + return nil +} + +type isUserDeleteBranchError_Error interface { + isUserDeleteBranchError_Error() +} + +type UserDeleteBranchError_AccessCheck struct { + // AccessCheckError is set if the RPC failed because `/internal/allowed` failed. + AccessCheck *AccessCheckError `protobuf:"bytes,1,opt,name=access_check,json=accessCheck,proto3,oneof"` +} + +type UserDeleteBranchError_ReferenceUpdate struct { + // ReferenceUpdateError is set if the RPC failed because updating the + // reference to the new object ID has failed. + ReferenceUpdate *ReferenceUpdateError `protobuf:"bytes,2,opt,name=reference_update,json=referenceUpdate,proto3,oneof"` +} + +type UserDeleteBranchError_CustomHook struct { + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHook *CustomHookError `protobuf:"bytes,3,opt,name=custom_hook,json=customHook,proto3,oneof"` +} + +func (*UserDeleteBranchError_AccessCheck) isUserDeleteBranchError_Error() {} + +func (*UserDeleteBranchError_ReferenceUpdate) isUserDeleteBranchError_Error() {} + +func (*UserDeleteBranchError_CustomHook) isUserDeleteBranchError_Error() {} + +// This comment is left unintentionally blank. type UserDeleteTagRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - TagName []byte `protobuf:"bytes,2,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + // This comment is left unintentionally blank. + TagName []byte `protobuf:"bytes,2,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"` + // This comment is left unintentionally blank. + User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` } func (x *UserDeleteTagRequest) Reset() { *x = UserDeleteTagRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[6] + mi := &file_operations_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -585,7 +790,7 @@ func (x *UserDeleteTagRequest) String() string { func (*UserDeleteTagRequest) ProtoMessage() {} func (x *UserDeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[6] + mi := &file_operations_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -598,7 +803,7 @@ func (x *UserDeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserDeleteTagRequest.ProtoReflect.Descriptor instead. func (*UserDeleteTagRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{6} + return file_operations_proto_rawDescGZIP(), []int{8} } func (x *UserDeleteTagRequest) GetRepository() *Repository { @@ -622,18 +827,20 @@ func (x *UserDeleteTagRequest) GetUser() *User { return nil } +// This comment is left unintentionally blank. type UserDeleteTagResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. PreReceiveError string `protobuf:"bytes,1,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserDeleteTagResponse) Reset() { *x = UserDeleteTagResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[7] + mi := &file_operations_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -646,7 +853,7 @@ func (x *UserDeleteTagResponse) String() string { func (*UserDeleteTagResponse) ProtoMessage() {} func (x *UserDeleteTagResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[7] + mi := &file_operations_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -659,7 +866,7 @@ func (x *UserDeleteTagResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserDeleteTagResponse.ProtoReflect.Descriptor instead. func (*UserDeleteTagResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{7} + return file_operations_proto_rawDescGZIP(), []int{9} } func (x *UserDeleteTagResponse) GetPreReceiveError() string { @@ -669,32 +876,36 @@ func (x *UserDeleteTagResponse) GetPreReceiveError() string { return "" } +// UserCreateTagRequest is a request for the UserCreateTag RPC. type UserCreateTagRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // repository is the repository in which the tag shall be created. + // Repository is the repository in which the tag shall be created. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - // tag_name is the name of the tag that shall be created. + // TagName is the name of the tag that shall be created. Note that this should be set to the name + // only: if you want to create a tag `refs/heads/v1.0`, you need to pass `v1.0` as TagName. TagName []byte `protobuf:"bytes,2,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"` - // user is the user as which the tag shall be created. + // User is the user as which the tag shall be created. This user is used to perform access checks + // against Rails' `/internal/allowed` endpoint. User *User `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` - // target_revision is the revision which the tag should point to. + // TargetRevision is the revision that the newly created tag should be pointing to. Note that if + // the revision points to a tag, that tag will be peeled to the commit it is pointing to. If the + // TargetRevision does not point to a commit then the RPC will return an error. TargetRevision []byte `protobuf:"bytes,4,opt,name=target_revision,json=targetRevision,proto3" json:"target_revision,omitempty"` - // message is the message of the tag. If it is empty, a lightweight tag is - // created. Otherwise, an annotated tag is created. + // Message is the message of the tag. If it is empty, a lightweight tag is created. Otherwise, an + // annotated tag is created. Message []byte `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` - // timestamp is the optional timestamp to use for the created tag tags. If - // it's not set, the current time will be used. It's only used if an - // annotated tag is being created. + // Timestamp is the optional timestamp to use for the created tag tags. If it's not set, the + // current time will be used. It's only used if an annotated tag is being created. Timestamp *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` } func (x *UserCreateTagRequest) Reset() { *x = UserCreateTagRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[8] + mi := &file_operations_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -707,7 +918,7 @@ func (x *UserCreateTagRequest) String() string { func (*UserCreateTagRequest) ProtoMessage() {} func (x *UserCreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[8] + mi := &file_operations_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -720,7 +931,7 @@ func (x *UserCreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCreateTagRequest.ProtoReflect.Descriptor instead. func (*UserCreateTagRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{8} + return file_operations_proto_rawDescGZIP(), []int{10} } func (x *UserCreateTagRequest) GetRepository() *Repository { @@ -765,6 +976,7 @@ func (x *UserCreateTagRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// UserCreateTagResponse is a response for the UserCreateTag RPC. type UserCreateTagResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -782,7 +994,7 @@ type UserCreateTagResponse struct { func (x *UserCreateTagResponse) Reset() { *x = UserCreateTagResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[9] + mi := &file_operations_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -795,7 +1007,7 @@ func (x *UserCreateTagResponse) String() string { func (*UserCreateTagResponse) ProtoMessage() {} func (x *UserCreateTagResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[9] + mi := &file_operations_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -808,7 +1020,7 @@ func (x *UserCreateTagResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCreateTagResponse.ProtoReflect.Descriptor instead. func (*UserCreateTagResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{9} + return file_operations_proto_rawDescGZIP(), []int{11} } func (x *UserCreateTagResponse) GetTag() *Tag { @@ -832,6 +1044,123 @@ func (x *UserCreateTagResponse) GetPreReceiveError() string { return "" } +// UserCreateTagError includes error descriptions which may be set as error details in case +// UserCreateTag fails. +type UserCreateTagError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *UserCreateTagError_AccessCheck + // *UserCreateTagError_ReferenceUpdate + // *UserCreateTagError_CustomHook + // *UserCreateTagError_ReferenceExists + Error isUserCreateTagError_Error `protobuf_oneof:"error"` +} + +func (x *UserCreateTagError) Reset() { + *x = UserCreateTagError{} + if protoimpl.UnsafeEnabled { + mi := &file_operations_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserCreateTagError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserCreateTagError) ProtoMessage() {} + +func (x *UserCreateTagError) ProtoReflect() protoreflect.Message { + mi := &file_operations_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserCreateTagError.ProtoReflect.Descriptor instead. +func (*UserCreateTagError) Descriptor() ([]byte, []int) { + return file_operations_proto_rawDescGZIP(), []int{12} +} + +func (m *UserCreateTagError) GetError() isUserCreateTagError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *UserCreateTagError) GetAccessCheck() *AccessCheckError { + if x, ok := x.GetError().(*UserCreateTagError_AccessCheck); ok { + return x.AccessCheck + } + return nil +} + +func (x *UserCreateTagError) GetReferenceUpdate() *ReferenceUpdateError { + if x, ok := x.GetError().(*UserCreateTagError_ReferenceUpdate); ok { + return x.ReferenceUpdate + } + return nil +} + +func (x *UserCreateTagError) GetCustomHook() *CustomHookError { + if x, ok := x.GetError().(*UserCreateTagError_CustomHook); ok { + return x.CustomHook + } + return nil +} + +func (x *UserCreateTagError) GetReferenceExists() *ReferenceExistsError { + if x, ok := x.GetError().(*UserCreateTagError_ReferenceExists); ok { + return x.ReferenceExists + } + return nil +} + +type isUserCreateTagError_Error interface { + isUserCreateTagError_Error() +} + +type UserCreateTagError_AccessCheck struct { + // AccessCheckError is set if the RPC failed because `/internal/allowed` failed. + AccessCheck *AccessCheckError `protobuf:"bytes,1,opt,name=access_check,json=accessCheck,proto3,oneof"` +} + +type UserCreateTagError_ReferenceUpdate struct { + // ReferenceUpdateError is set if the RPC failed because updating the + // reference to the new object ID has failed. + ReferenceUpdate *ReferenceUpdateError `protobuf:"bytes,2,opt,name=reference_update,json=referenceUpdate,proto3,oneof"` +} + +type UserCreateTagError_CustomHook struct { + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHook *CustomHookError `protobuf:"bytes,3,opt,name=custom_hook,json=customHook,proto3,oneof"` +} + +type UserCreateTagError_ReferenceExists struct { + // ReferenceExistsError is set if the tag reference exists already. + ReferenceExists *ReferenceExistsError `protobuf:"bytes,4,opt,name=reference_exists,json=referenceExists,proto3,oneof"` +} + +func (*UserCreateTagError_AccessCheck) isUserCreateTagError_Error() {} + +func (*UserCreateTagError_ReferenceUpdate) isUserCreateTagError_Error() {} + +func (*UserCreateTagError_CustomHook) isUserCreateTagError_Error() {} + +func (*UserCreateTagError_ReferenceExists) isUserCreateTagError_Error() {} + +// This comment is left unintentionally blank. type UserMergeBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -862,7 +1191,7 @@ type UserMergeBranchRequest struct { func (x *UserMergeBranchRequest) Reset() { *x = UserMergeBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[10] + mi := &file_operations_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -875,7 +1204,7 @@ func (x *UserMergeBranchRequest) String() string { func (*UserMergeBranchRequest) ProtoMessage() {} func (x *UserMergeBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[10] + mi := &file_operations_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -888,7 +1217,7 @@ func (x *UserMergeBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMergeBranchRequest.ProtoReflect.Descriptor instead. func (*UserMergeBranchRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{10} + return file_operations_proto_rawDescGZIP(), []int{13} } func (x *UserMergeBranchRequest) GetRepository() *Repository { @@ -940,6 +1269,7 @@ func (x *UserMergeBranchRequest) GetApply() bool { return false } +// This comment is left unintentionally blank. type UserMergeBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -951,17 +1281,12 @@ type UserMergeBranchResponse struct { // Second message // If set, the merge has been applied to the branch. BranchUpdate *OperationBranchUpdate `protobuf:"bytes,3,opt,name=branch_update,json=branchUpdate,proto3" json:"branch_update,omitempty"` - // PreReceiveError is never set. Instead, we return a proper gRPC error with - // UserMergeBranchError details set to an AccessCheckError. - // - // Deprecated: Do not use. - PreReceiveError string `protobuf:"bytes,4,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserMergeBranchResponse) Reset() { *x = UserMergeBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[11] + mi := &file_operations_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -974,7 +1299,7 @@ func (x *UserMergeBranchResponse) String() string { func (*UserMergeBranchResponse) ProtoMessage() {} func (x *UserMergeBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[11] + mi := &file_operations_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -987,7 +1312,7 @@ func (x *UserMergeBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMergeBranchResponse.ProtoReflect.Descriptor instead. func (*UserMergeBranchResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{11} + return file_operations_proto_rawDescGZIP(), []int{14} } func (x *UserMergeBranchResponse) GetCommitId() string { @@ -1004,14 +1329,6 @@ func (x *UserMergeBranchResponse) GetBranchUpdate() *OperationBranchUpdate { return nil } -// Deprecated: Do not use. -func (x *UserMergeBranchResponse) GetPreReceiveError() string { - if x != nil { - return x.PreReceiveError - } - return "" -} - // UserMergeBranchError includes error descriptions which may be set as error // details in case UserMergeBranch fails. type UserMergeBranchError struct { @@ -1022,13 +1339,15 @@ type UserMergeBranchError struct { // Types that are assignable to Error: // *UserMergeBranchError_AccessCheck // *UserMergeBranchError_ReferenceUpdate + // *UserMergeBranchError_CustomHook + // *UserMergeBranchError_MergeConflict Error isUserMergeBranchError_Error `protobuf_oneof:"error"` } func (x *UserMergeBranchError) Reset() { *x = UserMergeBranchError{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[12] + mi := &file_operations_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1041,7 +1360,7 @@ func (x *UserMergeBranchError) String() string { func (*UserMergeBranchError) ProtoMessage() {} func (x *UserMergeBranchError) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[12] + mi := &file_operations_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1054,7 +1373,7 @@ func (x *UserMergeBranchError) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMergeBranchError.ProtoReflect.Descriptor instead. func (*UserMergeBranchError) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{12} + return file_operations_proto_rawDescGZIP(), []int{15} } func (m *UserMergeBranchError) GetError() isUserMergeBranchError_Error { @@ -1078,6 +1397,20 @@ func (x *UserMergeBranchError) GetReferenceUpdate() *ReferenceUpdateError { return nil } +func (x *UserMergeBranchError) GetCustomHook() *CustomHookError { + if x, ok := x.GetError().(*UserMergeBranchError_CustomHook); ok { + return x.CustomHook + } + return nil +} + +func (x *UserMergeBranchError) GetMergeConflict() *MergeConflictError { + if x, ok := x.GetError().(*UserMergeBranchError_MergeConflict); ok { + return x.MergeConflict + } + return nil +} + type isUserMergeBranchError_Error interface { isUserMergeBranchError_Error() } @@ -1093,10 +1426,26 @@ type UserMergeBranchError_ReferenceUpdate struct { ReferenceUpdate *ReferenceUpdateError `protobuf:"bytes,2,opt,name=reference_update,json=referenceUpdate,proto3,oneof"` } +type UserMergeBranchError_CustomHook struct { + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHook *CustomHookError `protobuf:"bytes,3,opt,name=custom_hook,json=customHook,proto3,oneof"` +} + +type UserMergeBranchError_MergeConflict struct { + // MergeConflictError is set if merging the revisions has resulted in conflicting files. + MergeConflict *MergeConflictError `protobuf:"bytes,4,opt,name=merge_conflict,json=mergeConflict,proto3,oneof"` +} + func (*UserMergeBranchError_AccessCheck) isUserMergeBranchError_Error() {} func (*UserMergeBranchError_ReferenceUpdate) isUserMergeBranchError_Error() {} +func (*UserMergeBranchError_CustomHook) isUserMergeBranchError_Error() {} + +func (*UserMergeBranchError_MergeConflict) isUserMergeBranchError_Error() {} + +// This comment is left unintentionally blank. type UserMergeToRefRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1133,7 +1482,7 @@ type UserMergeToRefRequest struct { func (x *UserMergeToRefRequest) Reset() { *x = UserMergeToRefRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[13] + mi := &file_operations_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1146,7 +1495,7 @@ func (x *UserMergeToRefRequest) String() string { func (*UserMergeToRefRequest) ProtoMessage() {} func (x *UserMergeToRefRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[13] + mi := &file_operations_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1159,7 +1508,7 @@ func (x *UserMergeToRefRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMergeToRefRequest.ProtoReflect.Descriptor instead. func (*UserMergeToRefRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{13} + return file_operations_proto_rawDescGZIP(), []int{16} } func (x *UserMergeToRefRequest) GetRepository() *Repository { @@ -1225,6 +1574,7 @@ func (x *UserMergeToRefRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// This comment is left unintentionally blank. type UserMergeToRefResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1232,17 +1582,12 @@ type UserMergeToRefResponse struct { // commit_id is the object ID of the computed merge commit. CommitId string `protobuf:"bytes,1,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` - // PreReceiveError is never set because this RPC does not perform - // authentication via `/internal/allowed`. - // - // Deprecated: Do not use. - PreReceiveError string `protobuf:"bytes,2,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserMergeToRefResponse) Reset() { *x = UserMergeToRefResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[14] + mi := &file_operations_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1255,7 +1600,7 @@ func (x *UserMergeToRefResponse) String() string { func (*UserMergeToRefResponse) ProtoMessage() {} func (x *UserMergeToRefResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[14] + mi := &file_operations_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1268,7 +1613,7 @@ func (x *UserMergeToRefResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMergeToRefResponse.ProtoReflect.Descriptor instead. func (*UserMergeToRefResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{14} + return file_operations_proto_rawDescGZIP(), []int{17} } func (x *UserMergeToRefResponse) GetCommitId() string { @@ -1278,14 +1623,6 @@ func (x *UserMergeToRefResponse) GetCommitId() string { return "" } -// Deprecated: Do not use. -func (x *UserMergeToRefResponse) GetPreReceiveError() string { - if x != nil { - return x.PreReceiveError - } - return "" -} - // OperationBranchUpdate contains the details of a branch update. type OperationBranchUpdate struct { state protoimpl.MessageState @@ -1305,7 +1642,7 @@ type OperationBranchUpdate struct { func (x *OperationBranchUpdate) Reset() { *x = OperationBranchUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[15] + mi := &file_operations_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1318,7 +1655,7 @@ func (x *OperationBranchUpdate) String() string { func (*OperationBranchUpdate) ProtoMessage() {} func (x *OperationBranchUpdate) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[15] + mi := &file_operations_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1331,7 +1668,7 @@ func (x *OperationBranchUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationBranchUpdate.ProtoReflect.Descriptor instead. func (*OperationBranchUpdate) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{15} + return file_operations_proto_rawDescGZIP(), []int{18} } func (x *OperationBranchUpdate) GetCommitId() string { @@ -1377,7 +1714,7 @@ type UserFFBranchRequest struct { func (x *UserFFBranchRequest) Reset() { *x = UserFFBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[16] + mi := &file_operations_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1390,7 +1727,7 @@ func (x *UserFFBranchRequest) String() string { func (*UserFFBranchRequest) ProtoMessage() {} func (x *UserFFBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[16] + mi := &file_operations_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1403,7 +1740,7 @@ func (x *UserFFBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserFFBranchRequest.ProtoReflect.Descriptor instead. func (*UserFFBranchRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{16} + return file_operations_proto_rawDescGZIP(), []int{19} } func (x *UserFFBranchRequest) GetRepository() *Repository { @@ -1434,19 +1771,22 @@ func (x *UserFFBranchRequest) GetBranch() []byte { return nil } +// This comment is left unintentionally blank. type UserFFBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BranchUpdate *OperationBranchUpdate `protobuf:"bytes,1,opt,name=branch_update,json=branchUpdate,proto3" json:"branch_update,omitempty"` - PreReceiveError string `protobuf:"bytes,2,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` + // This comment is left unintentionally blank. + BranchUpdate *OperationBranchUpdate `protobuf:"bytes,1,opt,name=branch_update,json=branchUpdate,proto3" json:"branch_update,omitempty"` + // This comment is left unintentionally blank. + PreReceiveError string `protobuf:"bytes,2,opt,name=pre_receive_error,json=preReceiveError,proto3" json:"pre_receive_error,omitempty"` } func (x *UserFFBranchResponse) Reset() { *x = UserFFBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[17] + mi := &file_operations_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1459,7 +1799,7 @@ func (x *UserFFBranchResponse) String() string { func (*UserFFBranchResponse) ProtoMessage() {} func (x *UserFFBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[17] + mi := &file_operations_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1472,7 +1812,7 @@ func (x *UserFFBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserFFBranchResponse.ProtoReflect.Descriptor instead. func (*UserFFBranchResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{17} + return file_operations_proto_rawDescGZIP(), []int{20} } func (x *UserFFBranchResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -1489,6 +1829,7 @@ func (x *UserFFBranchResponse) GetPreReceiveError() string { return "" } +// This comment is left unintentionally blank. type UserCherryPickRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1524,7 +1865,7 @@ type UserCherryPickRequest struct { func (x *UserCherryPickRequest) Reset() { *x = UserCherryPickRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[18] + mi := &file_operations_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1537,7 +1878,7 @@ func (x *UserCherryPickRequest) String() string { func (*UserCherryPickRequest) ProtoMessage() {} func (x *UserCherryPickRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[18] + mi := &file_operations_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1550,7 +1891,7 @@ func (x *UserCherryPickRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCherryPickRequest.ProtoReflect.Descriptor instead. func (*UserCherryPickRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{18} + return file_operations_proto_rawDescGZIP(), []int{21} } func (x *UserCherryPickRequest) GetRepository() *Repository { @@ -1616,6 +1957,7 @@ func (x *UserCherryPickRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// This comment is left unintentionally blank. type UserCherryPickResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1639,7 +1981,7 @@ type UserCherryPickResponse struct { func (x *UserCherryPickResponse) Reset() { *x = UserCherryPickResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[19] + mi := &file_operations_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1652,7 +1994,7 @@ func (x *UserCherryPickResponse) String() string { func (*UserCherryPickResponse) ProtoMessage() {} func (x *UserCherryPickResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[19] + mi := &file_operations_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1665,7 +2007,7 @@ func (x *UserCherryPickResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCherryPickResponse.ProtoReflect.Descriptor instead. func (*UserCherryPickResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{19} + return file_operations_proto_rawDescGZIP(), []int{22} } func (x *UserCherryPickResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -1703,6 +2045,127 @@ func (x *UserCherryPickResponse) GetCreateTreeErrorCode() UserCherryPickResponse return UserCherryPickResponse_NONE } +// UserCherryPickError is an error returned by the UserCherryPick RPC. +type UserCherryPickError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *UserCherryPickError_CherryPickConflict + // *UserCherryPickError_TargetBranchDiverged + // *UserCherryPickError_ChangesAlreadyApplied + // *UserCherryPickError_AccessCheck + Error isUserCherryPickError_Error `protobuf_oneof:"error"` +} + +func (x *UserCherryPickError) Reset() { + *x = UserCherryPickError{} + if protoimpl.UnsafeEnabled { + mi := &file_operations_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserCherryPickError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserCherryPickError) ProtoMessage() {} + +func (x *UserCherryPickError) ProtoReflect() protoreflect.Message { + mi := &file_operations_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserCherryPickError.ProtoReflect.Descriptor instead. +func (*UserCherryPickError) Descriptor() ([]byte, []int) { + return file_operations_proto_rawDescGZIP(), []int{23} +} + +func (m *UserCherryPickError) GetError() isUserCherryPickError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *UserCherryPickError) GetCherryPickConflict() *MergeConflictError { + if x, ok := x.GetError().(*UserCherryPickError_CherryPickConflict); ok { + return x.CherryPickConflict + } + return nil +} + +func (x *UserCherryPickError) GetTargetBranchDiverged() *NotAncestorError { + if x, ok := x.GetError().(*UserCherryPickError_TargetBranchDiverged); ok { + return x.TargetBranchDiverged + } + return nil +} + +func (x *UserCherryPickError) GetChangesAlreadyApplied() *ChangesAlreadyAppliedError { + if x, ok := x.GetError().(*UserCherryPickError_ChangesAlreadyApplied); ok { + return x.ChangesAlreadyApplied + } + return nil +} + +func (x *UserCherryPickError) GetAccessCheck() *AccessCheckError { + if x, ok := x.GetError().(*UserCherryPickError_AccessCheck); ok { + return x.AccessCheck + } + return nil +} + +type isUserCherryPickError_Error interface { + isUserCherryPickError_Error() +} + +type UserCherryPickError_CherryPickConflict struct { + // CherryPickConflict is returned if there is a conflict when applying the cherry + // pick. + CherryPickConflict *MergeConflictError `protobuf:"bytes,1,opt,name=cherry_pick_conflict,json=cherryPickConflict,proto3,oneof"` +} + +type UserCherryPickError_TargetBranchDiverged struct { + // TargetBranchDiverged is returned whenever the tip commit of the branch we're + // about to apply the new commit on is not a direct ancestor of the newly created + // cherry-picked commit. This may happen either due to a race where the reference + // is modified while we compute the cherry-picked commit, or alternatively if the + // commit fetched from the start branch of the remote repository is not an ancestor + // of of the local target branch. + TargetBranchDiverged *NotAncestorError `protobuf:"bytes,2,opt,name=target_branch_diverged,json=targetBranchDiverged,proto3,oneof"` +} + +type UserCherryPickError_ChangesAlreadyApplied struct { + // ChangesAlreadyApplied is returned if the result after applying the cherry pick is empty. + ChangesAlreadyApplied *ChangesAlreadyAppliedError `protobuf:"bytes,3,opt,name=changes_already_applied,json=changesAlreadyApplied,proto3,oneof"` +} + +type UserCherryPickError_AccessCheck struct { + // AccessCheck is returned in case GitLab's `/internal/allowed` endpoint rejected + // the change. + AccessCheck *AccessCheckError `protobuf:"bytes,4,opt,name=access_check,json=accessCheck,proto3,oneof"` +} + +func (*UserCherryPickError_CherryPickConflict) isUserCherryPickError_Error() {} + +func (*UserCherryPickError_TargetBranchDiverged) isUserCherryPickError_Error() {} + +func (*UserCherryPickError_ChangesAlreadyApplied) isUserCherryPickError_Error() {} + +func (*UserCherryPickError_AccessCheck) isUserCherryPickError_Error() {} + +// This comment is left unintentionally blank. type UserRevertRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1737,7 +2200,7 @@ type UserRevertRequest struct { func (x *UserRevertRequest) Reset() { *x = UserRevertRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[20] + mi := &file_operations_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1750,7 +2213,7 @@ func (x *UserRevertRequest) String() string { func (*UserRevertRequest) ProtoMessage() {} func (x *UserRevertRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[20] + mi := &file_operations_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1763,7 +2226,7 @@ func (x *UserRevertRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserRevertRequest.ProtoReflect.Descriptor instead. func (*UserRevertRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{20} + return file_operations_proto_rawDescGZIP(), []int{24} } func (x *UserRevertRequest) GetRepository() *Repository { @@ -1829,6 +2292,7 @@ func (x *UserRevertRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// This comment is left unintentionally blank. type UserRevertResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1852,7 +2316,7 @@ type UserRevertResponse struct { func (x *UserRevertResponse) Reset() { *x = UserRevertResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[21] + mi := &file_operations_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1865,7 +2329,7 @@ func (x *UserRevertResponse) String() string { func (*UserRevertResponse) ProtoMessage() {} func (x *UserRevertResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[21] + mi := &file_operations_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1878,7 +2342,7 @@ func (x *UserRevertResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserRevertResponse.ProtoReflect.Descriptor instead. func (*UserRevertResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{21} + return file_operations_proto_rawDescGZIP(), []int{25} } func (x *UserRevertResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -1952,7 +2416,7 @@ type UserCommitFilesActionHeader struct { func (x *UserCommitFilesActionHeader) Reset() { *x = UserCommitFilesActionHeader{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[22] + mi := &file_operations_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1965,7 +2429,7 @@ func (x *UserCommitFilesActionHeader) String() string { func (*UserCommitFilesActionHeader) ProtoMessage() {} func (x *UserCommitFilesActionHeader) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[22] + mi := &file_operations_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1978,7 +2442,7 @@ func (x *UserCommitFilesActionHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCommitFilesActionHeader.ProtoReflect.Descriptor instead. func (*UserCommitFilesActionHeader) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{22} + return file_operations_proto_rawDescGZIP(), []int{26} } func (x *UserCommitFilesActionHeader) GetAction() UserCommitFilesActionHeader_ActionType { @@ -2038,7 +2502,7 @@ type UserCommitFilesAction struct { func (x *UserCommitFilesAction) Reset() { *x = UserCommitFilesAction{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[23] + mi := &file_operations_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2051,7 +2515,7 @@ func (x *UserCommitFilesAction) String() string { func (*UserCommitFilesAction) ProtoMessage() {} func (x *UserCommitFilesAction) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[23] + mi := &file_operations_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2064,7 +2528,7 @@ func (x *UserCommitFilesAction) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCommitFilesAction.ProtoReflect.Descriptor instead. func (*UserCommitFilesAction) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{23} + return file_operations_proto_rawDescGZIP(), []int{27} } func (m *UserCommitFilesAction) GetUserCommitFilesActionPayload() isUserCommitFilesAction_UserCommitFilesActionPayload { @@ -2150,7 +2614,7 @@ type UserCommitFilesRequestHeader struct { func (x *UserCommitFilesRequestHeader) Reset() { *x = UserCommitFilesRequestHeader{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[24] + mi := &file_operations_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2163,7 +2627,7 @@ func (x *UserCommitFilesRequestHeader) String() string { func (*UserCommitFilesRequestHeader) ProtoMessage() {} func (x *UserCommitFilesRequestHeader) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[24] + mi := &file_operations_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2176,7 +2640,7 @@ func (x *UserCommitFilesRequestHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCommitFilesRequestHeader.ProtoReflect.Descriptor instead. func (*UserCommitFilesRequestHeader) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{24} + return file_operations_proto_rawDescGZIP(), []int{28} } func (x *UserCommitFilesRequestHeader) GetRepository() *Repository { @@ -2271,7 +2735,7 @@ type UserCommitFilesRequest struct { func (x *UserCommitFilesRequest) Reset() { *x = UserCommitFilesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[25] + mi := &file_operations_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2284,7 +2748,7 @@ func (x *UserCommitFilesRequest) String() string { func (*UserCommitFilesRequest) ProtoMessage() {} func (x *UserCommitFilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[25] + mi := &file_operations_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2297,7 +2761,7 @@ func (x *UserCommitFilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCommitFilesRequest.ProtoReflect.Descriptor instead. func (*UserCommitFilesRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{25} + return file_operations_proto_rawDescGZIP(), []int{29} } func (m *UserCommitFilesRequest) GetUserCommitFilesRequestPayload() isUserCommitFilesRequest_UserCommitFilesRequestPayload { @@ -2358,7 +2822,7 @@ type UserCommitFilesResponse struct { func (x *UserCommitFilesResponse) Reset() { *x = UserCommitFilesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[26] + mi := &file_operations_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2371,7 +2835,7 @@ func (x *UserCommitFilesResponse) String() string { func (*UserCommitFilesResponse) ProtoMessage() {} func (x *UserCommitFilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[26] + mi := &file_operations_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2384,7 +2848,7 @@ func (x *UserCommitFilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserCommitFilesResponse.ProtoReflect.Descriptor instead. func (*UserCommitFilesResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{26} + return file_operations_proto_rawDescGZIP(), []int{30} } func (x *UserCommitFilesResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -2408,6 +2872,7 @@ func (x *UserCommitFilesResponse) GetPreReceiveError() string { return "" } +// This comment is left unintentionally blank. type UserRebaseConfirmableRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2422,7 +2887,7 @@ type UserRebaseConfirmableRequest struct { func (x *UserRebaseConfirmableRequest) Reset() { *x = UserRebaseConfirmableRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[27] + mi := &file_operations_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2435,7 +2900,7 @@ func (x *UserRebaseConfirmableRequest) String() string { func (*UserRebaseConfirmableRequest) ProtoMessage() {} func (x *UserRebaseConfirmableRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[27] + mi := &file_operations_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2448,7 +2913,7 @@ func (x *UserRebaseConfirmableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserRebaseConfirmableRequest.ProtoReflect.Descriptor instead. func (*UserRebaseConfirmableRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{27} + return file_operations_proto_rawDescGZIP(), []int{31} } func (m *UserRebaseConfirmableRequest) GetUserRebaseConfirmableRequestPayload() isUserRebaseConfirmableRequest_UserRebaseConfirmableRequestPayload { @@ -2494,6 +2959,7 @@ func (*UserRebaseConfirmableRequest_Header_) isUserRebaseConfirmableRequest_User func (*UserRebaseConfirmableRequest_Apply) isUserRebaseConfirmableRequest_UserRebaseConfirmableRequestPayload() { } +// This comment is left unintentionally blank. type UserRebaseConfirmableResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2513,7 +2979,7 @@ type UserRebaseConfirmableResponse struct { func (x *UserRebaseConfirmableResponse) Reset() { *x = UserRebaseConfirmableResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[28] + mi := &file_operations_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2526,7 +2992,7 @@ func (x *UserRebaseConfirmableResponse) String() string { func (*UserRebaseConfirmableResponse) ProtoMessage() {} func (x *UserRebaseConfirmableResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[28] + mi := &file_operations_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2539,7 +3005,7 @@ func (x *UserRebaseConfirmableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserRebaseConfirmableResponse.ProtoReflect.Descriptor instead. func (*UserRebaseConfirmableResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{28} + return file_operations_proto_rawDescGZIP(), []int{32} } func (m *UserRebaseConfirmableResponse) GetUserRebaseConfirmableResponsePayload() isUserRebaseConfirmableResponse_UserRebaseConfirmableResponsePayload { @@ -2599,6 +3065,7 @@ func (*UserRebaseConfirmableResponse_RebaseSha) isUserRebaseConfirmableResponse_ func (*UserRebaseConfirmableResponse_RebaseApplied) isUserRebaseConfirmableResponse_UserRebaseConfirmableResponsePayload() { } +// This comment is left unintentionally blank. type UserSquashRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2627,7 +3094,7 @@ type UserSquashRequest struct { func (x *UserSquashRequest) Reset() { *x = UserSquashRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[29] + mi := &file_operations_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2640,7 +3107,7 @@ func (x *UserSquashRequest) String() string { func (*UserSquashRequest) ProtoMessage() {} func (x *UserSquashRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[29] + mi := &file_operations_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2653,7 +3120,7 @@ func (x *UserSquashRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSquashRequest.ProtoReflect.Descriptor instead. func (*UserSquashRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{29} + return file_operations_proto_rawDescGZIP(), []int{33} } func (x *UserSquashRequest) GetRepository() *Repository { @@ -2705,6 +3172,7 @@ func (x *UserSquashRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// This comment is left unintentionally blank. type UserSquashResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2712,18 +3180,12 @@ type UserSquashResponse struct { // squash_sha is the object ID of the squashed commit. SquashSha string `protobuf:"bytes,1,opt,name=squash_sha,json=squashSha,proto3" json:"squash_sha,omitempty"` - // GitError is not used anymore. Instead, this RPC always returns a real - // error with an optional UserRebaseConfirmableError, which may be set on - // special errors. - // - // Deprecated: Do not use. - GitError string `protobuf:"bytes,3,opt,name=git_error,json=gitError,proto3" json:"git_error,omitempty"` } func (x *UserSquashResponse) Reset() { *x = UserSquashResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[30] + mi := &file_operations_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2736,7 +3198,7 @@ func (x *UserSquashResponse) String() string { func (*UserSquashResponse) ProtoMessage() {} func (x *UserSquashResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[30] + mi := &file_operations_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2749,7 +3211,7 @@ func (x *UserSquashResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSquashResponse.ProtoReflect.Descriptor instead. func (*UserSquashResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{30} + return file_operations_proto_rawDescGZIP(), []int{34} } func (x *UserSquashResponse) GetSquashSha() string { @@ -2759,14 +3221,7 @@ func (x *UserSquashResponse) GetSquashSha() string { return "" } -// Deprecated: Do not use. -func (x *UserSquashResponse) GetGitError() string { - if x != nil { - return x.GitError - } - return "" -} - +// This comment is left unintentionally blank. type UserRebaseConfirmableError struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2781,7 +3236,7 @@ type UserRebaseConfirmableError struct { func (x *UserRebaseConfirmableError) Reset() { *x = UserRebaseConfirmableError{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[31] + mi := &file_operations_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2794,7 +3249,7 @@ func (x *UserRebaseConfirmableError) String() string { func (*UserRebaseConfirmableError) ProtoMessage() {} func (x *UserRebaseConfirmableError) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[31] + mi := &file_operations_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2807,7 +3262,7 @@ func (x *UserRebaseConfirmableError) ProtoReflect() protoreflect.Message { // Deprecated: Use UserRebaseConfirmableError.ProtoReflect.Descriptor instead. func (*UserRebaseConfirmableError) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{31} + return file_operations_proto_rawDescGZIP(), []int{35} } func (m *UserRebaseConfirmableError) GetError() isUserRebaseConfirmableError_Error { @@ -2837,7 +3292,8 @@ type isUserRebaseConfirmableError_Error interface { type UserRebaseConfirmableError_RebaseConflict struct { // RebaseConflict is returned in case rebasing commits on top of the start - // commit fails with a merge conflict. + // commit fails with a merge conflict and in case merge squashing commits + // fails with a merge conflict. RebaseConflict *MergeConflictError `protobuf:"bytes,1,opt,name=rebase_conflict,json=rebaseConflict,proto3,oneof"` } @@ -2867,7 +3323,7 @@ type UserSquashError struct { func (x *UserSquashError) Reset() { *x = UserSquashError{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[32] + mi := &file_operations_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2880,7 +3336,7 @@ func (x *UserSquashError) String() string { func (*UserSquashError) ProtoMessage() {} func (x *UserSquashError) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[32] + mi := &file_operations_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2893,7 +3349,7 @@ func (x *UserSquashError) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSquashError.ProtoReflect.Descriptor instead. func (*UserSquashError) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{32} + return file_operations_proto_rawDescGZIP(), []int{36} } func (m *UserSquashError) GetError() isUserSquashError_Error { @@ -2937,6 +3393,7 @@ func (*UserSquashError_ResolveRevision) isUserSquashError_Error() {} func (*UserSquashError_RebaseConflict) isUserSquashError_Error() {} +// This comment is left unintentionally blank. type UserApplyPatchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2951,7 +3408,7 @@ type UserApplyPatchRequest struct { func (x *UserApplyPatchRequest) Reset() { *x = UserApplyPatchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[33] + mi := &file_operations_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2964,7 +3421,7 @@ func (x *UserApplyPatchRequest) String() string { func (*UserApplyPatchRequest) ProtoMessage() {} func (x *UserApplyPatchRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[33] + mi := &file_operations_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2977,7 +3434,7 @@ func (x *UserApplyPatchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserApplyPatchRequest.ProtoReflect.Descriptor instead. func (*UserApplyPatchRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{33} + return file_operations_proto_rawDescGZIP(), []int{37} } func (m *UserApplyPatchRequest) GetUserApplyPatchRequestPayload() isUserApplyPatchRequest_UserApplyPatchRequestPayload { @@ -3020,6 +3477,7 @@ func (*UserApplyPatchRequest_Header_) isUserApplyPatchRequest_UserApplyPatchRequ func (*UserApplyPatchRequest_Patches) isUserApplyPatchRequest_UserApplyPatchRequestPayload() {} +// This comment is left unintentionally blank. type UserApplyPatchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3032,7 +3490,7 @@ type UserApplyPatchResponse struct { func (x *UserApplyPatchResponse) Reset() { *x = UserApplyPatchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[34] + mi := &file_operations_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3045,7 +3503,7 @@ func (x *UserApplyPatchResponse) String() string { func (*UserApplyPatchResponse) ProtoMessage() {} func (x *UserApplyPatchResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[34] + mi := &file_operations_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3058,7 +3516,7 @@ func (x *UserApplyPatchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserApplyPatchResponse.ProtoReflect.Descriptor instead. func (*UserApplyPatchResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{34} + return file_operations_proto_rawDescGZIP(), []int{38} } func (x *UserApplyPatchResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -3068,6 +3526,7 @@ func (x *UserApplyPatchResponse) GetBranchUpdate() *OperationBranchUpdate { return nil } +// This comment is left unintentionally blank. type UserUpdateSubmoduleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3096,7 +3555,7 @@ type UserUpdateSubmoduleRequest struct { func (x *UserUpdateSubmoduleRequest) Reset() { *x = UserUpdateSubmoduleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[35] + mi := &file_operations_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3109,7 +3568,7 @@ func (x *UserUpdateSubmoduleRequest) String() string { func (*UserUpdateSubmoduleRequest) ProtoMessage() {} func (x *UserUpdateSubmoduleRequest) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[35] + mi := &file_operations_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3122,7 +3581,7 @@ func (x *UserUpdateSubmoduleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserUpdateSubmoduleRequest.ProtoReflect.Descriptor instead. func (*UserUpdateSubmoduleRequest) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{35} + return file_operations_proto_rawDescGZIP(), []int{39} } func (x *UserUpdateSubmoduleRequest) GetRepository() *Repository { @@ -3174,6 +3633,7 @@ func (x *UserUpdateSubmoduleRequest) GetTimestamp() *timestamppb.Timestamp { return nil } +// This comment is left unintentionally blank. type UserUpdateSubmoduleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3191,7 +3651,7 @@ type UserUpdateSubmoduleResponse struct { func (x *UserUpdateSubmoduleResponse) Reset() { *x = UserUpdateSubmoduleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[36] + mi := &file_operations_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3204,7 +3664,7 @@ func (x *UserUpdateSubmoduleResponse) String() string { func (*UserUpdateSubmoduleResponse) ProtoMessage() {} func (x *UserUpdateSubmoduleResponse) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[36] + mi := &file_operations_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3217,7 +3677,7 @@ func (x *UserUpdateSubmoduleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserUpdateSubmoduleResponse.ProtoReflect.Descriptor instead. func (*UserUpdateSubmoduleResponse) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{36} + return file_operations_proto_rawDescGZIP(), []int{40} } func (x *UserUpdateSubmoduleResponse) GetBranchUpdate() *OperationBranchUpdate { @@ -3281,7 +3741,7 @@ type UserRebaseConfirmableRequest_Header struct { func (x *UserRebaseConfirmableRequest_Header) Reset() { *x = UserRebaseConfirmableRequest_Header{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[37] + mi := &file_operations_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3294,7 +3754,7 @@ func (x *UserRebaseConfirmableRequest_Header) String() string { func (*UserRebaseConfirmableRequest_Header) ProtoMessage() {} func (x *UserRebaseConfirmableRequest_Header) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[37] + mi := &file_operations_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3307,7 +3767,7 @@ func (x *UserRebaseConfirmableRequest_Header) ProtoReflect() protoreflect.Messag // Deprecated: Use UserRebaseConfirmableRequest_Header.ProtoReflect.Descriptor instead. func (*UserRebaseConfirmableRequest_Header) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{27, 0} + return file_operations_proto_rawDescGZIP(), []int{31, 0} } func (x *UserRebaseConfirmableRequest_Header) GetRepository() *Repository { @@ -3394,7 +3854,7 @@ type UserApplyPatchRequest_Header struct { func (x *UserApplyPatchRequest_Header) Reset() { *x = UserApplyPatchRequest_Header{} if protoimpl.UnsafeEnabled { - mi := &file_operations_proto_msgTypes[38] + mi := &file_operations_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3407,7 +3867,7 @@ func (x *UserApplyPatchRequest_Header) String() string { func (*UserApplyPatchRequest_Header) ProtoMessage() {} func (x *UserApplyPatchRequest_Header) ProtoReflect() protoreflect.Message { - mi := &file_operations_proto_msgTypes[38] + mi := &file_operations_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3420,7 +3880,7 @@ func (x *UserApplyPatchRequest_Header) ProtoReflect() protoreflect.Message { // Deprecated: Use UserApplyPatchRequest_Header.ProtoReflect.Descriptor instead. func (*UserApplyPatchRequest_Header) Descriptor() ([]byte, []int) { - return file_operations_proto_rawDescGZIP(), []int{33, 0} + return file_operations_proto_rawDescGZIP(), []int{37, 0} } func (x *UserApplyPatchRequest_Header) GetRepository() *Repository { @@ -3455,11 +3915,11 @@ var File_operations_proto protoreflect.FileDescriptor var file_operations_proto_rawDesc = []byte{ 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0c, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, @@ -3478,39 +3938,73 @@ var file_operations_proto_rawDesc = []byte{ 0x6c, 0x79, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, - 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc6, 0x01, - 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x76, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x76, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x6c, 0x64, 0x72, 0x65, 0x76, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x6f, 0x6c, 0x64, 0x72, 0x65, 0x76, 0x22, 0x46, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, - 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, - 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x46, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x5c, 0x0a, + 0x15, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3a, 0x0a, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, + 0x6f, 0x6b, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc6, 0x01, 0x0a, 0x17, + 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x76, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x76, 0x12, 0x16, 0x0a, 0x06, + 0x6f, 0x6c, 0x64, 0x72, 0x65, 0x76, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x6c, + 0x64, 0x72, 0x65, 0x76, 0x22, 0x46, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, + 0x17, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x18, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2e, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0xe6, 0x01, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x0c, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x49, 0x0a, 0x10, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, + 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, + 0x6b, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x8d, 0x01, 0x0a, 0x14, 0x55, + 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, + 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x43, 0x0a, 0x15, 0x55, 0x73, + 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, - 0x8d, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, + 0x8a, 0x02, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, @@ -3518,66 +4012,24 @@ var file_operations_proto_rawDesc = []byte{ 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, - 0x43, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, - 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x22, 0x8a, 0x02, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x7a, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x74, 0x61, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, - 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, - 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, - 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, - 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x93, 0x02, - 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, - 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, - 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x22, 0xb0, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x0d, - 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x2e, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xa9, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x4d, - 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x7a, 0x0a, 0x15, + 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x52, + 0x03, 0x74, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, + 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xae, 0x02, 0x0a, 0x12, 0x55, 0x73, 0x65, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, @@ -3586,46 +4038,17 @@ var file_operations_proto_rawDesc = []byte{ 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0xf0, 0x02, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x73, - 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x66, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x22, 0x65, 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, - 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x11, - 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x70, 0x72, 0x65, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7e, 0x0a, 0x15, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xa6, 0x01, 0x0a, - 0x13, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, + 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, + 0x6f, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x49, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, + 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x93, 0x02, 0x0a, 0x16, 0x55, 0x73, + 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, @@ -3635,449 +4058,552 @@ var file_operations_proto_rawDesc = []byte{ 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x86, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, - 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x22, + 0x99, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x04, 0x08, 0x02, + 0x10, 0x03, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xaa, 0x02, 0x0a, 0x14, + 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x12, 0x49, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3a, + 0x0a, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0a, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x43, 0x0a, 0x0e, 0x6d, 0x65, + 0x72, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, + 0x52, 0x0d, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x42, + 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xf0, 0x02, 0x0a, 0x15, 0x55, 0x73, 0x65, + 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x12, 0x16, 0x0a, + 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x72, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x52, 0x65, 0x66, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, + 0x0a, 0x10, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, + 0x65, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, + 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, + 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, 0x22, 0x4e, 0x0a, 0x16, 0x55, + 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x49, 0x64, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7e, 0x0a, 0x15, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, - 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x97, - 0x03, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, - 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x38, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x22, 0xf2, 0x02, 0x0a, 0x16, 0x55, 0x73, 0x65, - 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x63, 0x0a, 0x16, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, - 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x34, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, - 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x01, 0x12, - 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x10, 0x02, 0x22, 0x93, 0x03, - 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xa6, 0x01, 0x0a, 0x13, + 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, - 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x3d, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x22, 0xea, 0x02, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, - 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, - 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, - 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x5f, 0x0a, 0x16, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, - 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x34, 0x0a, 0x0f, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x08, 0x0a, - 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, - 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x10, 0x02, - 0x22, 0xf5, 0x02, 0x0a, 0x1b, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x12, 0x46, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x69, 0x6c, - 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, - 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, - 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, - 0x73, 0x65, 0x36, 0x34, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, - 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x69, 0x6e, 0x66, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x22, 0x55, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x55, - 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x56, 0x45, 0x10, - 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x09, 0x0a, - 0x05, 0x43, 0x48, 0x4d, 0x4f, 0x44, 0x10, 0x05, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x55, 0x73, 0x65, - 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x1a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x22, 0x0a, - 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x22, 0xf8, 0x03, 0x0a, 0x1c, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x22, 0x86, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, + 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, + 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x97, 0x03, + 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x22, 0xf2, 0x02, 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, + 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x63, 0x0a, 0x16, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, + 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x34, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, + 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x01, 0x12, 0x0c, + 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x10, 0x02, 0x22, 0xdd, 0x02, 0x0a, + 0x13, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x4e, 0x0a, 0x14, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, 0x5f, 0x70, + 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, + 0x52, 0x12, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x6c, 0x69, 0x63, 0x74, 0x12, 0x50, 0x0a, 0x16, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x64, 0x69, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4e, 0x6f, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, + 0x52, 0x14, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x44, 0x69, + 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x17, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x41, + 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x15, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x41, 0x70, 0x70, + 0x6c, 0x69, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x93, 0x03, 0x0a, + 0x11, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, - 0x0a, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, - 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x29, + 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, + 0x74, 0x6f, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, - 0x68, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, - 0x68, 0x61, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x0b, 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, 0x22, 0xb6, 0x01, 0x0a, - 0x16, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x23, 0x0a, 0x21, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0xb1, 0x04, 0x0a, 0x1c, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x61, 0x70, 0x70, - 0x6c, 0x79, 0x1a, 0x86, 0x03, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x38, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x09, 0x72, 0x65, 0x62, - 0x61, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x08, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x73, 0x68, 0x61, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x53, 0x68, - 0x61, 0x12, 0x3f, 0x0a, 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x52, 0x10, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x62, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x5f, 0x70, - 0x75, 0x73, 0x68, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, + 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x22, 0xea, 0x02, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, + 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x11, + 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x5f, 0x0a, 0x16, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x34, 0x0a, 0x0f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x65, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x08, 0x0a, 0x04, + 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x10, 0x02, 0x22, + 0xf5, 0x02, 0x0a, 0x1b, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x46, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x65, + 0x76, 0x69, 0x6f, 0x75, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x73, + 0x65, 0x36, 0x34, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, + 0x6e, 0x66, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x22, 0x55, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, + 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x03, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, + 0x43, 0x48, 0x4d, 0x4f, 0x44, 0x10, 0x05, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x3d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x12, 0x1a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x22, 0x0a, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0xf8, 0x03, 0x0a, 0x1c, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, + 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x3d, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x68, + 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x68, + 0x61, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0b, 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, 0x42, 0x29, 0x0a, 0x27, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xde, 0x01, 0x0a, 0x1d, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x72, 0x65, 0x62, 0x61, - 0x73, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, - 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x12, 0x27, 0x0a, 0x0e, 0x72, 0x65, 0x62, - 0x61, 0x73, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, - 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, - 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, - 0x0a, 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x67, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x2a, 0x0a, 0x28, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xc3, 0x02, 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72, - 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x53, 0x68, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x68, - 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x64, 0x53, 0x68, 0x61, 0x12, - 0x24, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x06, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, - 0x10, 0x05, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x22, 0x6d, 0x0a, - 0x12, 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x5f, 0x73, 0x68, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x53, - 0x68, 0x61, 0x12, 0x1f, 0x0a, 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x67, 0x69, 0x74, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xab, 0x01, 0x0a, - 0x1a, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x0f, 0x72, - 0x65, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, - 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x48, 0x00, 0x52, 0x0e, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, - 0x63, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xac, 0x01, 0x0a, 0x0f, 0x55, - 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x49, - 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x62, - 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, - 0x52, 0x0e, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, - 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xdd, 0x02, 0x0a, 0x15, 0x55, 0x73, - 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x1a, - 0xc3, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x38, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb6, 0x01, 0x0a, 0x16, + 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x23, 0x0a, 0x21, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0xb1, 0x04, 0x0a, 0x1c, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x1a, 0x86, 0x03, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x09, 0x72, 0x65, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x08, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x73, 0x68, 0x61, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x53, 0x68, 0x61, + 0x12, 0x3f, 0x0a, 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x10, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0e, 0x67, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x42, 0x29, 0x0a, 0x27, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xde, 0x01, 0x0a, 0x1d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x72, 0x65, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x72, + 0x65, 0x62, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x12, 0x27, 0x0a, 0x0e, 0x72, 0x65, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, + 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, + 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, 0x0a, + 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x67, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x2a, 0x0a, 0x28, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xc3, 0x02, 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72, 0x53, + 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x53, 0x68, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x5f, 0x73, 0x68, 0x61, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x64, 0x53, 0x68, 0x61, 0x12, 0x24, + 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x06, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 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, 0x42, 0x22, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x5c, 0x0a, 0x16, 0x55, 0x73, 0x65, - 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xae, 0x02, 0x0a, 0x1a, 0x55, 0x73, 0x65, 0x72, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, - 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, - 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, - 0x61, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x75, - 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xc9, 0x01, 0x0a, 0x1b, 0x55, 0x73, 0x65, - 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, - 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, - 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, - 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x03, 0x10, - 0x04, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x32, 0xed, 0x0a, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, - 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, - 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1c, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, - 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x01, 0x12, 0x57, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, - 0x6f, 0x52, 0x65, 0x66, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5e, 0x0a, 0x0f, 0x55, - 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1e, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x0c, 0x55, - 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x57, - 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, - 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, - 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, - 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x01, 0x28, 0x01, 0x12, 0x70, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, - 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, - 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, - 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, - 0x73, 0x68, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x01, 0x12, 0x59, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, + 0x05, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x22, 0x5d, 0x0a, 0x12, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x5f, 0x73, 0x68, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x73, 0x68, 0x53, 0x68, + 0x61, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x11, 0x70, + 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x52, 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xab, 0x01, 0x0a, 0x1a, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, + 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, 0x72, + 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, + 0x00, 0x52, 0x0e, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, + 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xac, 0x01, 0x0a, 0x0f, 0x55, 0x73, + 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x49, 0x0a, + 0x10, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x72, 0x65, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, + 0x0e, 0x72, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x42, + 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xdd, 0x02, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x1a, 0xc3, + 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 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, 0x42, 0x22, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x5c, 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x12, 0x66, 0x0a, 0x13, + 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xae, 0x02, 0x0a, 0x1a, 0x55, 0x73, 0x65, 0x72, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x20, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, + 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x75, 0x62, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xc9, 0x01, 0x0a, 0x1b, 0x55, 0x73, 0x65, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x70, + 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, + 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x32, 0xed, 0x0a, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, + 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x55, + 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1c, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, + 0x01, 0x12, 0x57, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, + 0x52, 0x65, 0x66, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5e, 0x0a, 0x0f, 0x55, 0x73, + 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1e, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, + 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x0c, 0x55, 0x73, + 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x46, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x57, 0x0a, + 0x0e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x12, + 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, + 0x72, 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x65, 0x72, + 0x72, 0x79, 0x50, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, + 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x01, 0x28, 0x01, 0x12, 0x70, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, + 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x62, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x76, + 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, + 0x68, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, + 0x71, 0x75, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x71, 0x75, 0x61, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, + 0x12, 0x59, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x70, 0x70, 0x6c, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x12, 0x66, 0x0a, 0x13, 0x55, + 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, + 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -4093,167 +4619,189 @@ func file_operations_proto_rawDescGZIP() []byte { } var file_operations_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_operations_proto_msgTypes = make([]protoimpl.MessageInfo, 39) +var file_operations_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_operations_proto_goTypes = []interface{}{ (UserCherryPickResponse_CreateTreeError)(0), // 0: gitaly.UserCherryPickResponse.CreateTreeError (UserRevertResponse_CreateTreeError)(0), // 1: gitaly.UserRevertResponse.CreateTreeError (UserCommitFilesActionHeader_ActionType)(0), // 2: gitaly.UserCommitFilesActionHeader.ActionType (*UserCreateBranchRequest)(nil), // 3: gitaly.UserCreateBranchRequest (*UserCreateBranchResponse)(nil), // 4: gitaly.UserCreateBranchResponse - (*UserUpdateBranchRequest)(nil), // 5: gitaly.UserUpdateBranchRequest - (*UserUpdateBranchResponse)(nil), // 6: gitaly.UserUpdateBranchResponse - (*UserDeleteBranchRequest)(nil), // 7: gitaly.UserDeleteBranchRequest - (*UserDeleteBranchResponse)(nil), // 8: gitaly.UserDeleteBranchResponse - (*UserDeleteTagRequest)(nil), // 9: gitaly.UserDeleteTagRequest - (*UserDeleteTagResponse)(nil), // 10: gitaly.UserDeleteTagResponse - (*UserCreateTagRequest)(nil), // 11: gitaly.UserCreateTagRequest - (*UserCreateTagResponse)(nil), // 12: gitaly.UserCreateTagResponse - (*UserMergeBranchRequest)(nil), // 13: gitaly.UserMergeBranchRequest - (*UserMergeBranchResponse)(nil), // 14: gitaly.UserMergeBranchResponse - (*UserMergeBranchError)(nil), // 15: gitaly.UserMergeBranchError - (*UserMergeToRefRequest)(nil), // 16: gitaly.UserMergeToRefRequest - (*UserMergeToRefResponse)(nil), // 17: gitaly.UserMergeToRefResponse - (*OperationBranchUpdate)(nil), // 18: gitaly.OperationBranchUpdate - (*UserFFBranchRequest)(nil), // 19: gitaly.UserFFBranchRequest - (*UserFFBranchResponse)(nil), // 20: gitaly.UserFFBranchResponse - (*UserCherryPickRequest)(nil), // 21: gitaly.UserCherryPickRequest - (*UserCherryPickResponse)(nil), // 22: gitaly.UserCherryPickResponse - (*UserRevertRequest)(nil), // 23: gitaly.UserRevertRequest - (*UserRevertResponse)(nil), // 24: gitaly.UserRevertResponse - (*UserCommitFilesActionHeader)(nil), // 25: gitaly.UserCommitFilesActionHeader - (*UserCommitFilesAction)(nil), // 26: gitaly.UserCommitFilesAction - (*UserCommitFilesRequestHeader)(nil), // 27: gitaly.UserCommitFilesRequestHeader - (*UserCommitFilesRequest)(nil), // 28: gitaly.UserCommitFilesRequest - (*UserCommitFilesResponse)(nil), // 29: gitaly.UserCommitFilesResponse - (*UserRebaseConfirmableRequest)(nil), // 30: gitaly.UserRebaseConfirmableRequest - (*UserRebaseConfirmableResponse)(nil), // 31: gitaly.UserRebaseConfirmableResponse - (*UserSquashRequest)(nil), // 32: gitaly.UserSquashRequest - (*UserSquashResponse)(nil), // 33: gitaly.UserSquashResponse - (*UserRebaseConfirmableError)(nil), // 34: gitaly.UserRebaseConfirmableError - (*UserSquashError)(nil), // 35: gitaly.UserSquashError - (*UserApplyPatchRequest)(nil), // 36: gitaly.UserApplyPatchRequest - (*UserApplyPatchResponse)(nil), // 37: gitaly.UserApplyPatchResponse - (*UserUpdateSubmoduleRequest)(nil), // 38: gitaly.UserUpdateSubmoduleRequest - (*UserUpdateSubmoduleResponse)(nil), // 39: gitaly.UserUpdateSubmoduleResponse - (*UserRebaseConfirmableRequest_Header)(nil), // 40: gitaly.UserRebaseConfirmableRequest.Header - (*UserApplyPatchRequest_Header)(nil), // 41: gitaly.UserApplyPatchRequest.Header - (*Repository)(nil), // 42: gitaly.Repository - (*User)(nil), // 43: gitaly.User - (*Branch)(nil), // 44: gitaly.Branch - (*timestamppb.Timestamp)(nil), // 45: google.protobuf.Timestamp - (*Tag)(nil), // 46: gitaly.Tag - (*AccessCheckError)(nil), // 47: gitaly.AccessCheckError - (*ReferenceUpdateError)(nil), // 48: gitaly.ReferenceUpdateError - (*GitCommit)(nil), // 49: gitaly.GitCommit - (*MergeConflictError)(nil), // 50: gitaly.MergeConflictError - (*ResolveRevisionError)(nil), // 51: gitaly.ResolveRevisionError + (*UserCreateBranchError)(nil), // 5: gitaly.UserCreateBranchError + (*UserUpdateBranchRequest)(nil), // 6: gitaly.UserUpdateBranchRequest + (*UserUpdateBranchResponse)(nil), // 7: gitaly.UserUpdateBranchResponse + (*UserDeleteBranchRequest)(nil), // 8: gitaly.UserDeleteBranchRequest + (*UserDeleteBranchResponse)(nil), // 9: gitaly.UserDeleteBranchResponse + (*UserDeleteBranchError)(nil), // 10: gitaly.UserDeleteBranchError + (*UserDeleteTagRequest)(nil), // 11: gitaly.UserDeleteTagRequest + (*UserDeleteTagResponse)(nil), // 12: gitaly.UserDeleteTagResponse + (*UserCreateTagRequest)(nil), // 13: gitaly.UserCreateTagRequest + (*UserCreateTagResponse)(nil), // 14: gitaly.UserCreateTagResponse + (*UserCreateTagError)(nil), // 15: gitaly.UserCreateTagError + (*UserMergeBranchRequest)(nil), // 16: gitaly.UserMergeBranchRequest + (*UserMergeBranchResponse)(nil), // 17: gitaly.UserMergeBranchResponse + (*UserMergeBranchError)(nil), // 18: gitaly.UserMergeBranchError + (*UserMergeToRefRequest)(nil), // 19: gitaly.UserMergeToRefRequest + (*UserMergeToRefResponse)(nil), // 20: gitaly.UserMergeToRefResponse + (*OperationBranchUpdate)(nil), // 21: gitaly.OperationBranchUpdate + (*UserFFBranchRequest)(nil), // 22: gitaly.UserFFBranchRequest + (*UserFFBranchResponse)(nil), // 23: gitaly.UserFFBranchResponse + (*UserCherryPickRequest)(nil), // 24: gitaly.UserCherryPickRequest + (*UserCherryPickResponse)(nil), // 25: gitaly.UserCherryPickResponse + (*UserCherryPickError)(nil), // 26: gitaly.UserCherryPickError + (*UserRevertRequest)(nil), // 27: gitaly.UserRevertRequest + (*UserRevertResponse)(nil), // 28: gitaly.UserRevertResponse + (*UserCommitFilesActionHeader)(nil), // 29: gitaly.UserCommitFilesActionHeader + (*UserCommitFilesAction)(nil), // 30: gitaly.UserCommitFilesAction + (*UserCommitFilesRequestHeader)(nil), // 31: gitaly.UserCommitFilesRequestHeader + (*UserCommitFilesRequest)(nil), // 32: gitaly.UserCommitFilesRequest + (*UserCommitFilesResponse)(nil), // 33: gitaly.UserCommitFilesResponse + (*UserRebaseConfirmableRequest)(nil), // 34: gitaly.UserRebaseConfirmableRequest + (*UserRebaseConfirmableResponse)(nil), // 35: gitaly.UserRebaseConfirmableResponse + (*UserSquashRequest)(nil), // 36: gitaly.UserSquashRequest + (*UserSquashResponse)(nil), // 37: gitaly.UserSquashResponse + (*UserRebaseConfirmableError)(nil), // 38: gitaly.UserRebaseConfirmableError + (*UserSquashError)(nil), // 39: gitaly.UserSquashError + (*UserApplyPatchRequest)(nil), // 40: gitaly.UserApplyPatchRequest + (*UserApplyPatchResponse)(nil), // 41: gitaly.UserApplyPatchResponse + (*UserUpdateSubmoduleRequest)(nil), // 42: gitaly.UserUpdateSubmoduleRequest + (*UserUpdateSubmoduleResponse)(nil), // 43: gitaly.UserUpdateSubmoduleResponse + (*UserRebaseConfirmableRequest_Header)(nil), // 44: gitaly.UserRebaseConfirmableRequest.Header + (*UserApplyPatchRequest_Header)(nil), // 45: gitaly.UserApplyPatchRequest.Header + (*Repository)(nil), // 46: gitaly.Repository + (*User)(nil), // 47: gitaly.User + (*Branch)(nil), // 48: gitaly.Branch + (*CustomHookError)(nil), // 49: gitaly.CustomHookError + (*AccessCheckError)(nil), // 50: gitaly.AccessCheckError + (*ReferenceUpdateError)(nil), // 51: gitaly.ReferenceUpdateError + (*timestamppb.Timestamp)(nil), // 52: google.protobuf.Timestamp + (*Tag)(nil), // 53: gitaly.Tag + (*ReferenceExistsError)(nil), // 54: gitaly.ReferenceExistsError + (*MergeConflictError)(nil), // 55: gitaly.MergeConflictError + (*GitCommit)(nil), // 56: gitaly.GitCommit + (*NotAncestorError)(nil), // 57: gitaly.NotAncestorError + (*ChangesAlreadyAppliedError)(nil), // 58: gitaly.ChangesAlreadyAppliedError + (*ResolveRevisionError)(nil), // 59: gitaly.ResolveRevisionError } var file_operations_proto_depIdxs = []int32{ - 42, // 0: gitaly.UserCreateBranchRequest.repository:type_name -> gitaly.Repository - 43, // 1: gitaly.UserCreateBranchRequest.user:type_name -> gitaly.User - 44, // 2: gitaly.UserCreateBranchResponse.branch:type_name -> gitaly.Branch - 42, // 3: gitaly.UserUpdateBranchRequest.repository:type_name -> gitaly.Repository - 43, // 4: gitaly.UserUpdateBranchRequest.user:type_name -> gitaly.User - 42, // 5: gitaly.UserDeleteBranchRequest.repository:type_name -> gitaly.Repository - 43, // 6: gitaly.UserDeleteBranchRequest.user:type_name -> gitaly.User - 42, // 7: gitaly.UserDeleteTagRequest.repository:type_name -> gitaly.Repository - 43, // 8: gitaly.UserDeleteTagRequest.user:type_name -> gitaly.User - 42, // 9: gitaly.UserCreateTagRequest.repository:type_name -> gitaly.Repository - 43, // 10: gitaly.UserCreateTagRequest.user:type_name -> gitaly.User - 45, // 11: gitaly.UserCreateTagRequest.timestamp:type_name -> google.protobuf.Timestamp - 46, // 12: gitaly.UserCreateTagResponse.tag:type_name -> gitaly.Tag - 42, // 13: gitaly.UserMergeBranchRequest.repository:type_name -> gitaly.Repository - 43, // 14: gitaly.UserMergeBranchRequest.user:type_name -> gitaly.User - 45, // 15: gitaly.UserMergeBranchRequest.timestamp:type_name -> google.protobuf.Timestamp - 18, // 16: gitaly.UserMergeBranchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 47, // 17: gitaly.UserMergeBranchError.access_check:type_name -> gitaly.AccessCheckError - 48, // 18: gitaly.UserMergeBranchError.reference_update:type_name -> gitaly.ReferenceUpdateError - 42, // 19: gitaly.UserMergeToRefRequest.repository:type_name -> gitaly.Repository - 43, // 20: gitaly.UserMergeToRefRequest.user:type_name -> gitaly.User - 45, // 21: gitaly.UserMergeToRefRequest.timestamp:type_name -> google.protobuf.Timestamp - 42, // 22: gitaly.UserFFBranchRequest.repository:type_name -> gitaly.Repository - 43, // 23: gitaly.UserFFBranchRequest.user:type_name -> gitaly.User - 18, // 24: gitaly.UserFFBranchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 42, // 25: gitaly.UserCherryPickRequest.repository:type_name -> gitaly.Repository - 43, // 26: gitaly.UserCherryPickRequest.user:type_name -> gitaly.User - 49, // 27: gitaly.UserCherryPickRequest.commit:type_name -> gitaly.GitCommit - 42, // 28: gitaly.UserCherryPickRequest.start_repository:type_name -> gitaly.Repository - 45, // 29: gitaly.UserCherryPickRequest.timestamp:type_name -> google.protobuf.Timestamp - 18, // 30: gitaly.UserCherryPickResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 0, // 31: gitaly.UserCherryPickResponse.create_tree_error_code:type_name -> gitaly.UserCherryPickResponse.CreateTreeError - 42, // 32: gitaly.UserRevertRequest.repository:type_name -> gitaly.Repository - 43, // 33: gitaly.UserRevertRequest.user:type_name -> gitaly.User - 49, // 34: gitaly.UserRevertRequest.commit:type_name -> gitaly.GitCommit - 42, // 35: gitaly.UserRevertRequest.start_repository:type_name -> gitaly.Repository - 45, // 36: gitaly.UserRevertRequest.timestamp:type_name -> google.protobuf.Timestamp - 18, // 37: gitaly.UserRevertResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 1, // 38: gitaly.UserRevertResponse.create_tree_error_code:type_name -> gitaly.UserRevertResponse.CreateTreeError - 2, // 39: gitaly.UserCommitFilesActionHeader.action:type_name -> gitaly.UserCommitFilesActionHeader.ActionType - 25, // 40: gitaly.UserCommitFilesAction.header:type_name -> gitaly.UserCommitFilesActionHeader - 42, // 41: gitaly.UserCommitFilesRequestHeader.repository:type_name -> gitaly.Repository - 43, // 42: gitaly.UserCommitFilesRequestHeader.user:type_name -> gitaly.User - 42, // 43: gitaly.UserCommitFilesRequestHeader.start_repository:type_name -> gitaly.Repository - 45, // 44: gitaly.UserCommitFilesRequestHeader.timestamp:type_name -> google.protobuf.Timestamp - 27, // 45: gitaly.UserCommitFilesRequest.header:type_name -> gitaly.UserCommitFilesRequestHeader - 26, // 46: gitaly.UserCommitFilesRequest.action:type_name -> gitaly.UserCommitFilesAction - 18, // 47: gitaly.UserCommitFilesResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 40, // 48: gitaly.UserRebaseConfirmableRequest.header:type_name -> gitaly.UserRebaseConfirmableRequest.Header - 42, // 49: gitaly.UserSquashRequest.repository:type_name -> gitaly.Repository - 43, // 50: gitaly.UserSquashRequest.user:type_name -> gitaly.User - 43, // 51: gitaly.UserSquashRequest.author:type_name -> gitaly.User - 45, // 52: gitaly.UserSquashRequest.timestamp:type_name -> google.protobuf.Timestamp - 50, // 53: gitaly.UserRebaseConfirmableError.rebase_conflict:type_name -> gitaly.MergeConflictError - 47, // 54: gitaly.UserRebaseConfirmableError.access_check:type_name -> gitaly.AccessCheckError - 51, // 55: gitaly.UserSquashError.resolve_revision:type_name -> gitaly.ResolveRevisionError - 50, // 56: gitaly.UserSquashError.rebase_conflict:type_name -> gitaly.MergeConflictError - 41, // 57: gitaly.UserApplyPatchRequest.header:type_name -> gitaly.UserApplyPatchRequest.Header - 18, // 58: gitaly.UserApplyPatchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 42, // 59: gitaly.UserUpdateSubmoduleRequest.repository:type_name -> gitaly.Repository - 43, // 60: gitaly.UserUpdateSubmoduleRequest.user:type_name -> gitaly.User - 45, // 61: gitaly.UserUpdateSubmoduleRequest.timestamp:type_name -> google.protobuf.Timestamp - 18, // 62: gitaly.UserUpdateSubmoduleResponse.branch_update:type_name -> gitaly.OperationBranchUpdate - 42, // 63: gitaly.UserRebaseConfirmableRequest.Header.repository:type_name -> gitaly.Repository - 43, // 64: gitaly.UserRebaseConfirmableRequest.Header.user:type_name -> gitaly.User - 42, // 65: gitaly.UserRebaseConfirmableRequest.Header.remote_repository:type_name -> gitaly.Repository - 45, // 66: gitaly.UserRebaseConfirmableRequest.Header.timestamp:type_name -> google.protobuf.Timestamp - 42, // 67: gitaly.UserApplyPatchRequest.Header.repository:type_name -> gitaly.Repository - 43, // 68: gitaly.UserApplyPatchRequest.Header.user:type_name -> gitaly.User - 45, // 69: gitaly.UserApplyPatchRequest.Header.timestamp:type_name -> google.protobuf.Timestamp - 3, // 70: gitaly.OperationService.UserCreateBranch:input_type -> gitaly.UserCreateBranchRequest - 5, // 71: gitaly.OperationService.UserUpdateBranch:input_type -> gitaly.UserUpdateBranchRequest - 7, // 72: gitaly.OperationService.UserDeleteBranch:input_type -> gitaly.UserDeleteBranchRequest - 11, // 73: gitaly.OperationService.UserCreateTag:input_type -> gitaly.UserCreateTagRequest - 9, // 74: gitaly.OperationService.UserDeleteTag:input_type -> gitaly.UserDeleteTagRequest - 16, // 75: gitaly.OperationService.UserMergeToRef:input_type -> gitaly.UserMergeToRefRequest - 13, // 76: gitaly.OperationService.UserMergeBranch:input_type -> gitaly.UserMergeBranchRequest - 19, // 77: gitaly.OperationService.UserFFBranch:input_type -> gitaly.UserFFBranchRequest - 21, // 78: gitaly.OperationService.UserCherryPick:input_type -> gitaly.UserCherryPickRequest - 28, // 79: gitaly.OperationService.UserCommitFiles:input_type -> gitaly.UserCommitFilesRequest - 30, // 80: gitaly.OperationService.UserRebaseConfirmable:input_type -> gitaly.UserRebaseConfirmableRequest - 23, // 81: gitaly.OperationService.UserRevert:input_type -> gitaly.UserRevertRequest - 32, // 82: gitaly.OperationService.UserSquash:input_type -> gitaly.UserSquashRequest - 36, // 83: gitaly.OperationService.UserApplyPatch:input_type -> gitaly.UserApplyPatchRequest - 38, // 84: gitaly.OperationService.UserUpdateSubmodule:input_type -> gitaly.UserUpdateSubmoduleRequest - 4, // 85: gitaly.OperationService.UserCreateBranch:output_type -> gitaly.UserCreateBranchResponse - 6, // 86: gitaly.OperationService.UserUpdateBranch:output_type -> gitaly.UserUpdateBranchResponse - 8, // 87: gitaly.OperationService.UserDeleteBranch:output_type -> gitaly.UserDeleteBranchResponse - 12, // 88: gitaly.OperationService.UserCreateTag:output_type -> gitaly.UserCreateTagResponse - 10, // 89: gitaly.OperationService.UserDeleteTag:output_type -> gitaly.UserDeleteTagResponse - 17, // 90: gitaly.OperationService.UserMergeToRef:output_type -> gitaly.UserMergeToRefResponse - 14, // 91: gitaly.OperationService.UserMergeBranch:output_type -> gitaly.UserMergeBranchResponse - 20, // 92: gitaly.OperationService.UserFFBranch:output_type -> gitaly.UserFFBranchResponse - 22, // 93: gitaly.OperationService.UserCherryPick:output_type -> gitaly.UserCherryPickResponse - 29, // 94: gitaly.OperationService.UserCommitFiles:output_type -> gitaly.UserCommitFilesResponse - 31, // 95: gitaly.OperationService.UserRebaseConfirmable:output_type -> gitaly.UserRebaseConfirmableResponse - 24, // 96: gitaly.OperationService.UserRevert:output_type -> gitaly.UserRevertResponse - 33, // 97: gitaly.OperationService.UserSquash:output_type -> gitaly.UserSquashResponse - 37, // 98: gitaly.OperationService.UserApplyPatch:output_type -> gitaly.UserApplyPatchResponse - 39, // 99: gitaly.OperationService.UserUpdateSubmodule:output_type -> gitaly.UserUpdateSubmoduleResponse - 85, // [85:100] is the sub-list for method output_type - 70, // [70:85] is the sub-list for method input_type - 70, // [70:70] is the sub-list for extension type_name - 70, // [70:70] is the sub-list for extension extendee - 0, // [0:70] is the sub-list for field type_name + 46, // 0: gitaly.UserCreateBranchRequest.repository:type_name -> gitaly.Repository + 47, // 1: gitaly.UserCreateBranchRequest.user:type_name -> gitaly.User + 48, // 2: gitaly.UserCreateBranchResponse.branch:type_name -> gitaly.Branch + 49, // 3: gitaly.UserCreateBranchError.custom_hook:type_name -> gitaly.CustomHookError + 46, // 4: gitaly.UserUpdateBranchRequest.repository:type_name -> gitaly.Repository + 47, // 5: gitaly.UserUpdateBranchRequest.user:type_name -> gitaly.User + 46, // 6: gitaly.UserDeleteBranchRequest.repository:type_name -> gitaly.Repository + 47, // 7: gitaly.UserDeleteBranchRequest.user:type_name -> gitaly.User + 50, // 8: gitaly.UserDeleteBranchError.access_check:type_name -> gitaly.AccessCheckError + 51, // 9: gitaly.UserDeleteBranchError.reference_update:type_name -> gitaly.ReferenceUpdateError + 49, // 10: gitaly.UserDeleteBranchError.custom_hook:type_name -> gitaly.CustomHookError + 46, // 11: gitaly.UserDeleteTagRequest.repository:type_name -> gitaly.Repository + 47, // 12: gitaly.UserDeleteTagRequest.user:type_name -> gitaly.User + 46, // 13: gitaly.UserCreateTagRequest.repository:type_name -> gitaly.Repository + 47, // 14: gitaly.UserCreateTagRequest.user:type_name -> gitaly.User + 52, // 15: gitaly.UserCreateTagRequest.timestamp:type_name -> google.protobuf.Timestamp + 53, // 16: gitaly.UserCreateTagResponse.tag:type_name -> gitaly.Tag + 50, // 17: gitaly.UserCreateTagError.access_check:type_name -> gitaly.AccessCheckError + 51, // 18: gitaly.UserCreateTagError.reference_update:type_name -> gitaly.ReferenceUpdateError + 49, // 19: gitaly.UserCreateTagError.custom_hook:type_name -> gitaly.CustomHookError + 54, // 20: gitaly.UserCreateTagError.reference_exists:type_name -> gitaly.ReferenceExistsError + 46, // 21: gitaly.UserMergeBranchRequest.repository:type_name -> gitaly.Repository + 47, // 22: gitaly.UserMergeBranchRequest.user:type_name -> gitaly.User + 52, // 23: gitaly.UserMergeBranchRequest.timestamp:type_name -> google.protobuf.Timestamp + 21, // 24: gitaly.UserMergeBranchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 50, // 25: gitaly.UserMergeBranchError.access_check:type_name -> gitaly.AccessCheckError + 51, // 26: gitaly.UserMergeBranchError.reference_update:type_name -> gitaly.ReferenceUpdateError + 49, // 27: gitaly.UserMergeBranchError.custom_hook:type_name -> gitaly.CustomHookError + 55, // 28: gitaly.UserMergeBranchError.merge_conflict:type_name -> gitaly.MergeConflictError + 46, // 29: gitaly.UserMergeToRefRequest.repository:type_name -> gitaly.Repository + 47, // 30: gitaly.UserMergeToRefRequest.user:type_name -> gitaly.User + 52, // 31: gitaly.UserMergeToRefRequest.timestamp:type_name -> google.protobuf.Timestamp + 46, // 32: gitaly.UserFFBranchRequest.repository:type_name -> gitaly.Repository + 47, // 33: gitaly.UserFFBranchRequest.user:type_name -> gitaly.User + 21, // 34: gitaly.UserFFBranchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 46, // 35: gitaly.UserCherryPickRequest.repository:type_name -> gitaly.Repository + 47, // 36: gitaly.UserCherryPickRequest.user:type_name -> gitaly.User + 56, // 37: gitaly.UserCherryPickRequest.commit:type_name -> gitaly.GitCommit + 46, // 38: gitaly.UserCherryPickRequest.start_repository:type_name -> gitaly.Repository + 52, // 39: gitaly.UserCherryPickRequest.timestamp:type_name -> google.protobuf.Timestamp + 21, // 40: gitaly.UserCherryPickResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 0, // 41: gitaly.UserCherryPickResponse.create_tree_error_code:type_name -> gitaly.UserCherryPickResponse.CreateTreeError + 55, // 42: gitaly.UserCherryPickError.cherry_pick_conflict:type_name -> gitaly.MergeConflictError + 57, // 43: gitaly.UserCherryPickError.target_branch_diverged:type_name -> gitaly.NotAncestorError + 58, // 44: gitaly.UserCherryPickError.changes_already_applied:type_name -> gitaly.ChangesAlreadyAppliedError + 50, // 45: gitaly.UserCherryPickError.access_check:type_name -> gitaly.AccessCheckError + 46, // 46: gitaly.UserRevertRequest.repository:type_name -> gitaly.Repository + 47, // 47: gitaly.UserRevertRequest.user:type_name -> gitaly.User + 56, // 48: gitaly.UserRevertRequest.commit:type_name -> gitaly.GitCommit + 46, // 49: gitaly.UserRevertRequest.start_repository:type_name -> gitaly.Repository + 52, // 50: gitaly.UserRevertRequest.timestamp:type_name -> google.protobuf.Timestamp + 21, // 51: gitaly.UserRevertResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 1, // 52: gitaly.UserRevertResponse.create_tree_error_code:type_name -> gitaly.UserRevertResponse.CreateTreeError + 2, // 53: gitaly.UserCommitFilesActionHeader.action:type_name -> gitaly.UserCommitFilesActionHeader.ActionType + 29, // 54: gitaly.UserCommitFilesAction.header:type_name -> gitaly.UserCommitFilesActionHeader + 46, // 55: gitaly.UserCommitFilesRequestHeader.repository:type_name -> gitaly.Repository + 47, // 56: gitaly.UserCommitFilesRequestHeader.user:type_name -> gitaly.User + 46, // 57: gitaly.UserCommitFilesRequestHeader.start_repository:type_name -> gitaly.Repository + 52, // 58: gitaly.UserCommitFilesRequestHeader.timestamp:type_name -> google.protobuf.Timestamp + 31, // 59: gitaly.UserCommitFilesRequest.header:type_name -> gitaly.UserCommitFilesRequestHeader + 30, // 60: gitaly.UserCommitFilesRequest.action:type_name -> gitaly.UserCommitFilesAction + 21, // 61: gitaly.UserCommitFilesResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 44, // 62: gitaly.UserRebaseConfirmableRequest.header:type_name -> gitaly.UserRebaseConfirmableRequest.Header + 46, // 63: gitaly.UserSquashRequest.repository:type_name -> gitaly.Repository + 47, // 64: gitaly.UserSquashRequest.user:type_name -> gitaly.User + 47, // 65: gitaly.UserSquashRequest.author:type_name -> gitaly.User + 52, // 66: gitaly.UserSquashRequest.timestamp:type_name -> google.protobuf.Timestamp + 55, // 67: gitaly.UserRebaseConfirmableError.rebase_conflict:type_name -> gitaly.MergeConflictError + 50, // 68: gitaly.UserRebaseConfirmableError.access_check:type_name -> gitaly.AccessCheckError + 59, // 69: gitaly.UserSquashError.resolve_revision:type_name -> gitaly.ResolveRevisionError + 55, // 70: gitaly.UserSquashError.rebase_conflict:type_name -> gitaly.MergeConflictError + 45, // 71: gitaly.UserApplyPatchRequest.header:type_name -> gitaly.UserApplyPatchRequest.Header + 21, // 72: gitaly.UserApplyPatchResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 46, // 73: gitaly.UserUpdateSubmoduleRequest.repository:type_name -> gitaly.Repository + 47, // 74: gitaly.UserUpdateSubmoduleRequest.user:type_name -> gitaly.User + 52, // 75: gitaly.UserUpdateSubmoduleRequest.timestamp:type_name -> google.protobuf.Timestamp + 21, // 76: gitaly.UserUpdateSubmoduleResponse.branch_update:type_name -> gitaly.OperationBranchUpdate + 46, // 77: gitaly.UserRebaseConfirmableRequest.Header.repository:type_name -> gitaly.Repository + 47, // 78: gitaly.UserRebaseConfirmableRequest.Header.user:type_name -> gitaly.User + 46, // 79: gitaly.UserRebaseConfirmableRequest.Header.remote_repository:type_name -> gitaly.Repository + 52, // 80: gitaly.UserRebaseConfirmableRequest.Header.timestamp:type_name -> google.protobuf.Timestamp + 46, // 81: gitaly.UserApplyPatchRequest.Header.repository:type_name -> gitaly.Repository + 47, // 82: gitaly.UserApplyPatchRequest.Header.user:type_name -> gitaly.User + 52, // 83: gitaly.UserApplyPatchRequest.Header.timestamp:type_name -> google.protobuf.Timestamp + 3, // 84: gitaly.OperationService.UserCreateBranch:input_type -> gitaly.UserCreateBranchRequest + 6, // 85: gitaly.OperationService.UserUpdateBranch:input_type -> gitaly.UserUpdateBranchRequest + 8, // 86: gitaly.OperationService.UserDeleteBranch:input_type -> gitaly.UserDeleteBranchRequest + 13, // 87: gitaly.OperationService.UserCreateTag:input_type -> gitaly.UserCreateTagRequest + 11, // 88: gitaly.OperationService.UserDeleteTag:input_type -> gitaly.UserDeleteTagRequest + 19, // 89: gitaly.OperationService.UserMergeToRef:input_type -> gitaly.UserMergeToRefRequest + 16, // 90: gitaly.OperationService.UserMergeBranch:input_type -> gitaly.UserMergeBranchRequest + 22, // 91: gitaly.OperationService.UserFFBranch:input_type -> gitaly.UserFFBranchRequest + 24, // 92: gitaly.OperationService.UserCherryPick:input_type -> gitaly.UserCherryPickRequest + 32, // 93: gitaly.OperationService.UserCommitFiles:input_type -> gitaly.UserCommitFilesRequest + 34, // 94: gitaly.OperationService.UserRebaseConfirmable:input_type -> gitaly.UserRebaseConfirmableRequest + 27, // 95: gitaly.OperationService.UserRevert:input_type -> gitaly.UserRevertRequest + 36, // 96: gitaly.OperationService.UserSquash:input_type -> gitaly.UserSquashRequest + 40, // 97: gitaly.OperationService.UserApplyPatch:input_type -> gitaly.UserApplyPatchRequest + 42, // 98: gitaly.OperationService.UserUpdateSubmodule:input_type -> gitaly.UserUpdateSubmoduleRequest + 4, // 99: gitaly.OperationService.UserCreateBranch:output_type -> gitaly.UserCreateBranchResponse + 7, // 100: gitaly.OperationService.UserUpdateBranch:output_type -> gitaly.UserUpdateBranchResponse + 9, // 101: gitaly.OperationService.UserDeleteBranch:output_type -> gitaly.UserDeleteBranchResponse + 14, // 102: gitaly.OperationService.UserCreateTag:output_type -> gitaly.UserCreateTagResponse + 12, // 103: gitaly.OperationService.UserDeleteTag:output_type -> gitaly.UserDeleteTagResponse + 20, // 104: gitaly.OperationService.UserMergeToRef:output_type -> gitaly.UserMergeToRefResponse + 17, // 105: gitaly.OperationService.UserMergeBranch:output_type -> gitaly.UserMergeBranchResponse + 23, // 106: gitaly.OperationService.UserFFBranch:output_type -> gitaly.UserFFBranchResponse + 25, // 107: gitaly.OperationService.UserCherryPick:output_type -> gitaly.UserCherryPickResponse + 33, // 108: gitaly.OperationService.UserCommitFiles:output_type -> gitaly.UserCommitFilesResponse + 35, // 109: gitaly.OperationService.UserRebaseConfirmable:output_type -> gitaly.UserRebaseConfirmableResponse + 28, // 110: gitaly.OperationService.UserRevert:output_type -> gitaly.UserRevertResponse + 37, // 111: gitaly.OperationService.UserSquash:output_type -> gitaly.UserSquashResponse + 41, // 112: gitaly.OperationService.UserApplyPatch:output_type -> gitaly.UserApplyPatchResponse + 43, // 113: gitaly.OperationService.UserUpdateSubmodule:output_type -> gitaly.UserUpdateSubmoduleResponse + 99, // [99:114] is the sub-list for method output_type + 84, // [84:99] is the sub-list for method input_type + 84, // [84:84] is the sub-list for extension type_name + 84, // [84:84] is the sub-list for extension extendee + 0, // [0:84] is the sub-list for field type_name } func init() { file_operations_proto_init() } @@ -4261,9 +4809,9 @@ func file_operations_proto_init() { if File_operations_proto != nil { return } + file_errors_proto_init() file_lint_proto_init() file_shared_proto_init() - file_errors_proto_init() if !protoimpl.UnsafeEnabled { file_operations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserCreateBranchRequest); i { @@ -4290,7 +4838,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserUpdateBranchRequest); i { + switch v := v.(*UserCreateBranchError); i { case 0: return &v.state case 1: @@ -4302,7 +4850,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserUpdateBranchResponse); i { + switch v := v.(*UserUpdateBranchRequest); i { case 0: return &v.state case 1: @@ -4314,7 +4862,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserDeleteBranchRequest); i { + switch v := v.(*UserUpdateBranchResponse); i { case 0: return &v.state case 1: @@ -4326,7 +4874,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserDeleteBranchResponse); i { + switch v := v.(*UserDeleteBranchRequest); i { case 0: return &v.state case 1: @@ -4338,7 +4886,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserDeleteTagRequest); i { + switch v := v.(*UserDeleteBranchResponse); i { case 0: return &v.state case 1: @@ -4350,7 +4898,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserDeleteTagResponse); i { + switch v := v.(*UserDeleteBranchError); i { case 0: return &v.state case 1: @@ -4362,7 +4910,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCreateTagRequest); i { + switch v := v.(*UserDeleteTagRequest); i { case 0: return &v.state case 1: @@ -4374,7 +4922,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCreateTagResponse); i { + switch v := v.(*UserDeleteTagResponse); i { case 0: return &v.state case 1: @@ -4386,7 +4934,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMergeBranchRequest); i { + switch v := v.(*UserCreateTagRequest); i { case 0: return &v.state case 1: @@ -4398,7 +4946,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMergeBranchResponse); i { + switch v := v.(*UserCreateTagResponse); i { case 0: return &v.state case 1: @@ -4410,7 +4958,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMergeBranchError); i { + switch v := v.(*UserCreateTagError); i { case 0: return &v.state case 1: @@ -4422,7 +4970,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMergeToRefRequest); i { + switch v := v.(*UserMergeBranchRequest); i { case 0: return &v.state case 1: @@ -4434,7 +4982,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMergeToRefResponse); i { + switch v := v.(*UserMergeBranchResponse); i { case 0: return &v.state case 1: @@ -4446,7 +4994,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OperationBranchUpdate); i { + switch v := v.(*UserMergeBranchError); i { case 0: return &v.state case 1: @@ -4458,7 +5006,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserFFBranchRequest); i { + switch v := v.(*UserMergeToRefRequest); i { case 0: return &v.state case 1: @@ -4470,7 +5018,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserFFBranchResponse); i { + switch v := v.(*UserMergeToRefResponse); i { case 0: return &v.state case 1: @@ -4482,7 +5030,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCherryPickRequest); i { + switch v := v.(*OperationBranchUpdate); i { case 0: return &v.state case 1: @@ -4494,7 +5042,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCherryPickResponse); i { + switch v := v.(*UserFFBranchRequest); i { case 0: return &v.state case 1: @@ -4506,7 +5054,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRevertRequest); i { + switch v := v.(*UserFFBranchResponse); i { case 0: return &v.state case 1: @@ -4518,7 +5066,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRevertResponse); i { + switch v := v.(*UserCherryPickRequest); i { case 0: return &v.state case 1: @@ -4530,7 +5078,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCommitFilesActionHeader); i { + switch v := v.(*UserCherryPickResponse); i { case 0: return &v.state case 1: @@ -4542,7 +5090,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCommitFilesAction); i { + switch v := v.(*UserCherryPickError); i { case 0: return &v.state case 1: @@ -4554,7 +5102,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCommitFilesRequestHeader); i { + switch v := v.(*UserRevertRequest); i { case 0: return &v.state case 1: @@ -4566,7 +5114,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCommitFilesRequest); i { + switch v := v.(*UserRevertResponse); i { case 0: return &v.state case 1: @@ -4578,7 +5126,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserCommitFilesResponse); i { + switch v := v.(*UserCommitFilesActionHeader); i { case 0: return &v.state case 1: @@ -4590,7 +5138,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRebaseConfirmableRequest); i { + switch v := v.(*UserCommitFilesAction); i { case 0: return &v.state case 1: @@ -4602,7 +5150,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRebaseConfirmableResponse); i { + switch v := v.(*UserCommitFilesRequestHeader); i { case 0: return &v.state case 1: @@ -4614,7 +5162,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserSquashRequest); i { + switch v := v.(*UserCommitFilesRequest); i { case 0: return &v.state case 1: @@ -4626,7 +5174,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserSquashResponse); i { + switch v := v.(*UserCommitFilesResponse); i { case 0: return &v.state case 1: @@ -4638,7 +5186,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRebaseConfirmableError); i { + switch v := v.(*UserRebaseConfirmableRequest); i { case 0: return &v.state case 1: @@ -4650,7 +5198,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserSquashError); i { + switch v := v.(*UserRebaseConfirmableResponse); i { case 0: return &v.state case 1: @@ -4662,7 +5210,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserApplyPatchRequest); i { + switch v := v.(*UserSquashRequest); i { case 0: return &v.state case 1: @@ -4674,7 +5222,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserApplyPatchResponse); i { + switch v := v.(*UserSquashResponse); i { case 0: return &v.state case 1: @@ -4686,7 +5234,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserUpdateSubmoduleRequest); i { + switch v := v.(*UserRebaseConfirmableError); i { case 0: return &v.state case 1: @@ -4698,7 +5246,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserUpdateSubmoduleResponse); i { + switch v := v.(*UserSquashError); i { case 0: return &v.state case 1: @@ -4710,7 +5258,7 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserRebaseConfirmableRequest_Header); i { + switch v := v.(*UserApplyPatchRequest); i { case 0: return &v.state case 1: @@ -4722,6 +5270,54 @@ func file_operations_proto_init() { } } file_operations_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserApplyPatchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_operations_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserUpdateSubmoduleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_operations_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserUpdateSubmoduleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_operations_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserRebaseConfirmableRequest_Header); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_operations_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserApplyPatchRequest_Header); i { case 0: return &v.state @@ -4734,35 +5330,57 @@ func file_operations_proto_init() { } } } + file_operations_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*UserCreateBranchError_CustomHook)(nil), + } + file_operations_proto_msgTypes[7].OneofWrappers = []interface{}{ + (*UserDeleteBranchError_AccessCheck)(nil), + (*UserDeleteBranchError_ReferenceUpdate)(nil), + (*UserDeleteBranchError_CustomHook)(nil), + } file_operations_proto_msgTypes[12].OneofWrappers = []interface{}{ + (*UserCreateTagError_AccessCheck)(nil), + (*UserCreateTagError_ReferenceUpdate)(nil), + (*UserCreateTagError_CustomHook)(nil), + (*UserCreateTagError_ReferenceExists)(nil), + } + file_operations_proto_msgTypes[15].OneofWrappers = []interface{}{ (*UserMergeBranchError_AccessCheck)(nil), (*UserMergeBranchError_ReferenceUpdate)(nil), + (*UserMergeBranchError_CustomHook)(nil), + (*UserMergeBranchError_MergeConflict)(nil), } file_operations_proto_msgTypes[23].OneofWrappers = []interface{}{ + (*UserCherryPickError_CherryPickConflict)(nil), + (*UserCherryPickError_TargetBranchDiverged)(nil), + (*UserCherryPickError_ChangesAlreadyApplied)(nil), + (*UserCherryPickError_AccessCheck)(nil), + } + file_operations_proto_msgTypes[27].OneofWrappers = []interface{}{ (*UserCommitFilesAction_Header)(nil), (*UserCommitFilesAction_Content)(nil), } - file_operations_proto_msgTypes[25].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[29].OneofWrappers = []interface{}{ (*UserCommitFilesRequest_Header)(nil), (*UserCommitFilesRequest_Action)(nil), } - file_operations_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[31].OneofWrappers = []interface{}{ (*UserRebaseConfirmableRequest_Header_)(nil), (*UserRebaseConfirmableRequest_Apply)(nil), } - file_operations_proto_msgTypes[28].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[32].OneofWrappers = []interface{}{ (*UserRebaseConfirmableResponse_RebaseSha)(nil), (*UserRebaseConfirmableResponse_RebaseApplied)(nil), } - file_operations_proto_msgTypes[31].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[35].OneofWrappers = []interface{}{ (*UserRebaseConfirmableError_RebaseConflict)(nil), (*UserRebaseConfirmableError_AccessCheck)(nil), } - file_operations_proto_msgTypes[32].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[36].OneofWrappers = []interface{}{ (*UserSquashError_ResolveRevision)(nil), (*UserSquashError_RebaseConflict)(nil), } - file_operations_proto_msgTypes[33].OneofWrappers = []interface{}{ + file_operations_proto_msgTypes[37].OneofWrappers = []interface{}{ (*UserApplyPatchRequest_Header_)(nil), (*UserApplyPatchRequest_Patches)(nil), } @@ -4772,7 +5390,7 @@ func file_operations_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_operations_proto_rawDesc, NumEnums: 3, - NumMessages: 39, + NumMessages: 43, NumExtensions: 0, NumServices: 1, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations_grpc.pb.go similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations_grpc.pb.go index 45c083841b..f472462dc6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/operations_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/operations_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: operations.proto package gitalypb @@ -18,11 +22,29 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type OperationServiceClient interface { + // This comment is left unintentionally blank. UserCreateBranch(ctx context.Context, in *UserCreateBranchRequest, opts ...grpc.CallOption) (*UserCreateBranchResponse, error) + // This comment is left unintentionally blank. UserUpdateBranch(ctx context.Context, in *UserUpdateBranchRequest, opts ...grpc.CallOption) (*UserUpdateBranchResponse, error) + // UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes + // hooks and contacts Rails to verify that the user is indeed allowed to delete that branch. The + // following known error conditions may happen: + // + // - Returns `InvalidArgument` in case either the branch name or user are not set. + // - Returns `FailedPrecondition` in case the branch does not exist. + // - Returns `OK` with a `PreReceiveError` in case custom hooks refused the update. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is enabled this error case will + // instead return `PermissionDenied` with either a `CustomHook` or AccessCheck` structured + // error. + // - Returns `FailedPrecondition` in case updating the reference fails because + // of a concurrent write to the same reference. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is set this error case will + // instead return `FailedPrecondition` with a `ReferenceUpdate` structured error. UserDeleteBranch(ctx context.Context, in *UserDeleteBranchRequest, opts ...grpc.CallOption) (*UserDeleteBranchResponse, error) - // UserCreateTag creates a new tag. + // UserCreateTag creates a new tag. This RPC knows to create both lightweight and annotated tags + // depending on whether a message is set. UserCreateTag(ctx context.Context, in *UserCreateTagRequest, opts ...grpc.CallOption) (*UserCreateTagResponse, error) + // This comment is left unintentionally blank. UserDeleteTag(ctx context.Context, in *UserDeleteTagRequest, opts ...grpc.CallOption) (*UserDeleteTagResponse, error) // UserMergeRef creates a merge commit and updates target_ref to point to that // new commit. The first parent of the merge commit (the main line) is taken @@ -316,11 +338,29 @@ func (c *operationServiceClient) UserUpdateSubmodule(ctx context.Context, in *Us // All implementations must embed UnimplementedOperationServiceServer // for forward compatibility type OperationServiceServer interface { + // This comment is left unintentionally blank. UserCreateBranch(context.Context, *UserCreateBranchRequest) (*UserCreateBranchResponse, error) + // This comment is left unintentionally blank. UserUpdateBranch(context.Context, *UserUpdateBranchRequest) (*UserUpdateBranchResponse, error) + // UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes + // hooks and contacts Rails to verify that the user is indeed allowed to delete that branch. The + // following known error conditions may happen: + // + // - Returns `InvalidArgument` in case either the branch name or user are not set. + // - Returns `FailedPrecondition` in case the branch does not exist. + // - Returns `OK` with a `PreReceiveError` in case custom hooks refused the update. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is enabled this error case will + // instead return `PermissionDenied` with either a `CustomHook` or AccessCheck` structured + // error. + // - Returns `FailedPrecondition` in case updating the reference fails because + // of a concurrent write to the same reference. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is set this error case will + // instead return `FailedPrecondition` with a `ReferenceUpdate` structured error. UserDeleteBranch(context.Context, *UserDeleteBranchRequest) (*UserDeleteBranchResponse, error) - // UserCreateTag creates a new tag. + // UserCreateTag creates a new tag. This RPC knows to create both lightweight and annotated tags + // depending on whether a message is set. UserCreateTag(context.Context, *UserCreateTagRequest) (*UserCreateTagResponse, error) + // This comment is left unintentionally blank. UserDeleteTag(context.Context, *UserDeleteTagRequest) (*UserDeleteTagResponse, error) // UserMergeRef creates a merge commit and updates target_ref to point to that // new commit. The first parent of the merge commit (the main line) is taken diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect.pb.go index e21485b62e..d50af3f144 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: praefect.proto package gitalypb @@ -473,13 +473,17 @@ func (x *SetReplicationFactorResponse) GetStorages() []string { return nil } +// This comment is left unintentionally blank. type SetAuthoritativeStorageRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - VirtualStorage string `protobuf:"bytes,1,opt,name=virtual_storage,json=virtualStorage,proto3" json:"virtual_storage,omitempty"` - RelativePath string `protobuf:"bytes,2,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` + // This comment is left unintentionally blank. + VirtualStorage string `protobuf:"bytes,1,opt,name=virtual_storage,json=virtualStorage,proto3" json:"virtual_storage,omitempty"` + // This comment is left unintentionally blank. + RelativePath string `protobuf:"bytes,2,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` + // This comment is left unintentionally blank. AuthoritativeStorage string `protobuf:"bytes,3,opt,name=authoritative_storage,json=authoritativeStorage,proto3" json:"authoritative_storage,omitempty"` } @@ -536,6 +540,7 @@ func (x *SetAuthoritativeStorageRequest) GetAuthoritativeStorage() string { return "" } +// This comment is left unintentionally blank. type SetAuthoritativeStorageResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -574,11 +579,13 @@ func (*SetAuthoritativeStorageResponse) Descriptor() ([]byte, []int) { return file_praefect_proto_rawDescGZIP(), []int{7} } +// This comment is left unintentionally blank. type DatalossCheckRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. VirtualStorage string `protobuf:"bytes,1,opt,name=virtual_storage,json=virtualStorage,proto3" json:"virtual_storage,omitempty"` // include_partially_unavailable indicates whether to include repositories which are available but // are unavailable on some assigned storages. @@ -631,6 +638,7 @@ func (x *DatalossCheckRequest) GetIncludePartiallyReplicated() bool { return false } +// This comment is left unintentionally blank. type DatalossCheckResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -679,11 +687,13 @@ func (x *DatalossCheckResponse) GetRepositories() []*DatalossCheckResponse_Repos return nil } +// This comment is left unintentionally blank. type RepositoryReplicasRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -726,12 +736,15 @@ func (x *RepositoryReplicasRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type RepositoryReplicasResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Primary *RepositoryReplicasResponse_RepositoryDetails `protobuf:"bytes,1,opt,name=primary,proto3" json:"primary,omitempty"` + // This comment is left unintentionally blank. + Primary *RepositoryReplicasResponse_RepositoryDetails `protobuf:"bytes,1,opt,name=primary,proto3" json:"primary,omitempty"` + // This comment is left unintentionally blank. Replicas []*RepositoryReplicasResponse_RepositoryDetails `protobuf:"bytes,2,rep,name=replicas,proto3" json:"replicas,omitempty"` } @@ -839,6 +852,7 @@ func (x *MarkUnverifiedRequest_Storage) GetStorage() string { return "" } +// This comment is left unintentionally blank. type GetRepositoryMetadataRequest_Path struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -896,6 +910,7 @@ func (x *GetRepositoryMetadataRequest_Path) GetRelativePath() string { return "" } +// This comment is left unintentionally blank. type GetRepositoryMetadataResponse_Replica struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -990,6 +1005,7 @@ func (x *GetRepositoryMetadataResponse_Replica) GetVerifiedAt() *timestamppb.Tim return nil } +// This comment is left unintentionally blank. type DatalossCheckResponse_Repository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1065,6 +1081,7 @@ func (x *DatalossCheckResponse_Repository) GetPrimary() string { return "" } +// This comment is left unintentionally blank. type DatalossCheckResponse_Repository_Storage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1149,13 +1166,16 @@ func (x *DatalossCheckResponse_Repository_Storage) GetValidPrimary() bool { return false } +// This comment is left unintentionally blank. type RepositoryReplicasResponse_RepositoryDetails struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Checksum string `protobuf:"bytes,2,opt,name=checksum,proto3" json:"checksum,omitempty"` + // This comment is left unintentionally blank. + Checksum string `protobuf:"bytes,2,opt,name=checksum,proto3" json:"checksum,omitempty"` } func (x *RepositoryReplicasResponse_RepositoryDetails) Reset() { @@ -1208,10 +1228,10 @@ var File_praefect_proto protoreflect.FileDescriptor var file_praefect_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x70, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x02, 0x0a, 0x15, 0x4d, 0x61, 0x72, 0x6b, 0x55, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, @@ -1405,7 +1425,7 @@ var file_praefect_proto_rawDesc = []byte{ 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, + 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect_grpc.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect_grpc.pb.go index b01e699f6f..09af7a43f0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/praefect_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/praefect_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: praefect.proto package gitalypb @@ -18,6 +22,7 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type PraefectInfoServiceClient interface { + // This comment is left unintentionally blank. RepositoryReplicas(ctx context.Context, in *RepositoryReplicasRequest, opts ...grpc.CallOption) (*RepositoryReplicasResponse, error) // DatalossCheck checks for unavailable repositories. DatalossCheck(ctx context.Context, in *DatalossCheckRequest, opts ...grpc.CallOption) (*DatalossCheckResponse, error) @@ -107,6 +112,7 @@ func (c *praefectInfoServiceClient) GetRepositoryMetadata(ctx context.Context, i // All implementations must embed UnimplementedPraefectInfoServiceServer // for forward compatibility type PraefectInfoServiceServer interface { + // This comment is left unintentionally blank. RepositoryReplicas(context.Context, *RepositoryReplicasRequest) (*RepositoryReplicasResponse, error) // DatalossCheck checks for unavailable repositories. DatalossCheck(context.Context, *DatalossCheckRequest) (*DatalossCheckResponse, error) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/protolist.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/protolist.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/protolist.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/protolist.go index afb0510ae7..a4845712bc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/protolist.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/protolist.go @@ -19,7 +19,7 @@ var GitalyProtos = []string{ "praefect.proto", "ref.proto", "remote.proto", - "repository-service.proto", + "repository.proto", "server.proto", "shared.proto", "smarthttp.proto", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref.pb.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref.pb.go index 116e1ac182..75e97e6897 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: ref.proto package gitalypb @@ -21,12 +21,16 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type FindLocalBranchesRequest_SortBy int32 const ( - FindLocalBranchesRequest_NAME FindLocalBranchesRequest_SortBy = 0 - FindLocalBranchesRequest_UPDATED_ASC FindLocalBranchesRequest_SortBy = 1 - FindLocalBranchesRequest_UPDATED_DESC FindLocalBranchesRequest_SortBy = 2 + // This comment is left unintentionally blank. + FindLocalBranchesRequest_NAME FindLocalBranchesRequest_SortBy = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + FindLocalBranchesRequest_UPDATED_ASC FindLocalBranchesRequest_SortBy = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + FindLocalBranchesRequest_UPDATED_DESC FindLocalBranchesRequest_SortBy = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for FindLocalBranchesRequest_SortBy. @@ -74,8 +78,15 @@ func (FindLocalBranchesRequest_SortBy) EnumDescriptor() ([]byte, []int) { type FindAllTagsRequest_SortBy_Key int32 const ( - FindAllTagsRequest_SortBy_REFNAME FindAllTagsRequest_SortBy_Key = 0 - FindAllTagsRequest_SortBy_CREATORDATE FindAllTagsRequest_SortBy_Key = 1 + // This comment is left unintentionally blank. + FindAllTagsRequest_SortBy_REFNAME FindAllTagsRequest_SortBy_Key = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + FindAllTagsRequest_SortBy_CREATORDATE FindAllTagsRequest_SortBy_Key = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // VERSION_REFNAME sorts tags by their semantic versions (https://semver.org/). + // Tag names that are not semantic versions are sorted lexicographically. They come before + // the semantic versions if the direction is ascending and after the semantic versions if + // the direction is descending. + FindAllTagsRequest_SortBy_VERSION_REFNAME FindAllTagsRequest_SortBy_Key = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for FindAllTagsRequest_SortBy_Key. @@ -83,10 +94,12 @@ var ( FindAllTagsRequest_SortBy_Key_name = map[int32]string{ 0: "REFNAME", 1: "CREATORDATE", + 2: "VERSION_REFNAME", } FindAllTagsRequest_SortBy_Key_value = map[string]int32{ - "REFNAME": 0, - "CREATORDATE": 1, + "REFNAME": 0, + "CREATORDATE": 1, + "VERSION_REFNAME": 2, } ) @@ -114,16 +127,21 @@ func (x FindAllTagsRequest_SortBy_Key) Number() protoreflect.EnumNumber { // Deprecated: Use FindAllTagsRequest_SortBy_Key.Descriptor instead. func (FindAllTagsRequest_SortBy_Key) EnumDescriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{14, 0, 0} + return file_ref_proto_rawDescGZIP(), []int{15, 0, 0} } +// This comment is left unintentionally blank. type CreateBranchResponse_Status int32 const ( - CreateBranchResponse_OK CreateBranchResponse_Status = 0 - CreateBranchResponse_ERR_EXISTS CreateBranchResponse_Status = 1 - CreateBranchResponse_ERR_INVALID CreateBranchResponse_Status = 2 - CreateBranchResponse_ERR_INVALID_START_POINT CreateBranchResponse_Status = 3 + // This comment is left unintentionally blank. + CreateBranchResponse_OK CreateBranchResponse_Status = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + CreateBranchResponse_ERR_EXISTS CreateBranchResponse_Status = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + CreateBranchResponse_ERR_INVALID CreateBranchResponse_Status = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + CreateBranchResponse_ERR_INVALID_START_POINT CreateBranchResponse_Status = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for CreateBranchResponse_Status. @@ -166,16 +184,21 @@ func (x CreateBranchResponse_Status) Number() protoreflect.EnumNumber { // Deprecated: Use CreateBranchResponse_Status.Descriptor instead. func (CreateBranchResponse_Status) EnumDescriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{19, 0} + return file_ref_proto_rawDescGZIP(), []int{20, 0} } +// This comment is left unintentionally blank. type ListRefsRequest_SortBy_Key int32 const ( - ListRefsRequest_SortBy_REFNAME ListRefsRequest_SortBy_Key = 0 - ListRefsRequest_SortBy_CREATORDATE ListRefsRequest_SortBy_Key = 1 - ListRefsRequest_SortBy_AUTHORDATE ListRefsRequest_SortBy_Key = 2 - ListRefsRequest_SortBy_COMMITTERDATE ListRefsRequest_SortBy_Key = 3 + // This comment is left unintentionally blank. + ListRefsRequest_SortBy_REFNAME ListRefsRequest_SortBy_Key = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ListRefsRequest_SortBy_CREATORDATE ListRefsRequest_SortBy_Key = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ListRefsRequest_SortBy_AUTHORDATE ListRefsRequest_SortBy_Key = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ListRefsRequest_SortBy_COMMITTERDATE ListRefsRequest_SortBy_Key = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for ListRefsRequest_SortBy_Key. @@ -218,14 +241,16 @@ func (x ListRefsRequest_SortBy_Key) Number() protoreflect.EnumNumber { // Deprecated: Use ListRefsRequest_SortBy_Key.Descriptor instead. func (ListRefsRequest_SortBy_Key) EnumDescriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{38, 0, 0} + return file_ref_proto_rawDescGZIP(), []int{40, 0, 0} } +// This comment is left unintentionally blank. type FindDefaultBranchNameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -268,11 +293,13 @@ func (x *FindDefaultBranchNameRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type FindDefaultBranchNameResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } @@ -315,11 +342,13 @@ func (x *FindDefaultBranchNameResponse) GetName() []byte { return nil } +// This comment is left unintentionally blank. type FindAllBranchNamesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -362,11 +391,13 @@ func (x *FindAllBranchNamesRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type FindAllBranchNamesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Names [][]byte `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` } @@ -409,11 +440,13 @@ func (x *FindAllBranchNamesResponse) GetNames() [][]byte { return nil } +// This comment is left unintentionally blank. type FindAllTagNamesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } @@ -456,11 +489,13 @@ func (x *FindAllTagNamesRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type FindAllTagNamesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Names [][]byte `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` } @@ -503,13 +538,16 @@ func (x *FindAllTagNamesResponse) GetNames() [][]byte { return nil } +// This comment is left unintentionally blank. type FindLocalBranchesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - SortBy FindLocalBranchesRequest_SortBy `protobuf:"varint,2,opt,name=sort_by,json=sortBy,proto3,enum=gitaly.FindLocalBranchesRequest_SortBy" json:"sort_by,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + SortBy FindLocalBranchesRequest_SortBy `protobuf:"varint,2,opt,name=sort_by,json=sortBy,proto3,enum=gitaly.FindLocalBranchesRequest_SortBy" json:"sort_by,omitempty"` // The page token is the branch name, with the `refs/heads/` prefix, for // example "refs/heads/master". After the first branch name is encountered // which lexicographically exceeds the page token, it will be the first result @@ -570,12 +608,18 @@ func (x *FindLocalBranchesRequest) GetPaginationParams() *PaginationParameter { return nil } +// This comment is left unintentionally blank. type FindLocalBranchesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This field is duplicated by 'local_branches' and will be marked deprecated + // as we add the implementation for 'local_branches'. + // Issue: https://gitlab.com/gitlab-org/gitaly/-/issues/1294 Branches []*FindLocalBranchResponse `protobuf:"bytes,1,rep,name=branches,proto3" json:"branches,omitempty"` + // This comment is left unintentionally blank. + LocalBranches []*Branch `protobuf:"bytes,2,rep,name=local_branches,json=localBranches,proto3" json:"local_branches,omitempty"` } func (x *FindLocalBranchesResponse) Reset() { @@ -617,17 +661,31 @@ func (x *FindLocalBranchesResponse) GetBranches() []*FindLocalBranchResponse { return nil } +func (x *FindLocalBranchesResponse) GetLocalBranches() []*Branch { + if x != nil { + return x.LocalBranches + } + return nil +} + +// This comment is left unintentionally blank. type FindLocalBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` - CommitSubject []byte `protobuf:"bytes,3,opt,name=commit_subject,json=commitSubject,proto3" json:"commit_subject,omitempty"` - CommitAuthor *FindLocalBranchCommitAuthor `protobuf:"bytes,4,opt,name=commit_author,json=commitAuthor,proto3" json:"commit_author,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + // This comment is left unintentionally blank. + CommitSubject []byte `protobuf:"bytes,3,opt,name=commit_subject,json=commitSubject,proto3" json:"commit_subject,omitempty"` + // This comment is left unintentionally blank. + CommitAuthor *FindLocalBranchCommitAuthor `protobuf:"bytes,4,opt,name=commit_author,json=commitAuthor,proto3" json:"commit_author,omitempty"` + // This comment is left unintentionally blank. CommitCommitter *FindLocalBranchCommitAuthor `protobuf:"bytes,5,opt,name=commit_committer,json=commitCommitter,proto3" json:"commit_committer,omitempty"` - Commit *GitCommit `protobuf:"bytes,6,opt,name=commit,proto3" json:"commit,omitempty"` + // This comment is left unintentionally blank. + Commit *GitCommit `protobuf:"bytes,6,opt,name=commit,proto3" json:"commit,omitempty"` } func (x *FindLocalBranchResponse) Reset() { @@ -704,15 +762,20 @@ func (x *FindLocalBranchResponse) GetCommit() *GitCommit { return nil } +// This comment is left unintentionally blank. type FindLocalBranchCommitAuthor struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` - Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"` - Timezone []byte `protobuf:"bytes,4,opt,name=timezone,proto3" json:"timezone,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // This comment is left unintentionally blank. + Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"` + // This comment is left unintentionally blank. + Timezone []byte `protobuf:"bytes,4,opt,name=timezone,proto3" json:"timezone,omitempty"` } func (x *FindLocalBranchCommitAuthor) Reset() { @@ -775,11 +838,13 @@ func (x *FindLocalBranchCommitAuthor) GetTimezone() []byte { return nil } +// This comment is left unintentionally blank. type FindAllBranchesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Only return branches that are merged into root ref MergedOnly bool `protobuf:"varint,2,opt,name=merged_only,json=mergedOnly,proto3" json:"merged_only,omitempty"` @@ -841,11 +906,13 @@ func (x *FindAllBranchesRequest) GetMergedBranches() [][]byte { return nil } +// This comment is left unintentionally blank. type FindAllBranchesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Branches []*FindAllBranchesResponse_Branch `protobuf:"bytes,1,rep,name=branches,proto3" json:"branches,omitempty"` } @@ -888,13 +955,18 @@ func (x *FindAllBranchesResponse) GetBranches() []*FindAllBranchesResponse_Branc return nil } +// FindTagRequest is a request for the FindTag RPC. type FindTagRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Repository is the repository to look up the tag in. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - TagName []byte `protobuf:"bytes,2,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"` + // TagName is the name of the tag that should be looked up. The caller is supposed to pass in the + // tag name only, so if e.g. a tag `refs/tags/v1.0.0` exists, then the caller should pass `v1.0.0` + // as argument. + TagName []byte `protobuf:"bytes,2,opt,name=tag_name,json=tagName,proto3" json:"tag_name,omitempty"` } func (x *FindTagRequest) Reset() { @@ -943,11 +1015,13 @@ func (x *FindTagRequest) GetTagName() []byte { return nil } +// FindTagResponse is a response for the FindTag RPC. type FindTagResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Tag is the tag that was found. Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` } @@ -990,11 +1064,82 @@ func (x *FindTagResponse) GetTag() *Tag { return nil } +// FindTagError is an error that will be returned by the FindTag RPC under specific error +// conditions. +type FindTagError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *FindTagError_TagNotFound + Error isFindTagError_Error `protobuf_oneof:"error"` +} + +func (x *FindTagError) Reset() { + *x = FindTagError{} + if protoimpl.UnsafeEnabled { + mi := &file_ref_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindTagError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindTagError) ProtoMessage() {} + +func (x *FindTagError) ProtoReflect() protoreflect.Message { + mi := &file_ref_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindTagError.ProtoReflect.Descriptor instead. +func (*FindTagError) Descriptor() ([]byte, []int) { + return file_ref_proto_rawDescGZIP(), []int{14} +} + +func (m *FindTagError) GetError() isFindTagError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *FindTagError) GetTagNotFound() *ReferenceNotFoundError { + if x, ok := x.GetError().(*FindTagError_TagNotFound); ok { + return x.TagNotFound + } + return nil +} + +type isFindTagError_Error interface { + isFindTagError_Error() +} + +type FindTagError_TagNotFound struct { + // TagNotFound indicates that the tag was not found. + TagNotFound *ReferenceNotFoundError `protobuf:"bytes,1,opt,name=tag_not_found,json=tagNotFound,proto3,oneof"` +} + +func (*FindTagError_TagNotFound) isFindTagError_Error() {} + +// This comment is left unintentionally blank. type FindAllTagsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // SortBy allows to request tags in particular order. SortBy *FindAllTagsRequest_SortBy `protobuf:"bytes,2,opt,name=sort_by,json=sortBy,proto3" json:"sort_by,omitempty"` @@ -1007,7 +1152,7 @@ type FindAllTagsRequest struct { func (x *FindAllTagsRequest) Reset() { *x = FindAllTagsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[14] + mi := &file_ref_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1020,7 +1165,7 @@ func (x *FindAllTagsRequest) String() string { func (*FindAllTagsRequest) ProtoMessage() {} func (x *FindAllTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[14] + mi := &file_ref_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1033,7 +1178,7 @@ func (x *FindAllTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllTagsRequest.ProtoReflect.Descriptor instead. func (*FindAllTagsRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{14} + return file_ref_proto_rawDescGZIP(), []int{15} } func (x *FindAllTagsRequest) GetRepository() *Repository { @@ -1057,18 +1202,20 @@ func (x *FindAllTagsRequest) GetPaginationParams() *PaginationParameter { return nil } +// This comment is left unintentionally blank. type FindAllTagsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Tags []*Tag `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` } func (x *FindAllTagsResponse) Reset() { *x = FindAllTagsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[15] + mi := &file_ref_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1081,7 +1228,7 @@ func (x *FindAllTagsResponse) String() string { func (*FindAllTagsResponse) ProtoMessage() {} func (x *FindAllTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[15] + mi := &file_ref_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1094,7 +1241,7 @@ func (x *FindAllTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllTagsResponse.ProtoReflect.Descriptor instead. func (*FindAllTagsResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{15} + return file_ref_proto_rawDescGZIP(), []int{16} } func (x *FindAllTagsResponse) GetTags() []*Tag { @@ -1104,11 +1251,13 @@ func (x *FindAllTagsResponse) GetTags() []*Tag { return nil } +// This comment is left unintentionally blank. type RefExistsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Any ref, e.g. 'refs/heads/master' or 'refs/tags/v1.0.1'. Must start with 'refs/'. Ref []byte `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` @@ -1117,7 +1266,7 @@ type RefExistsRequest struct { func (x *RefExistsRequest) Reset() { *x = RefExistsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[16] + mi := &file_ref_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1130,7 +1279,7 @@ func (x *RefExistsRequest) String() string { func (*RefExistsRequest) ProtoMessage() {} func (x *RefExistsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[16] + mi := &file_ref_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1143,7 +1292,7 @@ func (x *RefExistsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefExistsRequest.ProtoReflect.Descriptor instead. func (*RefExistsRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{16} + return file_ref_proto_rawDescGZIP(), []int{17} } func (x *RefExistsRequest) GetRepository() *Repository { @@ -1160,18 +1309,20 @@ func (x *RefExistsRequest) GetRef() []byte { return nil } +// This comment is left unintentionally blank. type RefExistsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` } func (x *RefExistsResponse) Reset() { *x = RefExistsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[17] + mi := &file_ref_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1184,7 +1335,7 @@ func (x *RefExistsResponse) String() string { func (*RefExistsResponse) ProtoMessage() {} func (x *RefExistsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[17] + mi := &file_ref_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1197,7 +1348,7 @@ func (x *RefExistsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefExistsResponse.ProtoReflect.Descriptor instead. func (*RefExistsResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{17} + return file_ref_proto_rawDescGZIP(), []int{18} } func (x *RefExistsResponse) GetValue() bool { @@ -1207,20 +1358,24 @@ func (x *RefExistsResponse) GetValue() bool { return false } +// This comment is left unintentionally blank. type CreateBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - StartPoint []byte `protobuf:"bytes,3,opt,name=start_point,json=startPoint,proto3" json:"start_point,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + StartPoint []byte `protobuf:"bytes,3,opt,name=start_point,json=startPoint,proto3" json:"start_point,omitempty"` } func (x *CreateBranchRequest) Reset() { *x = CreateBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[18] + mi := &file_ref_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1233,7 +1388,7 @@ func (x *CreateBranchRequest) String() string { func (*CreateBranchRequest) ProtoMessage() {} func (x *CreateBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[18] + mi := &file_ref_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1246,7 +1401,7 @@ func (x *CreateBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBranchRequest.ProtoReflect.Descriptor instead. func (*CreateBranchRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{18} + return file_ref_proto_rawDescGZIP(), []int{19} } func (x *CreateBranchRequest) GetRepository() *Repository { @@ -1270,19 +1425,22 @@ func (x *CreateBranchRequest) GetStartPoint() []byte { return nil } +// This comment is left unintentionally blank. type CreateBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Status CreateBranchResponse_Status `protobuf:"varint,1,opt,name=status,proto3,enum=gitaly.CreateBranchResponse_Status" json:"status,omitempty"` - Branch *Branch `protobuf:"bytes,2,opt,name=branch,proto3" json:"branch,omitempty"` + // This comment is left unintentionally blank. + Branch *Branch `protobuf:"bytes,2,opt,name=branch,proto3" json:"branch,omitempty"` } func (x *CreateBranchResponse) Reset() { *x = CreateBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[19] + mi := &file_ref_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1295,7 +1453,7 @@ func (x *CreateBranchResponse) String() string { func (*CreateBranchResponse) ProtoMessage() {} func (x *CreateBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[19] + mi := &file_ref_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1308,7 +1466,7 @@ func (x *CreateBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBranchResponse.ProtoReflect.Descriptor instead. func (*CreateBranchResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{19} + return file_ref_proto_rawDescGZIP(), []int{20} } func (x *CreateBranchResponse) GetStatus() CreateBranchResponse_Status { @@ -1325,19 +1483,22 @@ func (x *CreateBranchResponse) GetBranch() *Branch { return nil } +// This comment is left unintentionally blank. type DeleteBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (x *DeleteBranchRequest) Reset() { *x = DeleteBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[20] + mi := &file_ref_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1350,7 +1511,7 @@ func (x *DeleteBranchRequest) String() string { func (*DeleteBranchRequest) ProtoMessage() {} func (x *DeleteBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[20] + mi := &file_ref_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1363,7 +1524,7 @@ func (x *DeleteBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteBranchRequest.ProtoReflect.Descriptor instead. func (*DeleteBranchRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{20} + return file_ref_proto_rawDescGZIP(), []int{21} } func (x *DeleteBranchRequest) GetRepository() *Repository { @@ -1390,7 +1551,7 @@ type DeleteBranchResponse struct { func (x *DeleteBranchResponse) Reset() { *x = DeleteBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[21] + mi := &file_ref_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1403,7 +1564,7 @@ func (x *DeleteBranchResponse) String() string { func (*DeleteBranchResponse) ProtoMessage() {} func (x *DeleteBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[21] + mi := &file_ref_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1416,9 +1577,10 @@ func (x *DeleteBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteBranchResponse.ProtoReflect.Descriptor instead. func (*DeleteBranchResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{21} + return file_ref_proto_rawDescGZIP(), []int{22} } +// This comment is left unintentionally blank. type FindBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1434,7 +1596,7 @@ type FindBranchRequest struct { func (x *FindBranchRequest) Reset() { *x = FindBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[22] + mi := &file_ref_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1447,7 +1609,7 @@ func (x *FindBranchRequest) String() string { func (*FindBranchRequest) ProtoMessage() {} func (x *FindBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[22] + mi := &file_ref_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1460,7 +1622,7 @@ func (x *FindBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindBranchRequest.ProtoReflect.Descriptor instead. func (*FindBranchRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{22} + return file_ref_proto_rawDescGZIP(), []int{23} } func (x *FindBranchRequest) GetRepository() *Repository { @@ -1477,18 +1639,20 @@ func (x *FindBranchRequest) GetName() []byte { return nil } +// This comment is left unintentionally blank. type FindBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Branch *Branch `protobuf:"bytes,1,opt,name=branch,proto3" json:"branch,omitempty"` } func (x *FindBranchResponse) Reset() { *x = FindBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[23] + mi := &file_ref_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1501,7 +1665,7 @@ func (x *FindBranchResponse) String() string { func (*FindBranchResponse) ProtoMessage() {} func (x *FindBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[23] + mi := &file_ref_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1514,7 +1678,7 @@ func (x *FindBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindBranchResponse.ProtoReflect.Descriptor instead. func (*FindBranchResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{23} + return file_ref_proto_rawDescGZIP(), []int{24} } func (x *FindBranchResponse) GetBranch() *Branch { @@ -1524,21 +1688,24 @@ func (x *FindBranchResponse) GetBranch() *Branch { return nil } +// This comment is left unintentionally blank. type DeleteRefsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // The following two fields are mutually exclusive - ExceptWithPrefix [][]byte `protobuf:"bytes,2,rep,name=except_with_prefix,json=exceptWithPrefix,proto3" json:"except_with_prefix,omitempty"` - Refs [][]byte `protobuf:"bytes,3,rep,name=refs,proto3" json:"refs,omitempty"` + ExceptWithPrefix [][]byte `protobuf:"bytes,2,rep,name=except_with_prefix,json=exceptWithPrefix,proto3" json:"except_with_prefix,omitempty"` // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED + // This comment is left unintentionally blank. + Refs [][]byte `protobuf:"bytes,3,rep,name=refs,proto3" json:"refs,omitempty"` } func (x *DeleteRefsRequest) Reset() { *x = DeleteRefsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[24] + mi := &file_ref_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1551,7 +1718,7 @@ func (x *DeleteRefsRequest) String() string { func (*DeleteRefsRequest) ProtoMessage() {} func (x *DeleteRefsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[24] + mi := &file_ref_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1564,7 +1731,7 @@ func (x *DeleteRefsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRefsRequest.ProtoReflect.Descriptor instead. func (*DeleteRefsRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{24} + return file_ref_proto_rawDescGZIP(), []int{25} } func (x *DeleteRefsRequest) GetRepository() *Repository { @@ -1588,18 +1755,20 @@ func (x *DeleteRefsRequest) GetRefs() [][]byte { return nil } +// This comment is left unintentionally blank. type DeleteRefsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. GitError string `protobuf:"bytes,1,opt,name=git_error,json=gitError,proto3" json:"git_error,omitempty"` } func (x *DeleteRefsResponse) Reset() { *x = DeleteRefsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[25] + mi := &file_ref_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1612,7 +1781,7 @@ func (x *DeleteRefsResponse) String() string { func (*DeleteRefsResponse) ProtoMessage() {} func (x *DeleteRefsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[25] + mi := &file_ref_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1625,7 +1794,7 @@ func (x *DeleteRefsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRefsResponse.ProtoReflect.Descriptor instead. func (*DeleteRefsResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{25} + return file_ref_proto_rawDescGZIP(), []int{26} } func (x *DeleteRefsResponse) GetGitError() string { @@ -1635,13 +1804,101 @@ func (x *DeleteRefsResponse) GetGitError() string { return "" } +// DeleteRefsError is returned when DeleteRefs fails to delete refs +type DeleteRefsError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Error: + // *DeleteRefsError_InvalidFormat + // *DeleteRefsError_ReferencesLocked + Error isDeleteRefsError_Error `protobuf_oneof:"error"` +} + +func (x *DeleteRefsError) Reset() { + *x = DeleteRefsError{} + if protoimpl.UnsafeEnabled { + mi := &file_ref_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRefsError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRefsError) ProtoMessage() {} + +func (x *DeleteRefsError) ProtoReflect() protoreflect.Message { + mi := &file_ref_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRefsError.ProtoReflect.Descriptor instead. +func (*DeleteRefsError) Descriptor() ([]byte, []int) { + return file_ref_proto_rawDescGZIP(), []int{27} +} + +func (m *DeleteRefsError) GetError() isDeleteRefsError_Error { + if m != nil { + return m.Error + } + return nil +} + +func (x *DeleteRefsError) GetInvalidFormat() *InvalidRefFormatError { + if x, ok := x.GetError().(*DeleteRefsError_InvalidFormat); ok { + return x.InvalidFormat + } + return nil +} + +func (x *DeleteRefsError) GetReferencesLocked() *ReferencesLockedError { + if x, ok := x.GetError().(*DeleteRefsError_ReferencesLocked); ok { + return x.ReferencesLocked + } + return nil +} + +type isDeleteRefsError_Error interface { + isDeleteRefsError_Error() +} + +type DeleteRefsError_InvalidFormat struct { + // InvalidFormat is returned when one or more of the refs to be deleted + // have an invalid format. + InvalidFormat *InvalidRefFormatError `protobuf:"bytes,1,opt,name=invalid_format,json=invalidFormat,proto3,oneof"` +} + +type DeleteRefsError_ReferencesLocked struct { + // ReferencesLocked is returned when the references to be deleted are already + // locked by another process. + ReferencesLocked *ReferencesLockedError `protobuf:"bytes,2,opt,name=references_locked,json=referencesLocked,proto3,oneof"` +} + +func (*DeleteRefsError_InvalidFormat) isDeleteRefsError_Error() {} + +func (*DeleteRefsError_ReferencesLocked) isDeleteRefsError_Error() {} + +// This comment is left unintentionally blank. type ListBranchNamesContainingCommitRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + // This comment is left unintentionally blank. + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` // Limit the number of tag names to be returned // If the limit is set to zero, all items will be returned Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` @@ -1650,7 +1907,7 @@ type ListBranchNamesContainingCommitRequest struct { func (x *ListBranchNamesContainingCommitRequest) Reset() { *x = ListBranchNamesContainingCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[26] + mi := &file_ref_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1663,7 +1920,7 @@ func (x *ListBranchNamesContainingCommitRequest) String() string { func (*ListBranchNamesContainingCommitRequest) ProtoMessage() {} func (x *ListBranchNamesContainingCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[26] + mi := &file_ref_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1676,7 +1933,7 @@ func (x *ListBranchNamesContainingCommitRequest) ProtoReflect() protoreflect.Mes // Deprecated: Use ListBranchNamesContainingCommitRequest.ProtoReflect.Descriptor instead. func (*ListBranchNamesContainingCommitRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{26} + return file_ref_proto_rawDescGZIP(), []int{28} } func (x *ListBranchNamesContainingCommitRequest) GetRepository() *Repository { @@ -1700,18 +1957,20 @@ func (x *ListBranchNamesContainingCommitRequest) GetLimit() uint32 { return 0 } +// This comment is left unintentionally blank. type ListBranchNamesContainingCommitResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. BranchNames [][]byte `protobuf:"bytes,2,rep,name=branch_names,json=branchNames,proto3" json:"branch_names,omitempty"` } func (x *ListBranchNamesContainingCommitResponse) Reset() { *x = ListBranchNamesContainingCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[27] + mi := &file_ref_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1724,7 +1983,7 @@ func (x *ListBranchNamesContainingCommitResponse) String() string { func (*ListBranchNamesContainingCommitResponse) ProtoMessage() {} func (x *ListBranchNamesContainingCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[27] + mi := &file_ref_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1737,7 +1996,7 @@ func (x *ListBranchNamesContainingCommitResponse) ProtoReflect() protoreflect.Me // Deprecated: Use ListBranchNamesContainingCommitResponse.ProtoReflect.Descriptor instead. func (*ListBranchNamesContainingCommitResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{27} + return file_ref_proto_rawDescGZIP(), []int{29} } func (x *ListBranchNamesContainingCommitResponse) GetBranchNames() [][]byte { @@ -1747,13 +2006,16 @@ func (x *ListBranchNamesContainingCommitResponse) GetBranchNames() [][]byte { return nil } +// This comment is left unintentionally blank. type ListTagNamesContainingCommitRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + // This comment is left unintentionally blank. + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` // Limit the number of tag names to be returned // If the limit is set to zero, all items will be returned Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` @@ -1762,7 +2024,7 @@ type ListTagNamesContainingCommitRequest struct { func (x *ListTagNamesContainingCommitRequest) Reset() { *x = ListTagNamesContainingCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[28] + mi := &file_ref_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1775,7 +2037,7 @@ func (x *ListTagNamesContainingCommitRequest) String() string { func (*ListTagNamesContainingCommitRequest) ProtoMessage() {} func (x *ListTagNamesContainingCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[28] + mi := &file_ref_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1788,7 +2050,7 @@ func (x *ListTagNamesContainingCommitRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use ListTagNamesContainingCommitRequest.ProtoReflect.Descriptor instead. func (*ListTagNamesContainingCommitRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{28} + return file_ref_proto_rawDescGZIP(), []int{30} } func (x *ListTagNamesContainingCommitRequest) GetRepository() *Repository { @@ -1812,18 +2074,20 @@ func (x *ListTagNamesContainingCommitRequest) GetLimit() uint32 { return 0 } +// This comment is left unintentionally blank. type ListTagNamesContainingCommitResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. TagNames [][]byte `protobuf:"bytes,2,rep,name=tag_names,json=tagNames,proto3" json:"tag_names,omitempty"` } func (x *ListTagNamesContainingCommitResponse) Reset() { *x = ListTagNamesContainingCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[29] + mi := &file_ref_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1836,7 +2100,7 @@ func (x *ListTagNamesContainingCommitResponse) String() string { func (*ListTagNamesContainingCommitResponse) ProtoMessage() {} func (x *ListTagNamesContainingCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[29] + mi := &file_ref_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1849,7 +2113,7 @@ func (x *ListTagNamesContainingCommitResponse) ProtoReflect() protoreflect.Messa // Deprecated: Use ListTagNamesContainingCommitResponse.ProtoReflect.Descriptor instead. func (*ListTagNamesContainingCommitResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{29} + return file_ref_proto_rawDescGZIP(), []int{31} } func (x *ListTagNamesContainingCommitResponse) GetTagNames() [][]byte { @@ -1876,7 +2140,7 @@ type GetTagSignaturesRequest struct { func (x *GetTagSignaturesRequest) Reset() { *x = GetTagSignaturesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[30] + mi := &file_ref_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1889,7 +2153,7 @@ func (x *GetTagSignaturesRequest) String() string { func (*GetTagSignaturesRequest) ProtoMessage() {} func (x *GetTagSignaturesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[30] + mi := &file_ref_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1902,7 +2166,7 @@ func (x *GetTagSignaturesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagSignaturesRequest.ProtoReflect.Descriptor instead. func (*GetTagSignaturesRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{30} + return file_ref_proto_rawDescGZIP(), []int{32} } func (x *GetTagSignaturesRequest) GetRepository() *Repository { @@ -1934,7 +2198,7 @@ type GetTagSignaturesResponse struct { func (x *GetTagSignaturesResponse) Reset() { *x = GetTagSignaturesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[31] + mi := &file_ref_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1947,7 +2211,7 @@ func (x *GetTagSignaturesResponse) String() string { func (*GetTagSignaturesResponse) ProtoMessage() {} func (x *GetTagSignaturesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[31] + mi := &file_ref_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1960,7 +2224,7 @@ func (x *GetTagSignaturesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagSignaturesResponse.ProtoReflect.Descriptor instead. func (*GetTagSignaturesResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{31} + return file_ref_proto_rawDescGZIP(), []int{33} } func (x *GetTagSignaturesResponse) GetSignatures() []*GetTagSignaturesResponse_TagSignature { @@ -1970,19 +2234,22 @@ func (x *GetTagSignaturesResponse) GetSignatures() []*GetTagSignaturesResponse_T return nil } +// This comment is left unintentionally blank. type GetTagMessagesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - TagIds []string `protobuf:"bytes,3,rep,name=tag_ids,json=tagIds,proto3" json:"tag_ids,omitempty"` + // This comment is left unintentionally blank. + TagIds []string `protobuf:"bytes,3,rep,name=tag_ids,json=tagIds,proto3" json:"tag_ids,omitempty"` } func (x *GetTagMessagesRequest) Reset() { *x = GetTagMessagesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[32] + mi := &file_ref_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1995,7 +2262,7 @@ func (x *GetTagMessagesRequest) String() string { func (*GetTagMessagesRequest) ProtoMessage() {} func (x *GetTagMessagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[32] + mi := &file_ref_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2008,7 +2275,7 @@ func (x *GetTagMessagesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagMessagesRequest.ProtoReflect.Descriptor instead. func (*GetTagMessagesRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{32} + return file_ref_proto_rawDescGZIP(), []int{34} } func (x *GetTagMessagesRequest) GetRepository() *Repository { @@ -2025,11 +2292,13 @@ func (x *GetTagMessagesRequest) GetTagIds() []string { return nil } +// This comment is left unintentionally blank. type GetTagMessagesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // Only present for a new tag message TagId string `protobuf:"bytes,3,opt,name=tag_id,json=tagId,proto3" json:"tag_id,omitempty"` @@ -2038,7 +2307,7 @@ type GetTagMessagesResponse struct { func (x *GetTagMessagesResponse) Reset() { *x = GetTagMessagesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[33] + mi := &file_ref_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2051,7 +2320,7 @@ func (x *GetTagMessagesResponse) String() string { func (*GetTagMessagesResponse) ProtoMessage() {} func (x *GetTagMessagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[33] + mi := &file_ref_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2064,7 +2333,7 @@ func (x *GetTagMessagesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagMessagesResponse.ProtoReflect.Descriptor instead. func (*GetTagMessagesResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{33} + return file_ref_proto_rawDescGZIP(), []int{35} } func (x *GetTagMessagesResponse) GetMessage() []byte { @@ -2081,19 +2350,22 @@ func (x *GetTagMessagesResponse) GetTagId() string { return "" } +// This comment is left unintentionally blank. type FindAllRemoteBranchesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - RemoteName string `protobuf:"bytes,2,opt,name=remote_name,json=remoteName,proto3" json:"remote_name,omitempty"` + // This comment is left unintentionally blank. + RemoteName string `protobuf:"bytes,2,opt,name=remote_name,json=remoteName,proto3" json:"remote_name,omitempty"` } func (x *FindAllRemoteBranchesRequest) Reset() { *x = FindAllRemoteBranchesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[34] + mi := &file_ref_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2106,7 +2378,7 @@ func (x *FindAllRemoteBranchesRequest) String() string { func (*FindAllRemoteBranchesRequest) ProtoMessage() {} func (x *FindAllRemoteBranchesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[34] + mi := &file_ref_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2119,7 +2391,7 @@ func (x *FindAllRemoteBranchesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllRemoteBranchesRequest.ProtoReflect.Descriptor instead. func (*FindAllRemoteBranchesRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{34} + return file_ref_proto_rawDescGZIP(), []int{36} } func (x *FindAllRemoteBranchesRequest) GetRepository() *Repository { @@ -2136,18 +2408,20 @@ func (x *FindAllRemoteBranchesRequest) GetRemoteName() string { return "" } +// This comment is left unintentionally blank. type FindAllRemoteBranchesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Branches []*Branch `protobuf:"bytes,1,rep,name=branches,proto3" json:"branches,omitempty"` } func (x *FindAllRemoteBranchesResponse) Reset() { *x = FindAllRemoteBranchesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[35] + mi := &file_ref_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2160,7 +2434,7 @@ func (x *FindAllRemoteBranchesResponse) String() string { func (*FindAllRemoteBranchesResponse) ProtoMessage() {} func (x *FindAllRemoteBranchesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[35] + mi := &file_ref_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2173,7 +2447,7 @@ func (x *FindAllRemoteBranchesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllRemoteBranchesResponse.ProtoReflect.Descriptor instead. func (*FindAllRemoteBranchesResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{35} + return file_ref_proto_rawDescGZIP(), []int{37} } func (x *FindAllRemoteBranchesResponse) GetBranches() []*Branch { @@ -2183,18 +2457,20 @@ func (x *FindAllRemoteBranchesResponse) GetBranches() []*Branch { return nil } +// This comment is left unintentionally blank. type PackRefsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *PackRefsRequest) Reset() { *x = PackRefsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[36] + mi := &file_ref_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2207,7 +2483,7 @@ func (x *PackRefsRequest) String() string { func (*PackRefsRequest) ProtoMessage() {} func (x *PackRefsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[36] + mi := &file_ref_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2220,7 +2496,7 @@ func (x *PackRefsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PackRefsRequest.ProtoReflect.Descriptor instead. func (*PackRefsRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{36} + return file_ref_proto_rawDescGZIP(), []int{38} } func (x *PackRefsRequest) GetRepository() *Repository { @@ -2230,6 +2506,7 @@ func (x *PackRefsRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type PackRefsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2239,7 +2516,7 @@ type PackRefsResponse struct { func (x *PackRefsResponse) Reset() { *x = PackRefsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[37] + mi := &file_ref_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2252,7 +2529,7 @@ func (x *PackRefsResponse) String() string { func (*PackRefsResponse) ProtoMessage() {} func (x *PackRefsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[37] + mi := &file_ref_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2265,7 +2542,7 @@ func (x *PackRefsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PackRefsResponse.ProtoReflect.Descriptor instead. func (*PackRefsResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{37} + return file_ref_proto_rawDescGZIP(), []int{39} } // ListRefsRequest is a request for the ListRefs RPC. @@ -2290,7 +2567,7 @@ type ListRefsRequest struct { func (x *ListRefsRequest) Reset() { *x = ListRefsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[38] + mi := &file_ref_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2303,7 +2580,7 @@ func (x *ListRefsRequest) String() string { func (*ListRefsRequest) ProtoMessage() {} func (x *ListRefsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[38] + mi := &file_ref_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2316,7 +2593,7 @@ func (x *ListRefsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefsRequest.ProtoReflect.Descriptor instead. func (*ListRefsRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{38} + return file_ref_proto_rawDescGZIP(), []int{40} } func (x *ListRefsRequest) GetRepository() *Repository { @@ -2361,7 +2638,7 @@ type ListRefsResponse struct { func (x *ListRefsResponse) Reset() { *x = ListRefsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[39] + mi := &file_ref_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2374,7 +2651,7 @@ func (x *ListRefsResponse) String() string { func (*ListRefsResponse) ProtoMessage() {} func (x *ListRefsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[39] + mi := &file_ref_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2387,7 +2664,7 @@ func (x *ListRefsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefsResponse.ProtoReflect.Descriptor instead. func (*ListRefsResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{39} + return file_ref_proto_rawDescGZIP(), []int{41} } func (x *ListRefsResponse) GetReferences() []*ListRefsResponse_Reference { @@ -2397,6 +2674,7 @@ func (x *ListRefsResponse) GetReferences() []*ListRefsResponse_Reference { return nil } +// This comment is left unintentionally blank. type FindRefsByOIDRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2420,7 +2698,7 @@ type FindRefsByOIDRequest struct { func (x *FindRefsByOIDRequest) Reset() { *x = FindRefsByOIDRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[40] + mi := &file_ref_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2433,7 +2711,7 @@ func (x *FindRefsByOIDRequest) String() string { func (*FindRefsByOIDRequest) ProtoMessage() {} func (x *FindRefsByOIDRequest) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[40] + mi := &file_ref_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2446,7 +2724,7 @@ func (x *FindRefsByOIDRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindRefsByOIDRequest.ProtoReflect.Descriptor instead. func (*FindRefsByOIDRequest) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{40} + return file_ref_proto_rawDescGZIP(), []int{42} } func (x *FindRefsByOIDRequest) GetRepository() *Repository { @@ -2484,6 +2762,7 @@ func (x *FindRefsByOIDRequest) GetLimit() uint32 { return 0 } +// This comment is left unintentionally blank. type FindRefsByOIDResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2496,7 +2775,7 @@ type FindRefsByOIDResponse struct { func (x *FindRefsByOIDResponse) Reset() { *x = FindRefsByOIDResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[41] + mi := &file_ref_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2509,7 +2788,7 @@ func (x *FindRefsByOIDResponse) String() string { func (*FindRefsByOIDResponse) ProtoMessage() {} func (x *FindRefsByOIDResponse) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[41] + mi := &file_ref_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2522,7 +2801,7 @@ func (x *FindRefsByOIDResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindRefsByOIDResponse.ProtoReflect.Descriptor instead. func (*FindRefsByOIDResponse) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{41} + return file_ref_proto_rawDescGZIP(), []int{43} } func (x *FindRefsByOIDResponse) GetRefs() []string { @@ -2532,19 +2811,22 @@ func (x *FindRefsByOIDResponse) GetRefs() []string { return nil } +// This comment is left unintentionally blank. type FindAllBranchesResponse_Branch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. Target *GitCommit `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` } func (x *FindAllBranchesResponse_Branch) Reset() { *x = FindAllBranchesResponse_Branch{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[42] + mi := &file_ref_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2557,7 +2839,7 @@ func (x *FindAllBranchesResponse_Branch) String() string { func (*FindAllBranchesResponse_Branch) ProtoMessage() {} func (x *FindAllBranchesResponse_Branch) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[42] + mi := &file_ref_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2593,14 +2875,16 @@ type FindAllTagsRequest_SortBy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key FindAllTagsRequest_SortBy_Key `protobuf:"varint,1,opt,name=key,proto3,enum=gitaly.FindAllTagsRequest_SortBy_Key" json:"key,omitempty"` - Direction SortDirection `protobuf:"varint,2,opt,name=direction,proto3,enum=gitaly.SortDirection" json:"direction,omitempty"` + // This comment is left unintentionally blank. + Key FindAllTagsRequest_SortBy_Key `protobuf:"varint,1,opt,name=key,proto3,enum=gitaly.FindAllTagsRequest_SortBy_Key" json:"key,omitempty"` + // This comment is left unintentionally blank. + Direction SortDirection `protobuf:"varint,2,opt,name=direction,proto3,enum=gitaly.SortDirection" json:"direction,omitempty"` } func (x *FindAllTagsRequest_SortBy) Reset() { *x = FindAllTagsRequest_SortBy{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[43] + mi := &file_ref_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2613,7 +2897,7 @@ func (x *FindAllTagsRequest_SortBy) String() string { func (*FindAllTagsRequest_SortBy) ProtoMessage() {} func (x *FindAllTagsRequest_SortBy) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[43] + mi := &file_ref_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2626,7 +2910,7 @@ func (x *FindAllTagsRequest_SortBy) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllTagsRequest_SortBy.ProtoReflect.Descriptor instead. func (*FindAllTagsRequest_SortBy) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{14, 0} + return file_ref_proto_rawDescGZIP(), []int{15, 0} } func (x *FindAllTagsRequest_SortBy) GetKey() FindAllTagsRequest_SortBy_Key { @@ -2663,7 +2947,7 @@ type GetTagSignaturesResponse_TagSignature struct { func (x *GetTagSignaturesResponse_TagSignature) Reset() { *x = GetTagSignaturesResponse_TagSignature{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[44] + mi := &file_ref_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2676,7 +2960,7 @@ func (x *GetTagSignaturesResponse_TagSignature) String() string { func (*GetTagSignaturesResponse_TagSignature) ProtoMessage() {} func (x *GetTagSignaturesResponse_TagSignature) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[44] + mi := &file_ref_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2689,7 +2973,7 @@ func (x *GetTagSignaturesResponse_TagSignature) ProtoReflect() protoreflect.Mess // Deprecated: Use GetTagSignaturesResponse_TagSignature.ProtoReflect.Descriptor instead. func (*GetTagSignaturesResponse_TagSignature) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{31, 0} + return file_ref_proto_rawDescGZIP(), []int{33, 0} } func (x *GetTagSignaturesResponse_TagSignature) GetTagId() string { @@ -2713,20 +2997,22 @@ func (x *GetTagSignaturesResponse_TagSignature) GetContent() []byte { return nil } +// This comment is left unintentionally blank. type ListRefsRequest_SortBy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Key is a key used for sorting. - Key ListRefsRequest_SortBy_Key `protobuf:"varint,1,opt,name=key,proto3,enum=gitaly.ListRefsRequest_SortBy_Key" json:"key,omitempty"` - Direction SortDirection `protobuf:"varint,2,opt,name=direction,proto3,enum=gitaly.SortDirection" json:"direction,omitempty"` + Key ListRefsRequest_SortBy_Key `protobuf:"varint,1,opt,name=key,proto3,enum=gitaly.ListRefsRequest_SortBy_Key" json:"key,omitempty"` + // This comment is left unintentionally blank. + Direction SortDirection `protobuf:"varint,2,opt,name=direction,proto3,enum=gitaly.SortDirection" json:"direction,omitempty"` } func (x *ListRefsRequest_SortBy) Reset() { *x = ListRefsRequest_SortBy{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[45] + mi := &file_ref_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2739,7 +3025,7 @@ func (x *ListRefsRequest_SortBy) String() string { func (*ListRefsRequest_SortBy) ProtoMessage() {} func (x *ListRefsRequest_SortBy) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[45] + mi := &file_ref_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2752,7 +3038,7 @@ func (x *ListRefsRequest_SortBy) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefsRequest_SortBy.ProtoReflect.Descriptor instead. func (*ListRefsRequest_SortBy) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{38, 0} + return file_ref_proto_rawDescGZIP(), []int{40, 0} } func (x *ListRefsRequest_SortBy) GetKey() ListRefsRequest_SortBy_Key { @@ -2784,7 +3070,7 @@ type ListRefsResponse_Reference struct { func (x *ListRefsResponse_Reference) Reset() { *x = ListRefsResponse_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_ref_proto_msgTypes[46] + mi := &file_ref_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2797,7 +3083,7 @@ func (x *ListRefsResponse_Reference) String() string { func (*ListRefsResponse_Reference) ProtoMessage() {} func (x *ListRefsResponse_Reference) ProtoReflect() protoreflect.Message { - mi := &file_ref_proto_msgTypes[46] + mi := &file_ref_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2810,7 +3096,7 @@ func (x *ListRefsResponse_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefsResponse_Reference.ProtoReflect.Descriptor instead. func (*ListRefsResponse_Reference) Descriptor() ([]byte, []int) { - return file_ref_proto_rawDescGZIP(), []int{39, 0} + return file_ref_proto_rawDescGZIP(), []int{41, 0} } func (x *ListRefsResponse_Reference) GetName() []byte { @@ -2831,445 +3117,468 @@ var File_ref_proto protoreflect.FileDescriptor var file_ref_proto_rawDesc = []byte{ 0x0a, 0x09, 0x72, 0x65, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, - 0x0a, 0x1c, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x33, 0x0a, 0x1d, 0x46, 0x69, 0x6e, 0x64, - 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x55, 0x0a, - 0x19, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x22, 0x32, 0x0a, 0x1a, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, - 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2f, 0x0a, 0x17, - 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x97, 0x02, - 0x0a, 0x18, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, - 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, - 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x22, 0x35, 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x41, - 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x5f, - 0x41, 0x53, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, - 0x5f, 0x44, 0x45, 0x53, 0x43, 0x10, 0x02, 0x22, 0x58, 0x0a, 0x19, 0x46, 0x69, 0x6e, 0x64, 0x4c, - 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, - 0x73, 0x22, 0xb6, 0x02, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x25, - 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, - 0x4e, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x0f, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, - 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x93, 0x01, 0x0a, 0x1b, 0x46, - 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 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, 0x04, - 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x22, 0x9c, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, - 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x67, - 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, - 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x0e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, - 0xa6, 0x01, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x08, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x1a, - 0x47, 0x0a, 0x06, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x65, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, - 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, - 0x30, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, - 0x67, 0x22, 0xf2, 0x02, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, - 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x48, - 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x06, 0x53, 0x6f, 0x72, - 0x74, 0x42, 0x79, 0x12, 0x37, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, - 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, - 0x74, 0x42, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x09, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x23, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x46, 0x4e, - 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, 0x4f, 0x52, - 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x22, 0x36, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, - 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, - 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x5e, - 0x0a, 0x10, 0x52, 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x22, 0x29, - 0x0a, 0x11, 0x52, 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x84, 0x01, 0x0a, 0x13, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, - 0x22, 0xcb, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x4e, - 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, - 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x52, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x01, - 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, - 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, - 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x03, 0x22, 0x63, - 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x0a, 0x11, 0x46, - 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3c, - 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x8f, 0x01, 0x0a, - 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, - 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, - 0x57, 0x69, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, - 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x22, 0x31, - 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x22, 0x95, 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x61, 0x6c, 0x79, 0x1a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, + 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x1c, + 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x52, 0x0a, 0x27, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x92, 0x01, - 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x22, 0x49, 0x0a, 0x24, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, - 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x74, - 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x78, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x33, 0x0a, 0x1d, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x55, 0x0a, 0x19, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x67, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x67, 0x52, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, - 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x1a, 0x5d, 0x0a, 0x0c, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x67, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x22, 0x7b, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x72, 0x79, 0x22, 0x32, 0x0a, 0x1a, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2f, 0x0a, 0x17, 0x46, 0x69, + 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x97, 0x02, 0x0a, 0x18, + 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, + 0x72, 0x74, 0x42, 0x79, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x35, + 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x41, 0x4d, 0x45, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, + 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x44, + 0x45, 0x53, 0x43, 0x10, 0x02, 0x22, 0x8f, 0x01, 0x0a, 0x19, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, + 0x12, 0x35, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, 0xb6, 0x02, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x4e, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, + 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x22, 0x93, 0x01, 0x0a, 0x1b, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x03, 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, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, + 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x0f, + 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, 0xa6, 0x01, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x42, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x1a, 0x47, 0x0a, 0x06, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x65, + 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, + 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x61, + 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, + 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x5d, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x54, + 0x61, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x44, 0x0a, 0x0d, 0x74, 0x61, 0x67, 0x5f, 0x6e, + 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, + 0x52, 0x0b, 0x74, 0x61, 0x67, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x07, 0x0a, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x87, 0x03, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, + 0x62, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, + 0x74, 0x42, 0x79, 0x12, 0x48, 0x0a, 0x11, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x10, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0xb0, 0x01, + 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x37, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x33, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x6f, + 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x38, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x0b, 0x0a, + 0x07, 0x52, 0x45, 0x46, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x4f, 0x52, 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x56, + 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x46, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x02, + 0x22, 0x36, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x54, + 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x5e, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x22, 0x29, 0x0a, 0x11, 0x52, 0x65, 0x66, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x84, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x67, 0x49, 0x64, 0x73, 0x4a, 0x04, - 0x08, 0x02, 0x10, 0x03, 0x52, 0x09, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, - 0x59, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x67, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x52, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x79, 0x0a, 0x1c, 0x46, 0x69, - 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xcb, 0x01, 0x0a, 0x14, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x26, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x4e, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x52, + 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x52, + 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x45, + 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, + 0x5f, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x03, 0x22, 0x63, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, + 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4b, 0x0a, 0x1d, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, - 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x0f, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, + 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x06, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x8f, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, + 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x10, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x57, 0x69, 0x74, 0x68, 0x50, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x22, 0x31, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x67, 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x67, 0x69, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xb0, 0x01, 0x0a, 0x0f, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x46, 0x0a, 0x0e, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x66, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x4c, 0x0a, 0x11, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x48, 0x00, 0x52, 0x10, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x4c, + 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x95, + 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x52, 0x0a, 0x27, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x92, 0x01, 0x0a, 0x23, 0x4c, + 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, + 0x49, 0x0a, 0x24, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x61, 0x67, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x78, 0x0a, 0x17, 0x47, 0x65, + 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4a, - 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x22, - 0x12, 0x0a, 0x10, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xf2, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x67, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x67, 0x52, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x1a, 0x5d, 0x0a, 0x0c, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x15, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x61, 0x67, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0x7b, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x67, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, + 0x03, 0x52, 0x09, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x59, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x15, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x61, 0x67, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x08, 0x74, + 0x61, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x79, 0x0a, 0x1c, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x68, 0x65, 0x61, - 0x64, 0x12, 0x37, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, - 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x1a, 0xbb, 0x01, 0x0a, 0x06, 0x53, - 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x34, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, - 0x42, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x09, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x46, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x46, 0x4e, 0x41, - 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, 0x4f, 0x52, 0x44, - 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x44, - 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, - 0x45, 0x52, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x22, 0x8f, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, - 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x14, 0x46, - 0x69, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x66, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, - 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x2b, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x52, - 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, - 0x72, 0x65, 0x66, 0x73, 0x32, 0xa5, 0x0d, 0x0a, 0x0a, 0x52, 0x65, 0x66, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, - 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x02, 0x12, 0x65, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0x4b, 0x0a, 0x1d, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, + 0x5b, 0x0a, 0x0f, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4a, 0x04, 0x08, 0x02, + 0x10, 0x03, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x22, 0x12, 0x0a, 0x10, + 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xf2, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, + 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x37, + 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, + 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x1a, 0xbb, 0x01, 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, + 0x42, 0x79, 0x12, 0x34, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x2e, + 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x46, 0x0a, + 0x03, 0x4b, 0x65, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x46, 0x4e, 0x41, 0x4d, 0x45, 0x10, + 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, 0x4f, 0x52, 0x44, 0x41, 0x54, 0x45, + 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x44, 0x41, 0x54, 0x45, + 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x52, 0x44, + 0x41, 0x54, 0x45, 0x10, 0x03, 0x22, 0x8f, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x37, + 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, + 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x72, 0x65, 0x66, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x22, 0x2b, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, + 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x66, + 0x73, 0x32, 0xa5, 0x0d, 0x0a, 0x0a, 0x52, 0x65, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x6c, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x65, + 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, + 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, - 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x46, 0x69, - 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x1e, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, - 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, - 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x07, 0x46, 0x69, - 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, - 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x6e, - 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x48, - 0x0a, 0x09, 0x52, 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4b, 0x0a, 0x0a, 0x46, 0x69, 0x6e, 0x64, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x46, 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4b, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x65, 0x66, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x01, 0x12, 0x8c, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, - 0x01, 0x12, 0x83, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x12, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, - 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, - 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, + 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x02, 0x30, 0x01, 0x12, 0x48, 0x0a, 0x08, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x12, - 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x09, 0x88, 0x02, 0x01, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x47, 0x0a, - 0x08, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, - 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, - 0x69, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, - 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x02, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, + 0x54, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, + 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x54, + 0x61, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x6e, 0x0a, 0x15, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, + 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x48, 0x0a, 0x09, 0x52, + 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x4b, 0x0a, 0x0a, 0x46, 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x02, 0x12, 0x4b, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, + 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x66, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, + 0x8c, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x12, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x83, + 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, + 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x02, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, + 0x12, 0x48, 0x0a, 0x08, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x12, 0x17, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x50, + 0x61, 0x63, 0x6b, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x09, 0x88, 0x02, 0x01, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x47, 0x0a, 0x08, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, + 0x02, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x42, + 0x79, 0x4f, 0x49, 0x44, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, + 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x52, 0x65, 0x66, 0x73, 0x42, 0x79, 0x4f, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, + 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, + 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3285,7 +3594,7 @@ func file_ref_proto_rawDescGZIP() []byte { } var file_ref_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_ref_proto_msgTypes = make([]protoimpl.MessageInfo, 47) +var file_ref_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_ref_proto_goTypes = []interface{}{ (FindLocalBranchesRequest_SortBy)(0), // 0: gitaly.FindLocalBranchesRequest.SortBy (FindAllTagsRequest_SortBy_Key)(0), // 1: gitaly.FindAllTagsRequest.SortBy.Key @@ -3305,133 +3614,142 @@ var file_ref_proto_goTypes = []interface{}{ (*FindAllBranchesResponse)(nil), // 15: gitaly.FindAllBranchesResponse (*FindTagRequest)(nil), // 16: gitaly.FindTagRequest (*FindTagResponse)(nil), // 17: gitaly.FindTagResponse - (*FindAllTagsRequest)(nil), // 18: gitaly.FindAllTagsRequest - (*FindAllTagsResponse)(nil), // 19: gitaly.FindAllTagsResponse - (*RefExistsRequest)(nil), // 20: gitaly.RefExistsRequest - (*RefExistsResponse)(nil), // 21: gitaly.RefExistsResponse - (*CreateBranchRequest)(nil), // 22: gitaly.CreateBranchRequest - (*CreateBranchResponse)(nil), // 23: gitaly.CreateBranchResponse - (*DeleteBranchRequest)(nil), // 24: gitaly.DeleteBranchRequest - (*DeleteBranchResponse)(nil), // 25: gitaly.DeleteBranchResponse - (*FindBranchRequest)(nil), // 26: gitaly.FindBranchRequest - (*FindBranchResponse)(nil), // 27: gitaly.FindBranchResponse - (*DeleteRefsRequest)(nil), // 28: gitaly.DeleteRefsRequest - (*DeleteRefsResponse)(nil), // 29: gitaly.DeleteRefsResponse - (*ListBranchNamesContainingCommitRequest)(nil), // 30: gitaly.ListBranchNamesContainingCommitRequest - (*ListBranchNamesContainingCommitResponse)(nil), // 31: gitaly.ListBranchNamesContainingCommitResponse - (*ListTagNamesContainingCommitRequest)(nil), // 32: gitaly.ListTagNamesContainingCommitRequest - (*ListTagNamesContainingCommitResponse)(nil), // 33: gitaly.ListTagNamesContainingCommitResponse - (*GetTagSignaturesRequest)(nil), // 34: gitaly.GetTagSignaturesRequest - (*GetTagSignaturesResponse)(nil), // 35: gitaly.GetTagSignaturesResponse - (*GetTagMessagesRequest)(nil), // 36: gitaly.GetTagMessagesRequest - (*GetTagMessagesResponse)(nil), // 37: gitaly.GetTagMessagesResponse - (*FindAllRemoteBranchesRequest)(nil), // 38: gitaly.FindAllRemoteBranchesRequest - (*FindAllRemoteBranchesResponse)(nil), // 39: gitaly.FindAllRemoteBranchesResponse - (*PackRefsRequest)(nil), // 40: gitaly.PackRefsRequest - (*PackRefsResponse)(nil), // 41: gitaly.PackRefsResponse - (*ListRefsRequest)(nil), // 42: gitaly.ListRefsRequest - (*ListRefsResponse)(nil), // 43: gitaly.ListRefsResponse - (*FindRefsByOIDRequest)(nil), // 44: gitaly.FindRefsByOIDRequest - (*FindRefsByOIDResponse)(nil), // 45: gitaly.FindRefsByOIDResponse - (*FindAllBranchesResponse_Branch)(nil), // 46: gitaly.FindAllBranchesResponse.Branch - (*FindAllTagsRequest_SortBy)(nil), // 47: gitaly.FindAllTagsRequest.SortBy - (*GetTagSignaturesResponse_TagSignature)(nil), // 48: gitaly.GetTagSignaturesResponse.TagSignature - (*ListRefsRequest_SortBy)(nil), // 49: gitaly.ListRefsRequest.SortBy - (*ListRefsResponse_Reference)(nil), // 50: gitaly.ListRefsResponse.Reference - (*Repository)(nil), // 51: gitaly.Repository - (*PaginationParameter)(nil), // 52: gitaly.PaginationParameter - (*GitCommit)(nil), // 53: gitaly.GitCommit - (*timestamppb.Timestamp)(nil), // 54: google.protobuf.Timestamp - (*Tag)(nil), // 55: gitaly.Tag - (*Branch)(nil), // 56: gitaly.Branch - (SortDirection)(0), // 57: gitaly.SortDirection + (*FindTagError)(nil), // 18: gitaly.FindTagError + (*FindAllTagsRequest)(nil), // 19: gitaly.FindAllTagsRequest + (*FindAllTagsResponse)(nil), // 20: gitaly.FindAllTagsResponse + (*RefExistsRequest)(nil), // 21: gitaly.RefExistsRequest + (*RefExistsResponse)(nil), // 22: gitaly.RefExistsResponse + (*CreateBranchRequest)(nil), // 23: gitaly.CreateBranchRequest + (*CreateBranchResponse)(nil), // 24: gitaly.CreateBranchResponse + (*DeleteBranchRequest)(nil), // 25: gitaly.DeleteBranchRequest + (*DeleteBranchResponse)(nil), // 26: gitaly.DeleteBranchResponse + (*FindBranchRequest)(nil), // 27: gitaly.FindBranchRequest + (*FindBranchResponse)(nil), // 28: gitaly.FindBranchResponse + (*DeleteRefsRequest)(nil), // 29: gitaly.DeleteRefsRequest + (*DeleteRefsResponse)(nil), // 30: gitaly.DeleteRefsResponse + (*DeleteRefsError)(nil), // 31: gitaly.DeleteRefsError + (*ListBranchNamesContainingCommitRequest)(nil), // 32: gitaly.ListBranchNamesContainingCommitRequest + (*ListBranchNamesContainingCommitResponse)(nil), // 33: gitaly.ListBranchNamesContainingCommitResponse + (*ListTagNamesContainingCommitRequest)(nil), // 34: gitaly.ListTagNamesContainingCommitRequest + (*ListTagNamesContainingCommitResponse)(nil), // 35: gitaly.ListTagNamesContainingCommitResponse + (*GetTagSignaturesRequest)(nil), // 36: gitaly.GetTagSignaturesRequest + (*GetTagSignaturesResponse)(nil), // 37: gitaly.GetTagSignaturesResponse + (*GetTagMessagesRequest)(nil), // 38: gitaly.GetTagMessagesRequest + (*GetTagMessagesResponse)(nil), // 39: gitaly.GetTagMessagesResponse + (*FindAllRemoteBranchesRequest)(nil), // 40: gitaly.FindAllRemoteBranchesRequest + (*FindAllRemoteBranchesResponse)(nil), // 41: gitaly.FindAllRemoteBranchesResponse + (*PackRefsRequest)(nil), // 42: gitaly.PackRefsRequest + (*PackRefsResponse)(nil), // 43: gitaly.PackRefsResponse + (*ListRefsRequest)(nil), // 44: gitaly.ListRefsRequest + (*ListRefsResponse)(nil), // 45: gitaly.ListRefsResponse + (*FindRefsByOIDRequest)(nil), // 46: gitaly.FindRefsByOIDRequest + (*FindRefsByOIDResponse)(nil), // 47: gitaly.FindRefsByOIDResponse + (*FindAllBranchesResponse_Branch)(nil), // 48: gitaly.FindAllBranchesResponse.Branch + (*FindAllTagsRequest_SortBy)(nil), // 49: gitaly.FindAllTagsRequest.SortBy + (*GetTagSignaturesResponse_TagSignature)(nil), // 50: gitaly.GetTagSignaturesResponse.TagSignature + (*ListRefsRequest_SortBy)(nil), // 51: gitaly.ListRefsRequest.SortBy + (*ListRefsResponse_Reference)(nil), // 52: gitaly.ListRefsResponse.Reference + (*Repository)(nil), // 53: gitaly.Repository + (*PaginationParameter)(nil), // 54: gitaly.PaginationParameter + (*Branch)(nil), // 55: gitaly.Branch + (*GitCommit)(nil), // 56: gitaly.GitCommit + (*timestamppb.Timestamp)(nil), // 57: google.protobuf.Timestamp + (*Tag)(nil), // 58: gitaly.Tag + (*ReferenceNotFoundError)(nil), // 59: gitaly.ReferenceNotFoundError + (*InvalidRefFormatError)(nil), // 60: gitaly.InvalidRefFormatError + (*ReferencesLockedError)(nil), // 61: gitaly.ReferencesLockedError + (SortDirection)(0), // 62: gitaly.SortDirection } var file_ref_proto_depIdxs = []int32{ - 51, // 0: gitaly.FindDefaultBranchNameRequest.repository:type_name -> gitaly.Repository - 51, // 1: gitaly.FindAllBranchNamesRequest.repository:type_name -> gitaly.Repository - 51, // 2: gitaly.FindAllTagNamesRequest.repository:type_name -> gitaly.Repository - 51, // 3: gitaly.FindLocalBranchesRequest.repository:type_name -> gitaly.Repository + 53, // 0: gitaly.FindDefaultBranchNameRequest.repository:type_name -> gitaly.Repository + 53, // 1: gitaly.FindAllBranchNamesRequest.repository:type_name -> gitaly.Repository + 53, // 2: gitaly.FindAllTagNamesRequest.repository:type_name -> gitaly.Repository + 53, // 3: gitaly.FindLocalBranchesRequest.repository:type_name -> gitaly.Repository 0, // 4: gitaly.FindLocalBranchesRequest.sort_by:type_name -> gitaly.FindLocalBranchesRequest.SortBy - 52, // 5: gitaly.FindLocalBranchesRequest.pagination_params:type_name -> gitaly.PaginationParameter + 54, // 5: gitaly.FindLocalBranchesRequest.pagination_params:type_name -> gitaly.PaginationParameter 12, // 6: gitaly.FindLocalBranchesResponse.branches:type_name -> gitaly.FindLocalBranchResponse - 13, // 7: gitaly.FindLocalBranchResponse.commit_author:type_name -> gitaly.FindLocalBranchCommitAuthor - 13, // 8: gitaly.FindLocalBranchResponse.commit_committer:type_name -> gitaly.FindLocalBranchCommitAuthor - 53, // 9: gitaly.FindLocalBranchResponse.commit:type_name -> gitaly.GitCommit - 54, // 10: gitaly.FindLocalBranchCommitAuthor.date:type_name -> google.protobuf.Timestamp - 51, // 11: gitaly.FindAllBranchesRequest.repository:type_name -> gitaly.Repository - 46, // 12: gitaly.FindAllBranchesResponse.branches:type_name -> gitaly.FindAllBranchesResponse.Branch - 51, // 13: gitaly.FindTagRequest.repository:type_name -> gitaly.Repository - 55, // 14: gitaly.FindTagResponse.tag:type_name -> gitaly.Tag - 51, // 15: gitaly.FindAllTagsRequest.repository:type_name -> gitaly.Repository - 47, // 16: gitaly.FindAllTagsRequest.sort_by:type_name -> gitaly.FindAllTagsRequest.SortBy - 52, // 17: gitaly.FindAllTagsRequest.pagination_params:type_name -> gitaly.PaginationParameter - 55, // 18: gitaly.FindAllTagsResponse.tags:type_name -> gitaly.Tag - 51, // 19: gitaly.RefExistsRequest.repository:type_name -> gitaly.Repository - 51, // 20: gitaly.CreateBranchRequest.repository:type_name -> gitaly.Repository - 2, // 21: gitaly.CreateBranchResponse.status:type_name -> gitaly.CreateBranchResponse.Status - 56, // 22: gitaly.CreateBranchResponse.branch:type_name -> gitaly.Branch - 51, // 23: gitaly.DeleteBranchRequest.repository:type_name -> gitaly.Repository - 51, // 24: gitaly.FindBranchRequest.repository:type_name -> gitaly.Repository - 56, // 25: gitaly.FindBranchResponse.branch:type_name -> gitaly.Branch - 51, // 26: gitaly.DeleteRefsRequest.repository:type_name -> gitaly.Repository - 51, // 27: gitaly.ListBranchNamesContainingCommitRequest.repository:type_name -> gitaly.Repository - 51, // 28: gitaly.ListTagNamesContainingCommitRequest.repository:type_name -> gitaly.Repository - 51, // 29: gitaly.GetTagSignaturesRequest.repository:type_name -> gitaly.Repository - 48, // 30: gitaly.GetTagSignaturesResponse.signatures:type_name -> gitaly.GetTagSignaturesResponse.TagSignature - 51, // 31: gitaly.GetTagMessagesRequest.repository:type_name -> gitaly.Repository - 51, // 32: gitaly.FindAllRemoteBranchesRequest.repository:type_name -> gitaly.Repository - 56, // 33: gitaly.FindAllRemoteBranchesResponse.branches:type_name -> gitaly.Branch - 51, // 34: gitaly.PackRefsRequest.repository:type_name -> gitaly.Repository - 51, // 35: gitaly.ListRefsRequest.repository:type_name -> gitaly.Repository - 49, // 36: gitaly.ListRefsRequest.sort_by:type_name -> gitaly.ListRefsRequest.SortBy - 50, // 37: gitaly.ListRefsResponse.references:type_name -> gitaly.ListRefsResponse.Reference - 51, // 38: gitaly.FindRefsByOIDRequest.repository:type_name -> gitaly.Repository - 53, // 39: gitaly.FindAllBranchesResponse.Branch.target:type_name -> gitaly.GitCommit - 1, // 40: gitaly.FindAllTagsRequest.SortBy.key:type_name -> gitaly.FindAllTagsRequest.SortBy.Key - 57, // 41: gitaly.FindAllTagsRequest.SortBy.direction:type_name -> gitaly.SortDirection - 3, // 42: gitaly.ListRefsRequest.SortBy.key:type_name -> gitaly.ListRefsRequest.SortBy.Key - 57, // 43: gitaly.ListRefsRequest.SortBy.direction:type_name -> gitaly.SortDirection - 4, // 44: gitaly.RefService.FindDefaultBranchName:input_type -> gitaly.FindDefaultBranchNameRequest - 6, // 45: gitaly.RefService.FindAllBranchNames:input_type -> gitaly.FindAllBranchNamesRequest - 8, // 46: gitaly.RefService.FindAllTagNames:input_type -> gitaly.FindAllTagNamesRequest - 10, // 47: gitaly.RefService.FindLocalBranches:input_type -> gitaly.FindLocalBranchesRequest - 14, // 48: gitaly.RefService.FindAllBranches:input_type -> gitaly.FindAllBranchesRequest - 18, // 49: gitaly.RefService.FindAllTags:input_type -> gitaly.FindAllTagsRequest - 16, // 50: gitaly.RefService.FindTag:input_type -> gitaly.FindTagRequest - 38, // 51: gitaly.RefService.FindAllRemoteBranches:input_type -> gitaly.FindAllRemoteBranchesRequest - 20, // 52: gitaly.RefService.RefExists:input_type -> gitaly.RefExistsRequest - 26, // 53: gitaly.RefService.FindBranch:input_type -> gitaly.FindBranchRequest - 28, // 54: gitaly.RefService.DeleteRefs:input_type -> gitaly.DeleteRefsRequest - 30, // 55: gitaly.RefService.ListBranchNamesContainingCommit:input_type -> gitaly.ListBranchNamesContainingCommitRequest - 32, // 56: gitaly.RefService.ListTagNamesContainingCommit:input_type -> gitaly.ListTagNamesContainingCommitRequest - 34, // 57: gitaly.RefService.GetTagSignatures:input_type -> gitaly.GetTagSignaturesRequest - 36, // 58: gitaly.RefService.GetTagMessages:input_type -> gitaly.GetTagMessagesRequest - 40, // 59: gitaly.RefService.PackRefs:input_type -> gitaly.PackRefsRequest - 42, // 60: gitaly.RefService.ListRefs:input_type -> gitaly.ListRefsRequest - 44, // 61: gitaly.RefService.FindRefsByOID:input_type -> gitaly.FindRefsByOIDRequest - 5, // 62: gitaly.RefService.FindDefaultBranchName:output_type -> gitaly.FindDefaultBranchNameResponse - 7, // 63: gitaly.RefService.FindAllBranchNames:output_type -> gitaly.FindAllBranchNamesResponse - 9, // 64: gitaly.RefService.FindAllTagNames:output_type -> gitaly.FindAllTagNamesResponse - 11, // 65: gitaly.RefService.FindLocalBranches:output_type -> gitaly.FindLocalBranchesResponse - 15, // 66: gitaly.RefService.FindAllBranches:output_type -> gitaly.FindAllBranchesResponse - 19, // 67: gitaly.RefService.FindAllTags:output_type -> gitaly.FindAllTagsResponse - 17, // 68: gitaly.RefService.FindTag:output_type -> gitaly.FindTagResponse - 39, // 69: gitaly.RefService.FindAllRemoteBranches:output_type -> gitaly.FindAllRemoteBranchesResponse - 21, // 70: gitaly.RefService.RefExists:output_type -> gitaly.RefExistsResponse - 27, // 71: gitaly.RefService.FindBranch:output_type -> gitaly.FindBranchResponse - 29, // 72: gitaly.RefService.DeleteRefs:output_type -> gitaly.DeleteRefsResponse - 31, // 73: gitaly.RefService.ListBranchNamesContainingCommit:output_type -> gitaly.ListBranchNamesContainingCommitResponse - 33, // 74: gitaly.RefService.ListTagNamesContainingCommit:output_type -> gitaly.ListTagNamesContainingCommitResponse - 35, // 75: gitaly.RefService.GetTagSignatures:output_type -> gitaly.GetTagSignaturesResponse - 37, // 76: gitaly.RefService.GetTagMessages:output_type -> gitaly.GetTagMessagesResponse - 41, // 77: gitaly.RefService.PackRefs:output_type -> gitaly.PackRefsResponse - 43, // 78: gitaly.RefService.ListRefs:output_type -> gitaly.ListRefsResponse - 45, // 79: gitaly.RefService.FindRefsByOID:output_type -> gitaly.FindRefsByOIDResponse - 62, // [62:80] is the sub-list for method output_type - 44, // [44:62] is the sub-list for method input_type - 44, // [44:44] is the sub-list for extension type_name - 44, // [44:44] is the sub-list for extension extendee - 0, // [0:44] is the sub-list for field type_name + 55, // 7: gitaly.FindLocalBranchesResponse.local_branches:type_name -> gitaly.Branch + 13, // 8: gitaly.FindLocalBranchResponse.commit_author:type_name -> gitaly.FindLocalBranchCommitAuthor + 13, // 9: gitaly.FindLocalBranchResponse.commit_committer:type_name -> gitaly.FindLocalBranchCommitAuthor + 56, // 10: gitaly.FindLocalBranchResponse.commit:type_name -> gitaly.GitCommit + 57, // 11: gitaly.FindLocalBranchCommitAuthor.date:type_name -> google.protobuf.Timestamp + 53, // 12: gitaly.FindAllBranchesRequest.repository:type_name -> gitaly.Repository + 48, // 13: gitaly.FindAllBranchesResponse.branches:type_name -> gitaly.FindAllBranchesResponse.Branch + 53, // 14: gitaly.FindTagRequest.repository:type_name -> gitaly.Repository + 58, // 15: gitaly.FindTagResponse.tag:type_name -> gitaly.Tag + 59, // 16: gitaly.FindTagError.tag_not_found:type_name -> gitaly.ReferenceNotFoundError + 53, // 17: gitaly.FindAllTagsRequest.repository:type_name -> gitaly.Repository + 49, // 18: gitaly.FindAllTagsRequest.sort_by:type_name -> gitaly.FindAllTagsRequest.SortBy + 54, // 19: gitaly.FindAllTagsRequest.pagination_params:type_name -> gitaly.PaginationParameter + 58, // 20: gitaly.FindAllTagsResponse.tags:type_name -> gitaly.Tag + 53, // 21: gitaly.RefExistsRequest.repository:type_name -> gitaly.Repository + 53, // 22: gitaly.CreateBranchRequest.repository:type_name -> gitaly.Repository + 2, // 23: gitaly.CreateBranchResponse.status:type_name -> gitaly.CreateBranchResponse.Status + 55, // 24: gitaly.CreateBranchResponse.branch:type_name -> gitaly.Branch + 53, // 25: gitaly.DeleteBranchRequest.repository:type_name -> gitaly.Repository + 53, // 26: gitaly.FindBranchRequest.repository:type_name -> gitaly.Repository + 55, // 27: gitaly.FindBranchResponse.branch:type_name -> gitaly.Branch + 53, // 28: gitaly.DeleteRefsRequest.repository:type_name -> gitaly.Repository + 60, // 29: gitaly.DeleteRefsError.invalid_format:type_name -> gitaly.InvalidRefFormatError + 61, // 30: gitaly.DeleteRefsError.references_locked:type_name -> gitaly.ReferencesLockedError + 53, // 31: gitaly.ListBranchNamesContainingCommitRequest.repository:type_name -> gitaly.Repository + 53, // 32: gitaly.ListTagNamesContainingCommitRequest.repository:type_name -> gitaly.Repository + 53, // 33: gitaly.GetTagSignaturesRequest.repository:type_name -> gitaly.Repository + 50, // 34: gitaly.GetTagSignaturesResponse.signatures:type_name -> gitaly.GetTagSignaturesResponse.TagSignature + 53, // 35: gitaly.GetTagMessagesRequest.repository:type_name -> gitaly.Repository + 53, // 36: gitaly.FindAllRemoteBranchesRequest.repository:type_name -> gitaly.Repository + 55, // 37: gitaly.FindAllRemoteBranchesResponse.branches:type_name -> gitaly.Branch + 53, // 38: gitaly.PackRefsRequest.repository:type_name -> gitaly.Repository + 53, // 39: gitaly.ListRefsRequest.repository:type_name -> gitaly.Repository + 51, // 40: gitaly.ListRefsRequest.sort_by:type_name -> gitaly.ListRefsRequest.SortBy + 52, // 41: gitaly.ListRefsResponse.references:type_name -> gitaly.ListRefsResponse.Reference + 53, // 42: gitaly.FindRefsByOIDRequest.repository:type_name -> gitaly.Repository + 56, // 43: gitaly.FindAllBranchesResponse.Branch.target:type_name -> gitaly.GitCommit + 1, // 44: gitaly.FindAllTagsRequest.SortBy.key:type_name -> gitaly.FindAllTagsRequest.SortBy.Key + 62, // 45: gitaly.FindAllTagsRequest.SortBy.direction:type_name -> gitaly.SortDirection + 3, // 46: gitaly.ListRefsRequest.SortBy.key:type_name -> gitaly.ListRefsRequest.SortBy.Key + 62, // 47: gitaly.ListRefsRequest.SortBy.direction:type_name -> gitaly.SortDirection + 4, // 48: gitaly.RefService.FindDefaultBranchName:input_type -> gitaly.FindDefaultBranchNameRequest + 6, // 49: gitaly.RefService.FindAllBranchNames:input_type -> gitaly.FindAllBranchNamesRequest + 8, // 50: gitaly.RefService.FindAllTagNames:input_type -> gitaly.FindAllTagNamesRequest + 10, // 51: gitaly.RefService.FindLocalBranches:input_type -> gitaly.FindLocalBranchesRequest + 14, // 52: gitaly.RefService.FindAllBranches:input_type -> gitaly.FindAllBranchesRequest + 19, // 53: gitaly.RefService.FindAllTags:input_type -> gitaly.FindAllTagsRequest + 16, // 54: gitaly.RefService.FindTag:input_type -> gitaly.FindTagRequest + 40, // 55: gitaly.RefService.FindAllRemoteBranches:input_type -> gitaly.FindAllRemoteBranchesRequest + 21, // 56: gitaly.RefService.RefExists:input_type -> gitaly.RefExistsRequest + 27, // 57: gitaly.RefService.FindBranch:input_type -> gitaly.FindBranchRequest + 29, // 58: gitaly.RefService.DeleteRefs:input_type -> gitaly.DeleteRefsRequest + 32, // 59: gitaly.RefService.ListBranchNamesContainingCommit:input_type -> gitaly.ListBranchNamesContainingCommitRequest + 34, // 60: gitaly.RefService.ListTagNamesContainingCommit:input_type -> gitaly.ListTagNamesContainingCommitRequest + 36, // 61: gitaly.RefService.GetTagSignatures:input_type -> gitaly.GetTagSignaturesRequest + 38, // 62: gitaly.RefService.GetTagMessages:input_type -> gitaly.GetTagMessagesRequest + 42, // 63: gitaly.RefService.PackRefs:input_type -> gitaly.PackRefsRequest + 44, // 64: gitaly.RefService.ListRefs:input_type -> gitaly.ListRefsRequest + 46, // 65: gitaly.RefService.FindRefsByOID:input_type -> gitaly.FindRefsByOIDRequest + 5, // 66: gitaly.RefService.FindDefaultBranchName:output_type -> gitaly.FindDefaultBranchNameResponse + 7, // 67: gitaly.RefService.FindAllBranchNames:output_type -> gitaly.FindAllBranchNamesResponse + 9, // 68: gitaly.RefService.FindAllTagNames:output_type -> gitaly.FindAllTagNamesResponse + 11, // 69: gitaly.RefService.FindLocalBranches:output_type -> gitaly.FindLocalBranchesResponse + 15, // 70: gitaly.RefService.FindAllBranches:output_type -> gitaly.FindAllBranchesResponse + 20, // 71: gitaly.RefService.FindAllTags:output_type -> gitaly.FindAllTagsResponse + 17, // 72: gitaly.RefService.FindTag:output_type -> gitaly.FindTagResponse + 41, // 73: gitaly.RefService.FindAllRemoteBranches:output_type -> gitaly.FindAllRemoteBranchesResponse + 22, // 74: gitaly.RefService.RefExists:output_type -> gitaly.RefExistsResponse + 28, // 75: gitaly.RefService.FindBranch:output_type -> gitaly.FindBranchResponse + 30, // 76: gitaly.RefService.DeleteRefs:output_type -> gitaly.DeleteRefsResponse + 33, // 77: gitaly.RefService.ListBranchNamesContainingCommit:output_type -> gitaly.ListBranchNamesContainingCommitResponse + 35, // 78: gitaly.RefService.ListTagNamesContainingCommit:output_type -> gitaly.ListTagNamesContainingCommitResponse + 37, // 79: gitaly.RefService.GetTagSignatures:output_type -> gitaly.GetTagSignaturesResponse + 39, // 80: gitaly.RefService.GetTagMessages:output_type -> gitaly.GetTagMessagesResponse + 43, // 81: gitaly.RefService.PackRefs:output_type -> gitaly.PackRefsResponse + 45, // 82: gitaly.RefService.ListRefs:output_type -> gitaly.ListRefsResponse + 47, // 83: gitaly.RefService.FindRefsByOID:output_type -> gitaly.FindRefsByOIDResponse + 66, // [66:84] is the sub-list for method output_type + 48, // [48:66] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { file_ref_proto_init() } @@ -3439,6 +3757,7 @@ func file_ref_proto_init() { if File_ref_proto != nil { return } + file_errors_proto_init() file_lint_proto_init() file_shared_proto_init() if !protoimpl.UnsafeEnabled { @@ -3611,7 +3930,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllTagsRequest); i { + switch v := v.(*FindTagError); i { case 0: return &v.state case 1: @@ -3623,7 +3942,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllTagsResponse); i { + switch v := v.(*FindAllTagsRequest); i { case 0: return &v.state case 1: @@ -3635,7 +3954,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefExistsRequest); i { + switch v := v.(*FindAllTagsResponse); i { case 0: return &v.state case 1: @@ -3647,7 +3966,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefExistsResponse); i { + switch v := v.(*RefExistsRequest); i { case 0: return &v.state case 1: @@ -3659,7 +3978,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateBranchRequest); i { + switch v := v.(*RefExistsResponse); i { case 0: return &v.state case 1: @@ -3671,7 +3990,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateBranchResponse); i { + switch v := v.(*CreateBranchRequest); i { case 0: return &v.state case 1: @@ -3683,7 +4002,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteBranchRequest); i { + switch v := v.(*CreateBranchResponse); i { case 0: return &v.state case 1: @@ -3695,7 +4014,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteBranchResponse); i { + switch v := v.(*DeleteBranchRequest); i { case 0: return &v.state case 1: @@ -3707,7 +4026,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindBranchRequest); i { + switch v := v.(*DeleteBranchResponse); i { case 0: return &v.state case 1: @@ -3719,7 +4038,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindBranchResponse); i { + switch v := v.(*FindBranchRequest); i { case 0: return &v.state case 1: @@ -3731,7 +4050,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRefsRequest); i { + switch v := v.(*FindBranchResponse); i { case 0: return &v.state case 1: @@ -3743,7 +4062,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteRefsResponse); i { + switch v := v.(*DeleteRefsRequest); i { case 0: return &v.state case 1: @@ -3755,7 +4074,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListBranchNamesContainingCommitRequest); i { + switch v := v.(*DeleteRefsResponse); i { case 0: return &v.state case 1: @@ -3767,7 +4086,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListBranchNamesContainingCommitResponse); i { + switch v := v.(*DeleteRefsError); i { case 0: return &v.state case 1: @@ -3779,7 +4098,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTagNamesContainingCommitRequest); i { + switch v := v.(*ListBranchNamesContainingCommitRequest); i { case 0: return &v.state case 1: @@ -3791,7 +4110,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTagNamesContainingCommitResponse); i { + switch v := v.(*ListBranchNamesContainingCommitResponse); i { case 0: return &v.state case 1: @@ -3803,7 +4122,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTagSignaturesRequest); i { + switch v := v.(*ListTagNamesContainingCommitRequest); i { case 0: return &v.state case 1: @@ -3815,7 +4134,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTagSignaturesResponse); i { + switch v := v.(*ListTagNamesContainingCommitResponse); i { case 0: return &v.state case 1: @@ -3827,7 +4146,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTagMessagesRequest); i { + switch v := v.(*GetTagSignaturesRequest); i { case 0: return &v.state case 1: @@ -3839,7 +4158,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTagMessagesResponse); i { + switch v := v.(*GetTagSignaturesResponse); i { case 0: return &v.state case 1: @@ -3851,7 +4170,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllRemoteBranchesRequest); i { + switch v := v.(*GetTagMessagesRequest); i { case 0: return &v.state case 1: @@ -3863,7 +4182,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllRemoteBranchesResponse); i { + switch v := v.(*GetTagMessagesResponse); i { case 0: return &v.state case 1: @@ -3875,7 +4194,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackRefsRequest); i { + switch v := v.(*FindAllRemoteBranchesRequest); i { case 0: return &v.state case 1: @@ -3887,7 +4206,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackRefsResponse); i { + switch v := v.(*FindAllRemoteBranchesResponse); i { case 0: return &v.state case 1: @@ -3899,7 +4218,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefsRequest); i { + switch v := v.(*PackRefsRequest); i { case 0: return &v.state case 1: @@ -3911,7 +4230,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefsResponse); i { + switch v := v.(*PackRefsResponse); i { case 0: return &v.state case 1: @@ -3923,7 +4242,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindRefsByOIDRequest); i { + switch v := v.(*ListRefsRequest); i { case 0: return &v.state case 1: @@ -3935,7 +4254,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindRefsByOIDResponse); i { + switch v := v.(*ListRefsResponse); i { case 0: return &v.state case 1: @@ -3947,7 +4266,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllBranchesResponse_Branch); i { + switch v := v.(*FindRefsByOIDRequest); i { case 0: return &v.state case 1: @@ -3959,7 +4278,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FindAllTagsRequest_SortBy); i { + switch v := v.(*FindRefsByOIDResponse); i { case 0: return &v.state case 1: @@ -3971,7 +4290,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTagSignaturesResponse_TagSignature); i { + switch v := v.(*FindAllBranchesResponse_Branch); i { case 0: return &v.state case 1: @@ -3983,7 +4302,7 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefsRequest_SortBy); i { + switch v := v.(*FindAllTagsRequest_SortBy); i { case 0: return &v.state case 1: @@ -3995,6 +4314,30 @@ func file_ref_proto_init() { } } file_ref_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTagSignaturesResponse_TagSignature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ref_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRefsRequest_SortBy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ref_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListRefsResponse_Reference); i { case 0: return &v.state @@ -4007,13 +4350,20 @@ func file_ref_proto_init() { } } } + file_ref_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*FindTagError_TagNotFound)(nil), + } + file_ref_proto_msgTypes[27].OneofWrappers = []interface{}{ + (*DeleteRefsError_InvalidFormat)(nil), + (*DeleteRefsError_ReferencesLocked)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ref_proto_rawDesc, NumEnums: 4, - NumMessages: 47, + NumMessages: 49, NumExtensions: 0, NumServices: 1, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref_grpc.pb.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref_grpc.pb.go index 8250020305..d84760be14 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ref_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ref_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: ref.proto package gitalypb @@ -18,28 +22,41 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RefServiceClient interface { + // This comment is left unintentionally blank. FindDefaultBranchName(ctx context.Context, in *FindDefaultBranchNameRequest, opts ...grpc.CallOption) (*FindDefaultBranchNameResponse, error) + // This comment is left unintentionally blank. FindAllBranchNames(ctx context.Context, in *FindAllBranchNamesRequest, opts ...grpc.CallOption) (RefService_FindAllBranchNamesClient, error) + // This comment is left unintentionally blank. FindAllTagNames(ctx context.Context, in *FindAllTagNamesRequest, opts ...grpc.CallOption) (RefService_FindAllTagNamesClient, error) // Return a stream so we can divide the response in chunks of branches FindLocalBranches(ctx context.Context, in *FindLocalBranchesRequest, opts ...grpc.CallOption) (RefService_FindLocalBranchesClient, error) + // This comment is left unintentionally blank. FindAllBranches(ctx context.Context, in *FindAllBranchesRequest, opts ...grpc.CallOption) (RefService_FindAllBranchesClient, error) // Returns a stream of tags repository has. FindAllTags(ctx context.Context, in *FindAllTagsRequest, opts ...grpc.CallOption) (RefService_FindAllTagsClient, error) + // FindTag looks up a tag by its name and returns it to the caller if it exists. This RPC supports + // both lightweight and annotated tags. Note: this RPC returns an `Internal` error if the tag was + // not found. FindTag(ctx context.Context, in *FindTagRequest, opts ...grpc.CallOption) (*FindTagResponse, error) + // This comment is left unintentionally blank. FindAllRemoteBranches(ctx context.Context, in *FindAllRemoteBranchesRequest, opts ...grpc.CallOption) (RefService_FindAllRemoteBranchesClient, error) + // This comment is left unintentionally blank. RefExists(ctx context.Context, in *RefExistsRequest, opts ...grpc.CallOption) (*RefExistsResponse, error) // FindBranch finds a branch by its unqualified name (like "master") and // returns the commit it currently points to. FindBranch(ctx context.Context, in *FindBranchRequest, opts ...grpc.CallOption) (*FindBranchResponse, error) + // This comment is left unintentionally blank. DeleteRefs(ctx context.Context, in *DeleteRefsRequest, opts ...grpc.CallOption) (*DeleteRefsResponse, error) + // This comment is left unintentionally blank. ListBranchNamesContainingCommit(ctx context.Context, in *ListBranchNamesContainingCommitRequest, opts ...grpc.CallOption) (RefService_ListBranchNamesContainingCommitClient, error) + // This comment is left unintentionally blank. ListTagNamesContainingCommit(ctx context.Context, in *ListTagNamesContainingCommitRequest, opts ...grpc.CallOption) (RefService_ListTagNamesContainingCommitClient, error) // GetTagSignatures returns signatures for annotated tags resolved from a set of revisions. Revisions // which don't resolve to an annotated tag are silently discarded. Revisions which cannot be resolved // result in an error. Tags which are annotated but not signed will return a TagSignature response // which has no signature, but its unsigned contents will still be returned. GetTagSignatures(ctx context.Context, in *GetTagSignaturesRequest, opts ...grpc.CallOption) (RefService_GetTagSignaturesClient, error) + // This comment is left unintentionally blank. GetTagMessages(ctx context.Context, in *GetTagMessagesRequest, opts ...grpc.CallOption) (RefService_GetTagMessagesClient, error) // Deprecated: Do not use. // PackRefs is deprecated in favor of OptimizeRepository. @@ -482,28 +499,41 @@ func (c *refServiceClient) FindRefsByOID(ctx context.Context, in *FindRefsByOIDR // All implementations must embed UnimplementedRefServiceServer // for forward compatibility type RefServiceServer interface { + // This comment is left unintentionally blank. FindDefaultBranchName(context.Context, *FindDefaultBranchNameRequest) (*FindDefaultBranchNameResponse, error) + // This comment is left unintentionally blank. FindAllBranchNames(*FindAllBranchNamesRequest, RefService_FindAllBranchNamesServer) error + // This comment is left unintentionally blank. FindAllTagNames(*FindAllTagNamesRequest, RefService_FindAllTagNamesServer) error // Return a stream so we can divide the response in chunks of branches FindLocalBranches(*FindLocalBranchesRequest, RefService_FindLocalBranchesServer) error + // This comment is left unintentionally blank. FindAllBranches(*FindAllBranchesRequest, RefService_FindAllBranchesServer) error // Returns a stream of tags repository has. FindAllTags(*FindAllTagsRequest, RefService_FindAllTagsServer) error + // FindTag looks up a tag by its name and returns it to the caller if it exists. This RPC supports + // both lightweight and annotated tags. Note: this RPC returns an `Internal` error if the tag was + // not found. FindTag(context.Context, *FindTagRequest) (*FindTagResponse, error) + // This comment is left unintentionally blank. FindAllRemoteBranches(*FindAllRemoteBranchesRequest, RefService_FindAllRemoteBranchesServer) error + // This comment is left unintentionally blank. RefExists(context.Context, *RefExistsRequest) (*RefExistsResponse, error) // FindBranch finds a branch by its unqualified name (like "master") and // returns the commit it currently points to. FindBranch(context.Context, *FindBranchRequest) (*FindBranchResponse, error) + // This comment is left unintentionally blank. DeleteRefs(context.Context, *DeleteRefsRequest) (*DeleteRefsResponse, error) + // This comment is left unintentionally blank. ListBranchNamesContainingCommit(*ListBranchNamesContainingCommitRequest, RefService_ListBranchNamesContainingCommitServer) error + // This comment is left unintentionally blank. ListTagNamesContainingCommit(*ListTagNamesContainingCommitRequest, RefService_ListTagNamesContainingCommitServer) error // GetTagSignatures returns signatures for annotated tags resolved from a set of revisions. Revisions // which don't resolve to an annotated tag are silently discarded. Revisions which cannot be resolved // result in an error. Tags which are annotated but not signed will return a TagSignature response // which has no signature, but its unsigned contents will still be returned. GetTagSignatures(*GetTagSignaturesRequest, RefService_GetTagSignaturesServer) error + // This comment is left unintentionally blank. GetTagMessages(*GetTagMessagesRequest, RefService_GetTagMessagesServer) error // Deprecated: Do not use. // PackRefs is deprecated in favor of OptimizeRepository. diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote.pb.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote.pb.go index 4bdee73c74..351b4da3bc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: remote.proto package gitalypb @@ -20,6 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type UpdateRemoteMirrorRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -37,7 +38,7 @@ type UpdateRemoteMirrorRequest struct { // branch name without the 'refs/heads/' prefix. "*" can be used as a // wildcard to match anything. only_branches_matching can be streamed to the // server over multiple messages. Optional. - OnlyBranchesMatching [][]byte `protobuf:"bytes,3,rep,name=only_branches_matching,json=onlyBranchesMatching,proto3" json:"only_branches_matching,omitempty"` + OnlyBranchesMatching [][]byte `protobuf:"bytes,3,rep,name=only_branches_matching,json=onlyBranchesMatching,proto3" json:"only_branches_matching,omitempty"` // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED // SshKey is the SSH key to use for accessing to the mirror repository. // Optional. SshKey string `protobuf:"bytes,4,opt,name=ssh_key,json=sshKey,proto3" json:"ssh_key,omitempty"` @@ -123,6 +124,7 @@ func (x *UpdateRemoteMirrorRequest) GetKeepDivergentRefs() bool { return false } +// This comment is left unintentionally blank. type UpdateRemoteMirrorResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -172,11 +174,13 @@ func (x *UpdateRemoteMirrorResponse) GetDivergentRefs() [][]byte { return nil } +// This comment is left unintentionally blank. type FindRemoteRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Remote string `protobuf:"bytes,1,opt,name=remote,proto3" json:"remote,omitempty"` // This field is used to redirect request to proper storage where it can be handled. // As of now it doesn't matter what storage will be used, but it still must be a valid. @@ -237,6 +241,7 @@ type FindRemoteRepositoryResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` } @@ -410,6 +415,7 @@ func (x *FindRemoteRootRefResponse) GetRef() string { return "" } +// This comment is left unintentionally blank. type UpdateRemoteMirrorRequest_Remote struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -566,7 +572,7 @@ var file_remote_proto_rawDesc = []byte{ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, + 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote_grpc.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote_grpc.pb.go index f97b453a59..53538b15be 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/remote_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/remote_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: remote.proto package gitalypb @@ -24,6 +28,7 @@ type RemoteServiceClient interface { // deleted from the mirror. UpdateRemoteMirror updates all tags. Branches are updated if they match // the patterns specified in the requests. UpdateRemoteMirror(ctx context.Context, opts ...grpc.CallOption) (RemoteService_UpdateRemoteMirrorClient, error) + // This comment is left unintentionally blank. FindRemoteRepository(ctx context.Context, in *FindRemoteRepositoryRequest, opts ...grpc.CallOption) (*FindRemoteRepositoryResponse, error) // FindRemoteRootRef tries to find the root reference of a remote // repository. The root reference is the default branch as pointed to by @@ -103,6 +108,7 @@ type RemoteServiceServer interface { // deleted from the mirror. UpdateRemoteMirror updates all tags. Branches are updated if they match // the patterns specified in the requests. UpdateRemoteMirror(RemoteService_UpdateRemoteMirrorServer) error + // This comment is left unintentionally blank. FindRemoteRepository(context.Context, *FindRemoteRepositoryRequest) (*FindRemoteRepositoryResponse, error) // FindRemoteRootRef tries to find the root reference of a remote // repository. The root reference is the default branch as pointed to by diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository.pb.go similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository.pb.go index 54e49033c4..3d3dc4f95c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository.pb.go @@ -1,8 +1,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: repository-service.proto +// protoc-gen-go v1.28.0 +// protoc v3.21.1 +// source: repository.proto package gitalypb @@ -20,13 +20,14 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type WriteCommitGraphRequest_SplitStrategy int32 const ( // SizeMultiple requires to use '--split --size-multiple=4' strategy to create/update commit graph. // https://git-scm.com/docs/git-commit-graph#Documentation/git-commit-graph.txt-emwriteem // It is a default, there is no need to explicitly set it in the request. - WriteCommitGraphRequest_SizeMultiple WriteCommitGraphRequest_SplitStrategy = 0 + WriteCommitGraphRequest_SizeMultiple WriteCommitGraphRequest_SplitStrategy = 0 // protolint:disable:this ENUM_FIELD_NAMES_UPPER_SNAKE_CASE ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH ) // Enum value maps for WriteCommitGraphRequest_SplitStrategy. @@ -50,11 +51,11 @@ func (x WriteCommitGraphRequest_SplitStrategy) String() string { } func (WriteCommitGraphRequest_SplitStrategy) Descriptor() protoreflect.EnumDescriptor { - return file_repository_service_proto_enumTypes[0].Descriptor() + return file_repository_proto_enumTypes[0].Descriptor() } func (WriteCommitGraphRequest_SplitStrategy) Type() protoreflect.EnumType { - return &file_repository_service_proto_enumTypes[0] + return &file_repository_proto_enumTypes[0] } func (x WriteCommitGraphRequest_SplitStrategy) Number() protoreflect.EnumNumber { @@ -63,16 +64,21 @@ func (x WriteCommitGraphRequest_SplitStrategy) Number() protoreflect.EnumNumber // Deprecated: Use WriteCommitGraphRequest_SplitStrategy.Descriptor instead. func (WriteCommitGraphRequest_SplitStrategy) EnumDescriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{10, 0} + return file_repository_proto_rawDescGZIP(), []int{10, 0} } +// This comment is left unintentionally blank. type GetArchiveRequest_Format int32 const ( - GetArchiveRequest_ZIP GetArchiveRequest_Format = 0 - GetArchiveRequest_TAR GetArchiveRequest_Format = 1 - GetArchiveRequest_TAR_GZ GetArchiveRequest_Format = 2 - GetArchiveRequest_TAR_BZ2 GetArchiveRequest_Format = 3 + // This comment is left unintentionally blank. + GetArchiveRequest_ZIP GetArchiveRequest_Format = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + GetArchiveRequest_TAR GetArchiveRequest_Format = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetArchiveRequest_TAR_GZ GetArchiveRequest_Format = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetArchiveRequest_TAR_BZ2 GetArchiveRequest_Format = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for GetArchiveRequest_Format. @@ -102,11 +108,11 @@ func (x GetArchiveRequest_Format) String() string { } func (GetArchiveRequest_Format) Descriptor() protoreflect.EnumDescriptor { - return file_repository_service_proto_enumTypes[1].Descriptor() + return file_repository_proto_enumTypes[1].Descriptor() } func (GetArchiveRequest_Format) Type() protoreflect.EnumType { - return &file_repository_service_proto_enumTypes[1] + return &file_repository_proto_enumTypes[1] } func (x GetArchiveRequest_Format) Number() protoreflect.EnumNumber { @@ -115,19 +121,27 @@ func (x GetArchiveRequest_Format) Number() protoreflect.EnumNumber { // Deprecated: Use GetArchiveRequest_Format.Descriptor instead. func (GetArchiveRequest_Format) EnumDescriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{24, 0} + return file_repository_proto_rawDescGZIP(), []int{24, 0} } +// This comment is left unintentionally blank. type GetRawChangesResponse_RawChange_Operation int32 const ( - GetRawChangesResponse_RawChange_UNKNOWN GetRawChangesResponse_RawChange_Operation = 0 - GetRawChangesResponse_RawChange_ADDED GetRawChangesResponse_RawChange_Operation = 1 - GetRawChangesResponse_RawChange_COPIED GetRawChangesResponse_RawChange_Operation = 2 - GetRawChangesResponse_RawChange_DELETED GetRawChangesResponse_RawChange_Operation = 3 - GetRawChangesResponse_RawChange_MODIFIED GetRawChangesResponse_RawChange_Operation = 4 - GetRawChangesResponse_RawChange_RENAMED GetRawChangesResponse_RawChange_Operation = 5 - GetRawChangesResponse_RawChange_TYPE_CHANGED GetRawChangesResponse_RawChange_Operation = 6 + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_UNKNOWN GetRawChangesResponse_RawChange_Operation = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_ADDED GetRawChangesResponse_RawChange_Operation = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_COPIED GetRawChangesResponse_RawChange_Operation = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_DELETED GetRawChangesResponse_RawChange_Operation = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_MODIFIED GetRawChangesResponse_RawChange_Operation = 4 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_RENAMED GetRawChangesResponse_RawChange_Operation = 5 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + GetRawChangesResponse_RawChange_TYPE_CHANGED GetRawChangesResponse_RawChange_Operation = 6 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for GetRawChangesResponse_RawChange_Operation. @@ -163,11 +177,11 @@ func (x GetRawChangesResponse_RawChange_Operation) String() string { } func (GetRawChangesResponse_RawChange_Operation) Descriptor() protoreflect.EnumDescriptor { - return file_repository_service_proto_enumTypes[2].Descriptor() + return file_repository_proto_enumTypes[2].Descriptor() } func (GetRawChangesResponse_RawChange_Operation) Type() protoreflect.EnumType { - return &file_repository_service_proto_enumTypes[2] + return &file_repository_proto_enumTypes[2] } func (x GetRawChangesResponse_RawChange_Operation) Number() protoreflect.EnumNumber { @@ -176,21 +190,23 @@ func (x GetRawChangesResponse_RawChange_Operation) Number() protoreflect.EnumNum // Deprecated: Use GetRawChangesResponse_RawChange_Operation.Descriptor instead. func (GetRawChangesResponse_RawChange_Operation) EnumDescriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{63, 0, 0} + return file_repository_proto_rawDescGZIP(), []int{63, 0, 0} } +// This comment is left unintentionally blank. type RepositoryExistsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *RepositoryExistsRequest) Reset() { *x = RepositoryExistsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[0] + mi := &file_repository_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -203,7 +219,7 @@ func (x *RepositoryExistsRequest) String() string { func (*RepositoryExistsRequest) ProtoMessage() {} func (x *RepositoryExistsRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[0] + mi := &file_repository_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -216,7 +232,7 @@ func (x *RepositoryExistsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepositoryExistsRequest.ProtoReflect.Descriptor instead. func (*RepositoryExistsRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{0} + return file_repository_proto_rawDescGZIP(), []int{0} } func (x *RepositoryExistsRequest) GetRepository() *Repository { @@ -226,18 +242,20 @@ func (x *RepositoryExistsRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type RepositoryExistsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` } func (x *RepositoryExistsResponse) Reset() { *x = RepositoryExistsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[1] + mi := &file_repository_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -250,7 +268,7 @@ func (x *RepositoryExistsResponse) String() string { func (*RepositoryExistsResponse) ProtoMessage() {} func (x *RepositoryExistsResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[1] + mi := &file_repository_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -263,7 +281,7 @@ func (x *RepositoryExistsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepositoryExistsResponse.ProtoReflect.Descriptor instead. func (*RepositoryExistsResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{1} + return file_repository_proto_rawDescGZIP(), []int{1} } func (x *RepositoryExistsResponse) GetExists() bool { @@ -273,18 +291,20 @@ func (x *RepositoryExistsResponse) GetExists() bool { return false } +// This comment is left unintentionally blank. type RepackIncrementalRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *RepackIncrementalRequest) Reset() { *x = RepackIncrementalRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[2] + mi := &file_repository_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -297,7 +317,7 @@ func (x *RepackIncrementalRequest) String() string { func (*RepackIncrementalRequest) ProtoMessage() {} func (x *RepackIncrementalRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[2] + mi := &file_repository_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -310,7 +330,7 @@ func (x *RepackIncrementalRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepackIncrementalRequest.ProtoReflect.Descriptor instead. func (*RepackIncrementalRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{2} + return file_repository_proto_rawDescGZIP(), []int{2} } func (x *RepackIncrementalRequest) GetRepository() *Repository { @@ -320,6 +340,7 @@ func (x *RepackIncrementalRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type RepackIncrementalResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -329,7 +350,7 @@ type RepackIncrementalResponse struct { func (x *RepackIncrementalResponse) Reset() { *x = RepackIncrementalResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[3] + mi := &file_repository_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -342,7 +363,7 @@ func (x *RepackIncrementalResponse) String() string { func (*RepackIncrementalResponse) ProtoMessage() {} func (x *RepackIncrementalResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[3] + mi := &file_repository_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -355,22 +376,25 @@ func (x *RepackIncrementalResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepackIncrementalResponse.ProtoReflect.Descriptor instead. func (*RepackIncrementalResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{3} + return file_repository_proto_rawDescGZIP(), []int{3} } +// This comment is left unintentionally blank. type RepackFullRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CreateBitmap bool `protobuf:"varint,2,opt,name=create_bitmap,json=createBitmap,proto3" json:"create_bitmap,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + CreateBitmap bool `protobuf:"varint,2,opt,name=create_bitmap,json=createBitmap,proto3" json:"create_bitmap,omitempty"` } func (x *RepackFullRequest) Reset() { *x = RepackFullRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[4] + mi := &file_repository_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -383,7 +407,7 @@ func (x *RepackFullRequest) String() string { func (*RepackFullRequest) ProtoMessage() {} func (x *RepackFullRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[4] + mi := &file_repository_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -396,7 +420,7 @@ func (x *RepackFullRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepackFullRequest.ProtoReflect.Descriptor instead. func (*RepackFullRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{4} + return file_repository_proto_rawDescGZIP(), []int{4} } func (x *RepackFullRequest) GetRepository() *Repository { @@ -413,6 +437,7 @@ func (x *RepackFullRequest) GetCreateBitmap() bool { return false } +// This comment is left unintentionally blank. type RepackFullResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -422,7 +447,7 @@ type RepackFullResponse struct { func (x *RepackFullResponse) Reset() { *x = RepackFullResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[5] + mi := &file_repository_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -435,7 +460,7 @@ func (x *RepackFullResponse) String() string { func (*RepackFullResponse) ProtoMessage() {} func (x *RepackFullResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[5] + mi := &file_repository_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -448,21 +473,23 @@ func (x *RepackFullResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepackFullResponse.ProtoReflect.Descriptor instead. func (*RepackFullResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{5} + return file_repository_proto_rawDescGZIP(), []int{5} } +// This comment is left unintentionally blank. type MidxRepackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *MidxRepackRequest) Reset() { *x = MidxRepackRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[6] + mi := &file_repository_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -475,7 +502,7 @@ func (x *MidxRepackRequest) String() string { func (*MidxRepackRequest) ProtoMessage() {} func (x *MidxRepackRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[6] + mi := &file_repository_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -488,7 +515,7 @@ func (x *MidxRepackRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MidxRepackRequest.ProtoReflect.Descriptor instead. func (*MidxRepackRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{6} + return file_repository_proto_rawDescGZIP(), []int{6} } func (x *MidxRepackRequest) GetRepository() *Repository { @@ -498,6 +525,7 @@ func (x *MidxRepackRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type MidxRepackResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -507,7 +535,7 @@ type MidxRepackResponse struct { func (x *MidxRepackResponse) Reset() { *x = MidxRepackResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[7] + mi := &file_repository_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -520,7 +548,7 @@ func (x *MidxRepackResponse) String() string { func (*MidxRepackResponse) ProtoMessage() {} func (x *MidxRepackResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[7] + mi := &file_repository_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -533,16 +561,19 @@ func (x *MidxRepackResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MidxRepackResponse.ProtoReflect.Descriptor instead. func (*MidxRepackResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{7} + return file_repository_proto_rawDescGZIP(), []int{7} } +// This comment is left unintentionally blank. type GarbageCollectRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CreateBitmap bool `protobuf:"varint,2,opt,name=create_bitmap,json=createBitmap,proto3" json:"create_bitmap,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + CreateBitmap bool `protobuf:"varint,2,opt,name=create_bitmap,json=createBitmap,proto3" json:"create_bitmap,omitempty"` // If set to 'true' the 'gc' will be triggered with '--prune=30.minutes.ago' flag. // This will remove dangling objects from the object storage that were not modified in the last 30 minutes. // If 'false' provided the 'gc' will rely on the default expiration period (2 weeks). @@ -554,7 +585,7 @@ type GarbageCollectRequest struct { func (x *GarbageCollectRequest) Reset() { *x = GarbageCollectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[8] + mi := &file_repository_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -567,7 +598,7 @@ func (x *GarbageCollectRequest) String() string { func (*GarbageCollectRequest) ProtoMessage() {} func (x *GarbageCollectRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[8] + mi := &file_repository_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -580,7 +611,7 @@ func (x *GarbageCollectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GarbageCollectRequest.ProtoReflect.Descriptor instead. func (*GarbageCollectRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{8} + return file_repository_proto_rawDescGZIP(), []int{8} } func (x *GarbageCollectRequest) GetRepository() *Repository { @@ -604,6 +635,7 @@ func (x *GarbageCollectRequest) GetPrune() bool { return false } +// This comment is left unintentionally blank. type GarbageCollectResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -613,7 +645,7 @@ type GarbageCollectResponse struct { func (x *GarbageCollectResponse) Reset() { *x = GarbageCollectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[9] + mi := &file_repository_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -626,7 +658,7 @@ func (x *GarbageCollectResponse) String() string { func (*GarbageCollectResponse) ProtoMessage() {} func (x *GarbageCollectResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[9] + mi := &file_repository_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -639,23 +671,25 @@ func (x *GarbageCollectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GarbageCollectResponse.ProtoReflect.Descriptor instead. func (*GarbageCollectResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{9} + return file_repository_proto_rawDescGZIP(), []int{9} } +// This comment is left unintentionally blank. type WriteCommitGraphRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // SplitStrategy is a strategy used to create/update commit graph. - SplitStrategy WriteCommitGraphRequest_SplitStrategy `protobuf:"varint,2,opt,name=splitStrategy,proto3,enum=gitaly.WriteCommitGraphRequest_SplitStrategy" json:"splitStrategy,omitempty"` + SplitStrategy WriteCommitGraphRequest_SplitStrategy `protobuf:"varint,2,opt,name=splitStrategy,proto3,enum=gitaly.WriteCommitGraphRequest_SplitStrategy" json:"splitStrategy,omitempty"` // protolint:disable:this FIELD_NAMES_LOWER_SNAKE_CASE } func (x *WriteCommitGraphRequest) Reset() { *x = WriteCommitGraphRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[10] + mi := &file_repository_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -668,7 +702,7 @@ func (x *WriteCommitGraphRequest) String() string { func (*WriteCommitGraphRequest) ProtoMessage() {} func (x *WriteCommitGraphRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[10] + mi := &file_repository_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -681,7 +715,7 @@ func (x *WriteCommitGraphRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteCommitGraphRequest.ProtoReflect.Descriptor instead. func (*WriteCommitGraphRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{10} + return file_repository_proto_rawDescGZIP(), []int{10} } func (x *WriteCommitGraphRequest) GetRepository() *Repository { @@ -698,6 +732,7 @@ func (x *WriteCommitGraphRequest) GetSplitStrategy() WriteCommitGraphRequest_Spl return WriteCommitGraphRequest_SizeMultiple } +// This comment is left unintentionally blank. type WriteCommitGraphResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -707,7 +742,7 @@ type WriteCommitGraphResponse struct { func (x *WriteCommitGraphResponse) Reset() { *x = WriteCommitGraphResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[11] + mi := &file_repository_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -720,7 +755,7 @@ func (x *WriteCommitGraphResponse) String() string { func (*WriteCommitGraphResponse) ProtoMessage() {} func (x *WriteCommitGraphResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[11] + mi := &file_repository_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -733,21 +768,23 @@ func (x *WriteCommitGraphResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteCommitGraphResponse.ProtoReflect.Descriptor instead. func (*WriteCommitGraphResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{11} + return file_repository_proto_rawDescGZIP(), []int{11} } +// This comment is left unintentionally blank. type CleanupRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *CleanupRequest) Reset() { *x = CleanupRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[12] + mi := &file_repository_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -760,7 +797,7 @@ func (x *CleanupRequest) String() string { func (*CleanupRequest) ProtoMessage() {} func (x *CleanupRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[12] + mi := &file_repository_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -773,7 +810,7 @@ func (x *CleanupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CleanupRequest.ProtoReflect.Descriptor instead. func (*CleanupRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{12} + return file_repository_proto_rawDescGZIP(), []int{12} } func (x *CleanupRequest) GetRepository() *Repository { @@ -783,6 +820,7 @@ func (x *CleanupRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type CleanupResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -792,7 +830,7 @@ type CleanupResponse struct { func (x *CleanupResponse) Reset() { *x = CleanupResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[13] + mi := &file_repository_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -805,7 +843,7 @@ func (x *CleanupResponse) String() string { func (*CleanupResponse) ProtoMessage() {} func (x *CleanupResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[13] + mi := &file_repository_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -818,21 +856,23 @@ func (x *CleanupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CleanupResponse.ProtoReflect.Descriptor instead. func (*CleanupResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{13} + return file_repository_proto_rawDescGZIP(), []int{13} } +// This comment is left unintentionally blank. type RepositorySizeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *RepositorySizeRequest) Reset() { *x = RepositorySizeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[14] + mi := &file_repository_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -845,7 +885,7 @@ func (x *RepositorySizeRequest) String() string { func (*RepositorySizeRequest) ProtoMessage() {} func (x *RepositorySizeRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[14] + mi := &file_repository_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -858,7 +898,7 @@ func (x *RepositorySizeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepositorySizeRequest.ProtoReflect.Descriptor instead. func (*RepositorySizeRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{14} + return file_repository_proto_rawDescGZIP(), []int{14} } func (x *RepositorySizeRequest) GetRepository() *Repository { @@ -868,6 +908,7 @@ func (x *RepositorySizeRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type RepositorySizeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -880,7 +921,7 @@ type RepositorySizeResponse struct { func (x *RepositorySizeResponse) Reset() { *x = RepositorySizeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[15] + mi := &file_repository_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -893,7 +934,7 @@ func (x *RepositorySizeResponse) String() string { func (*RepositorySizeResponse) ProtoMessage() {} func (x *RepositorySizeResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[15] + mi := &file_repository_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -906,7 +947,7 @@ func (x *RepositorySizeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepositorySizeResponse.ProtoReflect.Descriptor instead. func (*RepositorySizeResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{15} + return file_repository_proto_rawDescGZIP(), []int{15} } func (x *RepositorySizeResponse) GetSize() int64 { @@ -916,19 +957,22 @@ func (x *RepositorySizeResponse) GetSize() int64 { return 0 } +// This comment is left unintentionally blank. type ApplyGitattributesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` } func (x *ApplyGitattributesRequest) Reset() { *x = ApplyGitattributesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[16] + mi := &file_repository_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -941,7 +985,7 @@ func (x *ApplyGitattributesRequest) String() string { func (*ApplyGitattributesRequest) ProtoMessage() {} func (x *ApplyGitattributesRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[16] + mi := &file_repository_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -954,7 +998,7 @@ func (x *ApplyGitattributesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyGitattributesRequest.ProtoReflect.Descriptor instead. func (*ApplyGitattributesRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{16} + return file_repository_proto_rawDescGZIP(), []int{16} } func (x *ApplyGitattributesRequest) GetRepository() *Repository { @@ -971,6 +1015,7 @@ func (x *ApplyGitattributesRequest) GetRevision() []byte { return nil } +// This comment is left unintentionally blank. type ApplyGitattributesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -980,7 +1025,7 @@ type ApplyGitattributesResponse struct { func (x *ApplyGitattributesResponse) Reset() { *x = ApplyGitattributesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[17] + mi := &file_repository_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -993,7 +1038,7 @@ func (x *ApplyGitattributesResponse) String() string { func (*ApplyGitattributesResponse) ProtoMessage() {} func (x *ApplyGitattributesResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[17] + mi := &file_repository_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1006,9 +1051,10 @@ func (x *ApplyGitattributesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyGitattributesResponse.ProtoReflect.Descriptor instead. func (*ApplyGitattributesResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{17} + return file_repository_proto_rawDescGZIP(), []int{17} } +// This comment is left unintentionally blank. type FetchBundleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1025,7 +1071,7 @@ type FetchBundleRequest struct { func (x *FetchBundleRequest) Reset() { *x = FetchBundleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[18] + mi := &file_repository_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1038,7 +1084,7 @@ func (x *FetchBundleRequest) String() string { func (*FetchBundleRequest) ProtoMessage() {} func (x *FetchBundleRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[18] + mi := &file_repository_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1051,7 +1097,7 @@ func (x *FetchBundleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchBundleRequest.ProtoReflect.Descriptor instead. func (*FetchBundleRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{18} + return file_repository_proto_rawDescGZIP(), []int{18} } func (x *FetchBundleRequest) GetRepository() *Repository { @@ -1075,6 +1121,7 @@ func (x *FetchBundleRequest) GetUpdateHead() bool { return false } +// This comment is left unintentionally blank. type FetchBundleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1084,7 +1131,7 @@ type FetchBundleResponse struct { func (x *FetchBundleResponse) Reset() { *x = FetchBundleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[19] + mi := &file_repository_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1097,7 +1144,7 @@ func (x *FetchBundleResponse) String() string { func (*FetchBundleResponse) ProtoMessage() {} func (x *FetchBundleResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[19] + mi := &file_repository_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1110,14 +1157,16 @@ func (x *FetchBundleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchBundleResponse.ProtoReflect.Descriptor instead. func (*FetchBundleResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{19} + return file_repository_proto_rawDescGZIP(), []int{19} } +// This comment is left unintentionally blank. type FetchRemoteRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // force determines if references should be force-updated in case they have // diverged. @@ -1125,8 +1174,10 @@ type FetchRemoteRequest struct { // no_tags determines whether tags should be fetched. NoTags bool `protobuf:"varint,4,opt,name=no_tags,json=noTags,proto3" json:"no_tags,omitempty"` // timeout specifies a timeout for the fetch. - Timeout int32 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"` - SshKey string `protobuf:"bytes,6,opt,name=ssh_key,json=sshKey,proto3" json:"ssh_key,omitempty"` + Timeout int32 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"` + // This comment is left unintentionally blank. + SshKey string `protobuf:"bytes,6,opt,name=ssh_key,json=sshKey,proto3" json:"ssh_key,omitempty"` + // This comment is left unintentionally blank. KnownHosts string `protobuf:"bytes,7,opt,name=known_hosts,json=knownHosts,proto3" json:"known_hosts,omitempty"` // no_prune will the fetch to not prune remote references which do not exist // in the remote repository anymore. @@ -1143,7 +1194,7 @@ type FetchRemoteRequest struct { func (x *FetchRemoteRequest) Reset() { *x = FetchRemoteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[20] + mi := &file_repository_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1156,7 +1207,7 @@ func (x *FetchRemoteRequest) String() string { func (*FetchRemoteRequest) ProtoMessage() {} func (x *FetchRemoteRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[20] + mi := &file_repository_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1169,7 +1220,7 @@ func (x *FetchRemoteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchRemoteRequest.ProtoReflect.Descriptor instead. func (*FetchRemoteRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{20} + return file_repository_proto_rawDescGZIP(), []int{20} } func (x *FetchRemoteRequest) GetRepository() *Repository { @@ -1235,6 +1286,7 @@ func (x *FetchRemoteRequest) GetCheckTagsChanged() bool { return false } +// This comment is left unintentionally blank. type FetchRemoteResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1249,7 +1301,7 @@ type FetchRemoteResponse struct { func (x *FetchRemoteResponse) Reset() { *x = FetchRemoteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[21] + mi := &file_repository_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1262,7 +1314,7 @@ func (x *FetchRemoteResponse) String() string { func (*FetchRemoteResponse) ProtoMessage() {} func (x *FetchRemoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[21] + mi := &file_repository_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1275,7 +1327,7 @@ func (x *FetchRemoteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchRemoteResponse.ProtoReflect.Descriptor instead. func (*FetchRemoteResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{21} + return file_repository_proto_rawDescGZIP(), []int{21} } func (x *FetchRemoteResponse) GetTagsChanged() bool { @@ -1285,11 +1337,13 @@ func (x *FetchRemoteResponse) GetTagsChanged() bool { return false } +// This comment is left unintentionally blank. type CreateRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Provide a branch name to set as the default branch of a newly created // repository. Note, this will be treated as the branch name and not a @@ -1300,7 +1354,7 @@ type CreateRepositoryRequest struct { func (x *CreateRepositoryRequest) Reset() { *x = CreateRepositoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[22] + mi := &file_repository_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1313,7 +1367,7 @@ func (x *CreateRepositoryRequest) String() string { func (*CreateRepositoryRequest) ProtoMessage() {} func (x *CreateRepositoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[22] + mi := &file_repository_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1326,7 +1380,7 @@ func (x *CreateRepositoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRepositoryRequest.ProtoReflect.Descriptor instead. func (*CreateRepositoryRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{22} + return file_repository_proto_rawDescGZIP(), []int{22} } func (x *CreateRepositoryRequest) GetRepository() *Repository { @@ -1343,6 +1397,7 @@ func (x *CreateRepositoryRequest) GetDefaultBranch() []byte { return nil } +// This comment is left unintentionally blank. type CreateRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1352,7 +1407,7 @@ type CreateRepositoryResponse struct { func (x *CreateRepositoryResponse) Reset() { *x = CreateRepositoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[23] + mi := &file_repository_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1365,7 +1420,7 @@ func (x *CreateRepositoryResponse) String() string { func (*CreateRepositoryResponse) ProtoMessage() {} func (x *CreateRepositoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[23] + mi := &file_repository_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1378,34 +1433,42 @@ func (x *CreateRepositoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRepositoryResponse.ProtoReflect.Descriptor instead. func (*CreateRepositoryResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{23} + return file_repository_proto_rawDescGZIP(), []int{23} } +// This comment is left unintentionally blank. type GetArchiveRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` - Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"` - Format GetArchiveRequest_Format `protobuf:"varint,4,opt,name=format,proto3,enum=gitaly.GetArchiveRequest_Format" json:"format,omitempty"` - Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` - Exclude [][]byte `protobuf:"bytes,6,rep,name=exclude,proto3" json:"exclude,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + // This comment is left unintentionally blank. + Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"` + // This comment is left unintentionally blank. + Format GetArchiveRequest_Format `protobuf:"varint,4,opt,name=format,proto3,enum=gitaly.GetArchiveRequest_Format" json:"format,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Exclude [][]byte `protobuf:"bytes,6,rep,name=exclude,proto3" json:"exclude,omitempty"` // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED // If `elide_path` is true and `path` refers to a subdirectory, that // subdirectory will be elided from archive entries. For example, if `dir` // contains `README.md`, with `elide_path = false` the corresponding entry // will be `dir/README.md`; with `elide_path = true`, the entry will be // `README.md`. `elide_path` has no effect if `path` refers to the repository // root. `elide_path = true` is not supported if `path` refers to a file. - ElidePath bool `protobuf:"varint,7,opt,name=elide_path,json=elidePath,proto3" json:"elide_path,omitempty"` + ElidePath bool `protobuf:"varint,7,opt,name=elide_path,json=elidePath,proto3" json:"elide_path,omitempty"` + // This comment is left unintentionally blank. IncludeLfsBlobs bool `protobuf:"varint,8,opt,name=include_lfs_blobs,json=includeLfsBlobs,proto3" json:"include_lfs_blobs,omitempty"` } func (x *GetArchiveRequest) Reset() { *x = GetArchiveRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[24] + mi := &file_repository_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1418,7 +1481,7 @@ func (x *GetArchiveRequest) String() string { func (*GetArchiveRequest) ProtoMessage() {} func (x *GetArchiveRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[24] + mi := &file_repository_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1431,7 +1494,7 @@ func (x *GetArchiveRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetArchiveRequest.ProtoReflect.Descriptor instead. func (*GetArchiveRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{24} + return file_repository_proto_rawDescGZIP(), []int{24} } func (x *GetArchiveRequest) GetRepository() *Repository { @@ -1490,18 +1553,20 @@ func (x *GetArchiveRequest) GetIncludeLfsBlobs() bool { return false } +// This comment is left unintentionally blank. type GetArchiveResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } func (x *GetArchiveResponse) Reset() { *x = GetArchiveResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[25] + mi := &file_repository_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1514,7 +1579,7 @@ func (x *GetArchiveResponse) String() string { func (*GetArchiveResponse) ProtoMessage() {} func (x *GetArchiveResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[25] + mi := &file_repository_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1527,7 +1592,7 @@ func (x *GetArchiveResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetArchiveResponse.ProtoReflect.Descriptor instead. func (*GetArchiveResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{25} + return file_repository_proto_rawDescGZIP(), []int{25} } func (x *GetArchiveResponse) GetData() []byte { @@ -1537,18 +1602,20 @@ func (x *GetArchiveResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type HasLocalBranchesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *HasLocalBranchesRequest) Reset() { *x = HasLocalBranchesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[26] + mi := &file_repository_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1561,7 +1628,7 @@ func (x *HasLocalBranchesRequest) String() string { func (*HasLocalBranchesRequest) ProtoMessage() {} func (x *HasLocalBranchesRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[26] + mi := &file_repository_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1574,7 +1641,7 @@ func (x *HasLocalBranchesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use HasLocalBranchesRequest.ProtoReflect.Descriptor instead. func (*HasLocalBranchesRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{26} + return file_repository_proto_rawDescGZIP(), []int{26} } func (x *HasLocalBranchesRequest) GetRepository() *Repository { @@ -1584,18 +1651,20 @@ func (x *HasLocalBranchesRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type HasLocalBranchesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` } func (x *HasLocalBranchesResponse) Reset() { *x = HasLocalBranchesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[27] + mi := &file_repository_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1608,7 +1677,7 @@ func (x *HasLocalBranchesResponse) String() string { func (*HasLocalBranchesResponse) ProtoMessage() {} func (x *HasLocalBranchesResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[27] + mi := &file_repository_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1621,7 +1690,7 @@ func (x *HasLocalBranchesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HasLocalBranchesResponse.ProtoReflect.Descriptor instead. func (*HasLocalBranchesResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{27} + return file_repository_proto_rawDescGZIP(), []int{27} } func (x *HasLocalBranchesResponse) GetValue() bool { @@ -1631,6 +1700,7 @@ func (x *HasLocalBranchesResponse) GetValue() bool { return false } +// This comment is left unintentionally blank. type FetchSourceBranchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1652,7 +1722,7 @@ type FetchSourceBranchRequest struct { func (x *FetchSourceBranchRequest) Reset() { *x = FetchSourceBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[28] + mi := &file_repository_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1665,7 +1735,7 @@ func (x *FetchSourceBranchRequest) String() string { func (*FetchSourceBranchRequest) ProtoMessage() {} func (x *FetchSourceBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[28] + mi := &file_repository_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1678,7 +1748,7 @@ func (x *FetchSourceBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSourceBranchRequest.ProtoReflect.Descriptor instead. func (*FetchSourceBranchRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{28} + return file_repository_proto_rawDescGZIP(), []int{28} } func (x *FetchSourceBranchRequest) GetRepository() *Repository { @@ -1709,6 +1779,7 @@ func (x *FetchSourceBranchRequest) GetTargetRef() []byte { return nil } +// This comment is left unintentionally blank. type FetchSourceBranchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1722,7 +1793,7 @@ type FetchSourceBranchResponse struct { func (x *FetchSourceBranchResponse) Reset() { *x = FetchSourceBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[29] + mi := &file_repository_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1735,7 +1806,7 @@ func (x *FetchSourceBranchResponse) String() string { func (*FetchSourceBranchResponse) ProtoMessage() {} func (x *FetchSourceBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[29] + mi := &file_repository_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1748,7 +1819,7 @@ func (x *FetchSourceBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchSourceBranchResponse.ProtoReflect.Descriptor instead. func (*FetchSourceBranchResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{29} + return file_repository_proto_rawDescGZIP(), []int{29} } func (x *FetchSourceBranchResponse) GetResult() bool { @@ -1758,18 +1829,20 @@ func (x *FetchSourceBranchResponse) GetResult() bool { return false } +// This comment is left unintentionally blank. type FsckRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *FsckRequest) Reset() { *x = FsckRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[30] + mi := &file_repository_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1782,7 +1855,7 @@ func (x *FsckRequest) String() string { func (*FsckRequest) ProtoMessage() {} func (x *FsckRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[30] + mi := &file_repository_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1795,7 +1868,7 @@ func (x *FsckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FsckRequest.ProtoReflect.Descriptor instead. func (*FsckRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{30} + return file_repository_proto_rawDescGZIP(), []int{30} } func (x *FsckRequest) GetRepository() *Repository { @@ -1805,18 +1878,20 @@ func (x *FsckRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type FsckResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Error []byte `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` } func (x *FsckResponse) Reset() { *x = FsckResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[31] + mi := &file_repository_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1829,7 +1904,7 @@ func (x *FsckResponse) String() string { func (*FsckResponse) ProtoMessage() {} func (x *FsckResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[31] + mi := &file_repository_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1842,7 +1917,7 @@ func (x *FsckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FsckResponse.ProtoReflect.Descriptor instead. func (*FsckResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{31} + return file_repository_proto_rawDescGZIP(), []int{31} } func (x *FsckResponse) GetError() []byte { @@ -1852,22 +1927,28 @@ func (x *FsckResponse) GetError() []byte { return nil } +// This comment is left unintentionally blank. type WriteRefRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Ref []byte `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` - Revision []byte `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` - OldRevision []byte `protobuf:"bytes,4,opt,name=old_revision,json=oldRevision,proto3" json:"old_revision,omitempty"` - Force bool `protobuf:"varint,5,opt,name=force,proto3" json:"force,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Ref []byte `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + OldRevision []byte `protobuf:"bytes,4,opt,name=old_revision,json=oldRevision,proto3" json:"old_revision,omitempty"` + // This comment is left unintentionally blank. + Force bool `protobuf:"varint,5,opt,name=force,proto3" json:"force,omitempty"` } func (x *WriteRefRequest) Reset() { *x = WriteRefRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[32] + mi := &file_repository_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1880,7 +1961,7 @@ func (x *WriteRefRequest) String() string { func (*WriteRefRequest) ProtoMessage() {} func (x *WriteRefRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[32] + mi := &file_repository_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1893,7 +1974,7 @@ func (x *WriteRefRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteRefRequest.ProtoReflect.Descriptor instead. func (*WriteRefRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{32} + return file_repository_proto_rawDescGZIP(), []int{32} } func (x *WriteRefRequest) GetRepository() *Repository { @@ -1931,6 +2012,7 @@ func (x *WriteRefRequest) GetForce() bool { return false } +// This comment is left unintentionally blank. type WriteRefResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1940,7 +2022,7 @@ type WriteRefResponse struct { func (x *WriteRefResponse) Reset() { *x = WriteRefResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[33] + mi := &file_repository_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1953,7 +2035,7 @@ func (x *WriteRefResponse) String() string { func (*WriteRefResponse) ProtoMessage() {} func (x *WriteRefResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[33] + mi := &file_repository_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1966,14 +2048,16 @@ func (x *WriteRefResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteRefResponse.ProtoReflect.Descriptor instead. func (*WriteRefResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{33} + return file_repository_proto_rawDescGZIP(), []int{33} } +// This comment is left unintentionally blank. type FindMergeBaseRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // We use a repeated field because rugged supports finding a base // for more than 2 revisions, so if we needed that in the future we don't @@ -1984,7 +2068,7 @@ type FindMergeBaseRequest struct { func (x *FindMergeBaseRequest) Reset() { *x = FindMergeBaseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[34] + mi := &file_repository_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1997,7 +2081,7 @@ func (x *FindMergeBaseRequest) String() string { func (*FindMergeBaseRequest) ProtoMessage() {} func (x *FindMergeBaseRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[34] + mi := &file_repository_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2010,7 +2094,7 @@ func (x *FindMergeBaseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindMergeBaseRequest.ProtoReflect.Descriptor instead. func (*FindMergeBaseRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{34} + return file_repository_proto_rawDescGZIP(), []int{34} } func (x *FindMergeBaseRequest) GetRepository() *Repository { @@ -2027,18 +2111,20 @@ func (x *FindMergeBaseRequest) GetRevisions() [][]byte { return nil } +// This comment is left unintentionally blank. type FindMergeBaseResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Base string `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` } func (x *FindMergeBaseResponse) Reset() { *x = FindMergeBaseResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[35] + mi := &file_repository_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2051,7 +2137,7 @@ func (x *FindMergeBaseResponse) String() string { func (*FindMergeBaseResponse) ProtoMessage() {} func (x *FindMergeBaseResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[35] + mi := &file_repository_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2064,7 +2150,7 @@ func (x *FindMergeBaseResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindMergeBaseResponse.ProtoReflect.Descriptor instead. func (*FindMergeBaseResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{35} + return file_repository_proto_rawDescGZIP(), []int{35} } func (x *FindMergeBaseResponse) GetBase() string { @@ -2074,19 +2160,22 @@ func (x *FindMergeBaseResponse) GetBase() string { return "" } +// This comment is left unintentionally blank. type CreateForkRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. SourceRepository *Repository `protobuf:"bytes,2,opt,name=source_repository,json=sourceRepository,proto3" json:"source_repository,omitempty"` } func (x *CreateForkRequest) Reset() { *x = CreateForkRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[36] + mi := &file_repository_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2099,7 +2188,7 @@ func (x *CreateForkRequest) String() string { func (*CreateForkRequest) ProtoMessage() {} func (x *CreateForkRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[36] + mi := &file_repository_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2112,7 +2201,7 @@ func (x *CreateForkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateForkRequest.ProtoReflect.Descriptor instead. func (*CreateForkRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{36} + return file_repository_proto_rawDescGZIP(), []int{36} } func (x *CreateForkRequest) GetRepository() *Repository { @@ -2129,6 +2218,7 @@ func (x *CreateForkRequest) GetSourceRepository() *Repository { return nil } +// This comment is left unintentionally blank. type CreateForkResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2138,7 +2228,7 @@ type CreateForkResponse struct { func (x *CreateForkResponse) Reset() { *x = CreateForkResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[37] + mi := &file_repository_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2151,7 +2241,7 @@ func (x *CreateForkResponse) String() string { func (*CreateForkResponse) ProtoMessage() {} func (x *CreateForkResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[37] + mi := &file_repository_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2164,16 +2254,19 @@ func (x *CreateForkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateForkResponse.ProtoReflect.Descriptor instead. func (*CreateForkResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{37} + return file_repository_proto_rawDescGZIP(), []int{37} } +// This comment is left unintentionally blank. type CreateRepositoryFromURLRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + // This comment is left unintentionally blank. + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` // HttpHost is the hostname of the remote repository. Use this when the // URL hostname has already been resolved to an IP address to prevent DNS // rebinding. @@ -2192,7 +2285,7 @@ type CreateRepositoryFromURLRequest struct { func (x *CreateRepositoryFromURLRequest) Reset() { *x = CreateRepositoryFromURLRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[38] + mi := &file_repository_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2205,7 +2298,7 @@ func (x *CreateRepositoryFromURLRequest) String() string { func (*CreateRepositoryFromURLRequest) ProtoMessage() {} func (x *CreateRepositoryFromURLRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[38] + mi := &file_repository_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2218,7 +2311,7 @@ func (x *CreateRepositoryFromURLRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRepositoryFromURLRequest.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromURLRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{38} + return file_repository_proto_rawDescGZIP(), []int{38} } func (x *CreateRepositoryFromURLRequest) GetRepository() *Repository { @@ -2256,6 +2349,7 @@ func (x *CreateRepositoryFromURLRequest) GetMirror() bool { return false } +// This comment is left unintentionally blank. type CreateRepositoryFromURLResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2265,7 +2359,7 @@ type CreateRepositoryFromURLResponse struct { func (x *CreateRepositoryFromURLResponse) Reset() { *x = CreateRepositoryFromURLResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[39] + mi := &file_repository_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2278,7 +2372,7 @@ func (x *CreateRepositoryFromURLResponse) String() string { func (*CreateRepositoryFromURLResponse) ProtoMessage() {} func (x *CreateRepositoryFromURLResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[39] + mi := &file_repository_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2291,21 +2385,23 @@ func (x *CreateRepositoryFromURLResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRepositoryFromURLResponse.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromURLResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{39} + return file_repository_proto_rawDescGZIP(), []int{39} } +// This comment is left unintentionally blank. type CreateBundleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *CreateBundleRequest) Reset() { *x = CreateBundleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[40] + mi := &file_repository_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2318,7 +2414,7 @@ func (x *CreateBundleRequest) String() string { func (*CreateBundleRequest) ProtoMessage() {} func (x *CreateBundleRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[40] + mi := &file_repository_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2331,7 +2427,7 @@ func (x *CreateBundleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBundleRequest.ProtoReflect.Descriptor instead. func (*CreateBundleRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{40} + return file_repository_proto_rawDescGZIP(), []int{40} } func (x *CreateBundleRequest) GetRepository() *Repository { @@ -2341,18 +2437,20 @@ func (x *CreateBundleRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type CreateBundleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } func (x *CreateBundleResponse) Reset() { *x = CreateBundleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[41] + mi := &file_repository_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2365,7 +2463,7 @@ func (x *CreateBundleResponse) String() string { func (*CreateBundleResponse) ProtoMessage() {} func (x *CreateBundleResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[41] + mi := &file_repository_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2378,7 +2476,7 @@ func (x *CreateBundleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBundleResponse.ProtoReflect.Descriptor instead. func (*CreateBundleResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{41} + return file_repository_proto_rawDescGZIP(), []int{41} } func (x *CreateBundleResponse) GetData() []byte { @@ -2388,6 +2486,7 @@ func (x *CreateBundleResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type CreateBundleFromRefListRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2404,7 +2503,7 @@ type CreateBundleFromRefListRequest struct { func (x *CreateBundleFromRefListRequest) Reset() { *x = CreateBundleFromRefListRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[42] + mi := &file_repository_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2417,7 +2516,7 @@ func (x *CreateBundleFromRefListRequest) String() string { func (*CreateBundleFromRefListRequest) ProtoMessage() {} func (x *CreateBundleFromRefListRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[42] + mi := &file_repository_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2430,7 +2529,7 @@ func (x *CreateBundleFromRefListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBundleFromRefListRequest.ProtoReflect.Descriptor instead. func (*CreateBundleFromRefListRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{42} + return file_repository_proto_rawDescGZIP(), []int{42} } func (x *CreateBundleFromRefListRequest) GetRepository() *Repository { @@ -2447,18 +2546,20 @@ func (x *CreateBundleFromRefListRequest) GetPatterns() [][]byte { return nil } +// This comment is left unintentionally blank. type CreateBundleFromRefListResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } func (x *CreateBundleFromRefListResponse) Reset() { *x = CreateBundleFromRefListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[43] + mi := &file_repository_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2471,7 +2572,7 @@ func (x *CreateBundleFromRefListResponse) String() string { func (*CreateBundleFromRefListResponse) ProtoMessage() {} func (x *CreateBundleFromRefListResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[43] + mi := &file_repository_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2484,7 +2585,7 @@ func (x *CreateBundleFromRefListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateBundleFromRefListResponse.ProtoReflect.Descriptor instead. func (*CreateBundleFromRefListResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{43} + return file_repository_proto_rawDescGZIP(), []int{43} } func (x *CreateBundleFromRefListResponse) GetData() []byte { @@ -2508,7 +2609,7 @@ type GetConfigRequest struct { func (x *GetConfigRequest) Reset() { *x = GetConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[44] + mi := &file_repository_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2521,7 +2622,7 @@ func (x *GetConfigRequest) String() string { func (*GetConfigRequest) ProtoMessage() {} func (x *GetConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[44] + mi := &file_repository_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2534,7 +2635,7 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead. func (*GetConfigRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{44} + return file_repository_proto_rawDescGZIP(), []int{44} } func (x *GetConfigRequest) GetRepository() *Repository { @@ -2557,7 +2658,7 @@ type GetConfigResponse struct { func (x *GetConfigResponse) Reset() { *x = GetConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[45] + mi := &file_repository_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2570,7 +2671,7 @@ func (x *GetConfigResponse) String() string { func (*GetConfigResponse) ProtoMessage() {} func (x *GetConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[45] + mi := &file_repository_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2583,7 +2684,7 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead. func (*GetConfigResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{45} + return file_repository_proto_rawDescGZIP(), []int{45} } func (x *GetConfigResponse) GetData() []byte { @@ -2593,19 +2694,22 @@ func (x *GetConfigResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type RestoreCustomHooksRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // This comment is left unintentionally blank. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` } func (x *RestoreCustomHooksRequest) Reset() { *x = RestoreCustomHooksRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[46] + mi := &file_repository_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2618,7 +2722,7 @@ func (x *RestoreCustomHooksRequest) String() string { func (*RestoreCustomHooksRequest) ProtoMessage() {} func (x *RestoreCustomHooksRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[46] + mi := &file_repository_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2631,7 +2735,7 @@ func (x *RestoreCustomHooksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreCustomHooksRequest.ProtoReflect.Descriptor instead. func (*RestoreCustomHooksRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{46} + return file_repository_proto_rawDescGZIP(), []int{46} } func (x *RestoreCustomHooksRequest) GetRepository() *Repository { @@ -2648,6 +2752,7 @@ func (x *RestoreCustomHooksRequest) GetData() []byte { return nil } +// This comment is left unintentionally blank. type RestoreCustomHooksResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2657,7 +2762,7 @@ type RestoreCustomHooksResponse struct { func (x *RestoreCustomHooksResponse) Reset() { *x = RestoreCustomHooksResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[47] + mi := &file_repository_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2670,7 +2775,7 @@ func (x *RestoreCustomHooksResponse) String() string { func (*RestoreCustomHooksResponse) ProtoMessage() {} func (x *RestoreCustomHooksResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[47] + mi := &file_repository_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2683,21 +2788,23 @@ func (x *RestoreCustomHooksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreCustomHooksResponse.ProtoReflect.Descriptor instead. func (*RestoreCustomHooksResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{47} + return file_repository_proto_rawDescGZIP(), []int{47} } +// This comment is left unintentionally blank. type BackupCustomHooksRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *BackupCustomHooksRequest) Reset() { *x = BackupCustomHooksRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[48] + mi := &file_repository_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2710,7 +2817,7 @@ func (x *BackupCustomHooksRequest) String() string { func (*BackupCustomHooksRequest) ProtoMessage() {} func (x *BackupCustomHooksRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[48] + mi := &file_repository_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2723,7 +2830,7 @@ func (x *BackupCustomHooksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BackupCustomHooksRequest.ProtoReflect.Descriptor instead. func (*BackupCustomHooksRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{48} + return file_repository_proto_rawDescGZIP(), []int{48} } func (x *BackupCustomHooksRequest) GetRepository() *Repository { @@ -2733,18 +2840,20 @@ func (x *BackupCustomHooksRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type BackupCustomHooksResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } func (x *BackupCustomHooksResponse) Reset() { *x = BackupCustomHooksResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[49] + mi := &file_repository_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2757,7 +2866,7 @@ func (x *BackupCustomHooksResponse) String() string { func (*BackupCustomHooksResponse) ProtoMessage() {} func (x *BackupCustomHooksResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[49] + mi := &file_repository_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2770,7 +2879,7 @@ func (x *BackupCustomHooksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BackupCustomHooksResponse.ProtoReflect.Descriptor instead. func (*BackupCustomHooksResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{49} + return file_repository_proto_rawDescGZIP(), []int{49} } func (x *BackupCustomHooksResponse) GetData() []byte { @@ -2780,6 +2889,7 @@ func (x *BackupCustomHooksResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type CreateRepositoryFromBundleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2787,13 +2897,14 @@ type CreateRepositoryFromBundleRequest struct { // Only available on the first message Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // This comment is left unintentionally blank. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` } func (x *CreateRepositoryFromBundleRequest) Reset() { *x = CreateRepositoryFromBundleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[50] + mi := &file_repository_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2806,7 +2917,7 @@ func (x *CreateRepositoryFromBundleRequest) String() string { func (*CreateRepositoryFromBundleRequest) ProtoMessage() {} func (x *CreateRepositoryFromBundleRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[50] + mi := &file_repository_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2819,7 +2930,7 @@ func (x *CreateRepositoryFromBundleRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateRepositoryFromBundleRequest.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromBundleRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{50} + return file_repository_proto_rawDescGZIP(), []int{50} } func (x *CreateRepositoryFromBundleRequest) GetRepository() *Repository { @@ -2836,6 +2947,7 @@ func (x *CreateRepositoryFromBundleRequest) GetData() []byte { return nil } +// This comment is left unintentionally blank. type CreateRepositoryFromBundleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2845,7 +2957,7 @@ type CreateRepositoryFromBundleResponse struct { func (x *CreateRepositoryFromBundleResponse) Reset() { *x = CreateRepositoryFromBundleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[51] + mi := &file_repository_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2858,7 +2970,7 @@ func (x *CreateRepositoryFromBundleResponse) String() string { func (*CreateRepositoryFromBundleResponse) ProtoMessage() {} func (x *CreateRepositoryFromBundleResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[51] + mi := &file_repository_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2871,21 +2983,23 @@ func (x *CreateRepositoryFromBundleResponse) ProtoReflect() protoreflect.Message // Deprecated: Use CreateRepositoryFromBundleResponse.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromBundleResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{51} + return file_repository_proto_rawDescGZIP(), []int{51} } +// This comment is left unintentionally blank. type FindLicenseRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *FindLicenseRequest) Reset() { *x = FindLicenseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[52] + mi := &file_repository_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2898,7 +3012,7 @@ func (x *FindLicenseRequest) String() string { func (*FindLicenseRequest) ProtoMessage() {} func (x *FindLicenseRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[52] + mi := &file_repository_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2911,7 +3025,7 @@ func (x *FindLicenseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindLicenseRequest.ProtoReflect.Descriptor instead. func (*FindLicenseRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{52} + return file_repository_proto_rawDescGZIP(), []int{52} } func (x *FindLicenseRequest) GetRepository() *Repository { @@ -2921,18 +3035,33 @@ func (x *FindLicenseRequest) GetRepository() *Repository { return nil } +// FindLicenseResponse contains the result of detecting the license used in the repository. +// If there is nothing that looks like a license file, the empty response is returned. +// If there is something that looks like a license, but that license can't be found in the +// list of known licenses, we return a pre-defined response with "Other" license. type FindLicenseResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // LicenseShortName is the license unique SPDX identifier or a short name. + // It is always returned lower-cased. LicenseShortName string `protobuf:"bytes,1,opt,name=license_short_name,json=licenseShortName,proto3" json:"license_short_name,omitempty"` + // LicenseName is the license full name. + LicenseName string `protobuf:"bytes,2,opt,name=license_name,json=licenseName,proto3" json:"license_name,omitempty"` + // LicenseUrl is a URL to the license on the internet. + LicenseUrl string `protobuf:"bytes,3,opt,name=license_url,json=licenseUrl,proto3" json:"license_url,omitempty"` + // LicensePath is a path to the file that contains the text of the license. + LicensePath string `protobuf:"bytes,4,opt,name=license_path,json=licensePath,proto3" json:"license_path,omitempty"` + // LicenseNickname is a shortened full name for better readability. + // It exists only for a small set of licenses and an empty value is returned in most cases. + LicenseNickname string `protobuf:"bytes,5,opt,name=license_nickname,json=licenseNickname,proto3" json:"license_nickname,omitempty"` } func (x *FindLicenseResponse) Reset() { *x = FindLicenseResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[53] + mi := &file_repository_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2945,7 +3074,7 @@ func (x *FindLicenseResponse) String() string { func (*FindLicenseResponse) ProtoMessage() {} func (x *FindLicenseResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[53] + mi := &file_repository_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2958,7 +3087,7 @@ func (x *FindLicenseResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindLicenseResponse.ProtoReflect.Descriptor instead. func (*FindLicenseResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{53} + return file_repository_proto_rawDescGZIP(), []int{53} } func (x *FindLicenseResponse) GetLicenseShortName() string { @@ -2968,18 +3097,48 @@ func (x *FindLicenseResponse) GetLicenseShortName() string { return "" } +func (x *FindLicenseResponse) GetLicenseName() string { + if x != nil { + return x.LicenseName + } + return "" +} + +func (x *FindLicenseResponse) GetLicenseUrl() string { + if x != nil { + return x.LicenseUrl + } + return "" +} + +func (x *FindLicenseResponse) GetLicensePath() string { + if x != nil { + return x.LicensePath + } + return "" +} + +func (x *FindLicenseResponse) GetLicenseNickname() string { + if x != nil { + return x.LicenseNickname + } + return "" +} + +// This comment is left unintentionally blank. type GetInfoAttributesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *GetInfoAttributesRequest) Reset() { *x = GetInfoAttributesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[54] + mi := &file_repository_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2992,7 +3151,7 @@ func (x *GetInfoAttributesRequest) String() string { func (*GetInfoAttributesRequest) ProtoMessage() {} func (x *GetInfoAttributesRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[54] + mi := &file_repository_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3005,7 +3164,7 @@ func (x *GetInfoAttributesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetInfoAttributesRequest.ProtoReflect.Descriptor instead. func (*GetInfoAttributesRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{54} + return file_repository_proto_rawDescGZIP(), []int{54} } func (x *GetInfoAttributesRequest) GetRepository() *Repository { @@ -3015,18 +3174,20 @@ func (x *GetInfoAttributesRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type GetInfoAttributesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Attributes []byte `protobuf:"bytes,1,opt,name=attributes,proto3" json:"attributes,omitempty"` } func (x *GetInfoAttributesResponse) Reset() { *x = GetInfoAttributesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[55] + mi := &file_repository_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3039,7 +3200,7 @@ func (x *GetInfoAttributesResponse) String() string { func (*GetInfoAttributesResponse) ProtoMessage() {} func (x *GetInfoAttributesResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[55] + mi := &file_repository_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3052,7 +3213,7 @@ func (x *GetInfoAttributesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetInfoAttributesResponse.ProtoReflect.Descriptor instead. func (*GetInfoAttributesResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{55} + return file_repository_proto_rawDescGZIP(), []int{55} } func (x *GetInfoAttributesResponse) GetAttributes() []byte { @@ -3062,18 +3223,20 @@ func (x *GetInfoAttributesResponse) GetAttributes() []byte { return nil } +// This comment is left unintentionally blank. type CalculateChecksumRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *CalculateChecksumRequest) Reset() { *x = CalculateChecksumRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[56] + mi := &file_repository_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3086,7 +3249,7 @@ func (x *CalculateChecksumRequest) String() string { func (*CalculateChecksumRequest) ProtoMessage() {} func (x *CalculateChecksumRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[56] + mi := &file_repository_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3099,7 +3262,7 @@ func (x *CalculateChecksumRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CalculateChecksumRequest.ProtoReflect.Descriptor instead. func (*CalculateChecksumRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{56} + return file_repository_proto_rawDescGZIP(), []int{56} } func (x *CalculateChecksumRequest) GetRepository() *Repository { @@ -3109,18 +3272,20 @@ func (x *CalculateChecksumRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type CalculateChecksumResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Checksum string `protobuf:"bytes,1,opt,name=checksum,proto3" json:"checksum,omitempty"` } func (x *CalculateChecksumResponse) Reset() { *x = CalculateChecksumResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[57] + mi := &file_repository_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3133,7 +3298,7 @@ func (x *CalculateChecksumResponse) String() string { func (*CalculateChecksumResponse) ProtoMessage() {} func (x *CalculateChecksumResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[57] + mi := &file_repository_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3146,7 +3311,7 @@ func (x *CalculateChecksumResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CalculateChecksumResponse.ProtoReflect.Descriptor instead. func (*CalculateChecksumResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{57} + return file_repository_proto_rawDescGZIP(), []int{57} } func (x *CalculateChecksumResponse) GetChecksum() string { @@ -3156,18 +3321,20 @@ func (x *CalculateChecksumResponse) GetChecksum() string { return "" } +// This comment is left unintentionally blank. type GetSnapshotRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *GetSnapshotRequest) Reset() { *x = GetSnapshotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[58] + mi := &file_repository_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3180,7 +3347,7 @@ func (x *GetSnapshotRequest) String() string { func (*GetSnapshotRequest) ProtoMessage() {} func (x *GetSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[58] + mi := &file_repository_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3193,7 +3360,7 @@ func (x *GetSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSnapshotRequest.ProtoReflect.Descriptor instead. func (*GetSnapshotRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{58} + return file_repository_proto_rawDescGZIP(), []int{58} } func (x *GetSnapshotRequest) GetRepository() *Repository { @@ -3203,18 +3370,20 @@ func (x *GetSnapshotRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type GetSnapshotResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } func (x *GetSnapshotResponse) Reset() { *x = GetSnapshotResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[59] + mi := &file_repository_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3227,7 +3396,7 @@ func (x *GetSnapshotResponse) String() string { func (*GetSnapshotResponse) ProtoMessage() {} func (x *GetSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[59] + mi := &file_repository_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3240,7 +3409,7 @@ func (x *GetSnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSnapshotResponse.ProtoReflect.Descriptor instead. func (*GetSnapshotResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{59} + return file_repository_proto_rawDescGZIP(), []int{59} } func (x *GetSnapshotResponse) GetData() []byte { @@ -3250,14 +3419,18 @@ func (x *GetSnapshotResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type CreateRepositoryFromSnapshotRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - HttpUrl string `protobuf:"bytes,2,opt,name=http_url,json=httpUrl,proto3" json:"http_url,omitempty"` - HttpAuth string `protobuf:"bytes,3,opt,name=http_auth,json=httpAuth,proto3" json:"http_auth,omitempty"` + // This comment is left unintentionally blank. + HttpUrl string `protobuf:"bytes,2,opt,name=http_url,json=httpUrl,proto3" json:"http_url,omitempty"` + // This comment is left unintentionally blank. + HttpAuth string `protobuf:"bytes,3,opt,name=http_auth,json=httpAuth,proto3" json:"http_auth,omitempty"` // HttpHost is the hostname of the remote snapshot. Use this when the // URL hostname has already been resolved to an IP address to prevent DNS // rebinding. @@ -3267,7 +3440,7 @@ type CreateRepositoryFromSnapshotRequest struct { func (x *CreateRepositoryFromSnapshotRequest) Reset() { *x = CreateRepositoryFromSnapshotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[60] + mi := &file_repository_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3280,7 +3453,7 @@ func (x *CreateRepositoryFromSnapshotRequest) String() string { func (*CreateRepositoryFromSnapshotRequest) ProtoMessage() {} func (x *CreateRepositoryFromSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[60] + mi := &file_repository_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3293,7 +3466,7 @@ func (x *CreateRepositoryFromSnapshotRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use CreateRepositoryFromSnapshotRequest.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromSnapshotRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{60} + return file_repository_proto_rawDescGZIP(), []int{60} } func (x *CreateRepositoryFromSnapshotRequest) GetRepository() *Repository { @@ -3324,6 +3497,7 @@ func (x *CreateRepositoryFromSnapshotRequest) GetHttpHost() string { return "" } +// This comment is left unintentionally blank. type CreateRepositoryFromSnapshotResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3333,7 +3507,7 @@ type CreateRepositoryFromSnapshotResponse struct { func (x *CreateRepositoryFromSnapshotResponse) Reset() { *x = CreateRepositoryFromSnapshotResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[61] + mi := &file_repository_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3346,7 +3520,7 @@ func (x *CreateRepositoryFromSnapshotResponse) String() string { func (*CreateRepositoryFromSnapshotResponse) ProtoMessage() {} func (x *CreateRepositoryFromSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[61] + mi := &file_repository_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3359,23 +3533,27 @@ func (x *CreateRepositoryFromSnapshotResponse) ProtoReflect() protoreflect.Messa // Deprecated: Use CreateRepositoryFromSnapshotResponse.ProtoReflect.Descriptor instead. func (*CreateRepositoryFromSnapshotResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{61} + return file_repository_proto_rawDescGZIP(), []int{61} } +// This comment is left unintentionally blank. type GetRawChangesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - FromRevision string `protobuf:"bytes,2,opt,name=from_revision,json=fromRevision,proto3" json:"from_revision,omitempty"` - ToRevision string `protobuf:"bytes,3,opt,name=to_revision,json=toRevision,proto3" json:"to_revision,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + FromRevision string `protobuf:"bytes,2,opt,name=from_revision,json=fromRevision,proto3" json:"from_revision,omitempty"` + // This comment is left unintentionally blank. + ToRevision string `protobuf:"bytes,3,opt,name=to_revision,json=toRevision,proto3" json:"to_revision,omitempty"` } func (x *GetRawChangesRequest) Reset() { *x = GetRawChangesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[62] + mi := &file_repository_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3388,7 +3566,7 @@ func (x *GetRawChangesRequest) String() string { func (*GetRawChangesRequest) ProtoMessage() {} func (x *GetRawChangesRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[62] + mi := &file_repository_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3401,7 +3579,7 @@ func (x *GetRawChangesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRawChangesRequest.ProtoReflect.Descriptor instead. func (*GetRawChangesRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{62} + return file_repository_proto_rawDescGZIP(), []int{62} } func (x *GetRawChangesRequest) GetRepository() *Repository { @@ -3425,18 +3603,20 @@ func (x *GetRawChangesRequest) GetToRevision() string { return "" } +// This comment is left unintentionally blank. type GetRawChangesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. RawChanges []*GetRawChangesResponse_RawChange `protobuf:"bytes,1,rep,name=raw_changes,json=rawChanges,proto3" json:"raw_changes,omitempty"` } func (x *GetRawChangesResponse) Reset() { *x = GetRawChangesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[63] + mi := &file_repository_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3449,7 +3629,7 @@ func (x *GetRawChangesResponse) String() string { func (*GetRawChangesResponse) ProtoMessage() {} func (x *GetRawChangesResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[63] + mi := &file_repository_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3462,7 +3642,7 @@ func (x *GetRawChangesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRawChangesResponse.ProtoReflect.Descriptor instead. func (*GetRawChangesResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{63} + return file_repository_proto_rawDescGZIP(), []int{63} } func (x *GetRawChangesResponse) GetRawChanges() []*GetRawChangesResponse_RawChange { @@ -3472,14 +3652,18 @@ func (x *GetRawChangesResponse) GetRawChanges() []*GetRawChangesResponse_RawChan return nil } +// This comment is left unintentionally blank. type SearchFilesByNameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` + // This comment is left unintentionally blank. + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + // This comment is left unintentionally blank. + Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` // If `filter` is specified and non-empty, it will be parsed as a regular // expression and used to filter the result set before it is transmitted. It is // parsed using Go's `regexp` package, which is closely related to PCRE, @@ -3491,7 +3675,7 @@ type SearchFilesByNameRequest struct { func (x *SearchFilesByNameRequest) Reset() { *x = SearchFilesByNameRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[64] + mi := &file_repository_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3504,7 +3688,7 @@ func (x *SearchFilesByNameRequest) String() string { func (*SearchFilesByNameRequest) ProtoMessage() {} func (x *SearchFilesByNameRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[64] + mi := &file_repository_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3517,7 +3701,7 @@ func (x *SearchFilesByNameRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchFilesByNameRequest.ProtoReflect.Descriptor instead. func (*SearchFilesByNameRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{64} + return file_repository_proto_rawDescGZIP(), []int{64} } func (x *SearchFilesByNameRequest) GetRepository() *Repository { @@ -3548,18 +3732,20 @@ func (x *SearchFilesByNameRequest) GetFilter() string { return "" } +// This comment is left unintentionally blank. type SearchFilesByNameResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Files [][]byte `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` } func (x *SearchFilesByNameResponse) Reset() { *x = SearchFilesByNameResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[65] + mi := &file_repository_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3572,7 +3758,7 @@ func (x *SearchFilesByNameResponse) String() string { func (*SearchFilesByNameResponse) ProtoMessage() {} func (x *SearchFilesByNameResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[65] + mi := &file_repository_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3585,7 +3771,7 @@ func (x *SearchFilesByNameResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchFilesByNameResponse.ProtoReflect.Descriptor instead. func (*SearchFilesByNameResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{65} + return file_repository_proto_rawDescGZIP(), []int{65} } func (x *SearchFilesByNameResponse) GetFiles() [][]byte { @@ -3595,21 +3781,26 @@ func (x *SearchFilesByNameResponse) GetFiles() [][]byte { return nil } +// This comment is left unintentionally blank. type SearchFilesByContentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` - ChunkedResponse bool `protobuf:"varint,4,opt,name=chunked_response,json=chunkedResponse,proto3" json:"chunked_response,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + // This comment is left unintentionally blank. + Ref []byte `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"` + // This comment is left unintentionally blank. + ChunkedResponse bool `protobuf:"varint,4,opt,name=chunked_response,json=chunkedResponse,proto3" json:"chunked_response,omitempty"` } func (x *SearchFilesByContentRequest) Reset() { *x = SearchFilesByContentRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[66] + mi := &file_repository_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3622,7 +3813,7 @@ func (x *SearchFilesByContentRequest) String() string { func (*SearchFilesByContentRequest) ProtoMessage() {} func (x *SearchFilesByContentRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[66] + mi := &file_repository_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3635,7 +3826,7 @@ func (x *SearchFilesByContentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchFilesByContentRequest.ProtoReflect.Descriptor instead. func (*SearchFilesByContentRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{66} + return file_repository_proto_rawDescGZIP(), []int{66} } func (x *SearchFilesByContentRequest) GetRepository() *Repository { @@ -3666,20 +3857,24 @@ func (x *SearchFilesByContentRequest) GetChunkedResponse() bool { return false } +// This comment is left unintentionally blank. type SearchFilesByContentResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Matches [][]byte `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` - MatchData []byte `protobuf:"bytes,2,opt,name=match_data,json=matchData,proto3" json:"match_data,omitempty"` - EndOfMatch bool `protobuf:"varint,3,opt,name=end_of_match,json=endOfMatch,proto3" json:"end_of_match,omitempty"` + // This comment is left unintentionally blank. + Matches [][]byte `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` + // This comment is left unintentionally blank. + MatchData []byte `protobuf:"bytes,2,opt,name=match_data,json=matchData,proto3" json:"match_data,omitempty"` + // This comment is left unintentionally blank. + EndOfMatch bool `protobuf:"varint,3,opt,name=end_of_match,json=endOfMatch,proto3" json:"end_of_match,omitempty"` } func (x *SearchFilesByContentResponse) Reset() { *x = SearchFilesByContentResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[67] + mi := &file_repository_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3692,7 +3887,7 @@ func (x *SearchFilesByContentResponse) String() string { func (*SearchFilesByContentResponse) ProtoMessage() {} func (x *SearchFilesByContentResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[67] + mi := &file_repository_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3705,7 +3900,7 @@ func (x *SearchFilesByContentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchFilesByContentResponse.ProtoReflect.Descriptor instead. func (*SearchFilesByContentResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{67} + return file_repository_proto_rawDescGZIP(), []int{67} } func (x *SearchFilesByContentResponse) GetMatches() [][]byte { @@ -3761,7 +3956,7 @@ type Remote struct { func (x *Remote) Reset() { *x = Remote{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[68] + mi := &file_repository_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3774,7 +3969,7 @@ func (x *Remote) String() string { func (*Remote) ProtoMessage() {} func (x *Remote) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[68] + mi := &file_repository_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3787,7 +3982,7 @@ func (x *Remote) ProtoReflect() protoreflect.Message { // Deprecated: Use Remote.ProtoReflect.Descriptor instead. func (*Remote) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{68} + return file_repository_proto_rawDescGZIP(), []int{68} } func (x *Remote) GetUrl() string { @@ -3818,18 +4013,20 @@ func (x *Remote) GetHttpHost() string { return "" } +// This comment is left unintentionally blank. type GetObjectDirectorySizeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *GetObjectDirectorySizeRequest) Reset() { *x = GetObjectDirectorySizeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[69] + mi := &file_repository_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3842,7 +4039,7 @@ func (x *GetObjectDirectorySizeRequest) String() string { func (*GetObjectDirectorySizeRequest) ProtoMessage() {} func (x *GetObjectDirectorySizeRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[69] + mi := &file_repository_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3855,7 +4052,7 @@ func (x *GetObjectDirectorySizeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetObjectDirectorySizeRequest.ProtoReflect.Descriptor instead. func (*GetObjectDirectorySizeRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{69} + return file_repository_proto_rawDescGZIP(), []int{69} } func (x *GetObjectDirectorySizeRequest) GetRepository() *Repository { @@ -3865,6 +4062,7 @@ func (x *GetObjectDirectorySizeRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type GetObjectDirectorySizeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3877,7 +4075,7 @@ type GetObjectDirectorySizeResponse struct { func (x *GetObjectDirectorySizeResponse) Reset() { *x = GetObjectDirectorySizeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[70] + mi := &file_repository_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3890,7 +4088,7 @@ func (x *GetObjectDirectorySizeResponse) String() string { func (*GetObjectDirectorySizeResponse) ProtoMessage() {} func (x *GetObjectDirectorySizeResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[70] + mi := &file_repository_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3903,7 +4101,7 @@ func (x *GetObjectDirectorySizeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetObjectDirectorySizeResponse.ProtoReflect.Descriptor instead. func (*GetObjectDirectorySizeResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{70} + return file_repository_proto_rawDescGZIP(), []int{70} } func (x *GetObjectDirectorySizeResponse) GetSize() int64 { @@ -3913,18 +4111,20 @@ func (x *GetObjectDirectorySizeResponse) GetSize() int64 { return 0 } +// This comment is left unintentionally blank. type RemoveRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *RemoveRepositoryRequest) Reset() { *x = RemoveRepositoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[71] + mi := &file_repository_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3937,7 +4137,7 @@ func (x *RemoveRepositoryRequest) String() string { func (*RemoveRepositoryRequest) ProtoMessage() {} func (x *RemoveRepositoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[71] + mi := &file_repository_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3950,7 +4150,7 @@ func (x *RemoveRepositoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveRepositoryRequest.ProtoReflect.Descriptor instead. func (*RemoveRepositoryRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{71} + return file_repository_proto_rawDescGZIP(), []int{71} } func (x *RemoveRepositoryRequest) GetRepository() *Repository { @@ -3960,6 +4160,7 @@ func (x *RemoveRepositoryRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type RemoveRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3969,7 +4170,7 @@ type RemoveRepositoryResponse struct { func (x *RemoveRepositoryResponse) Reset() { *x = RemoveRepositoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[72] + mi := &file_repository_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3982,7 +4183,7 @@ func (x *RemoveRepositoryResponse) String() string { func (*RemoveRepositoryResponse) ProtoMessage() {} func (x *RemoveRepositoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[72] + mi := &file_repository_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3995,22 +4196,25 @@ func (x *RemoveRepositoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveRepositoryResponse.ProtoReflect.Descriptor instead. func (*RemoveRepositoryResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{72} + return file_repository_proto_rawDescGZIP(), []int{72} } +// This comment is left unintentionally blank. type RenameRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - RelativePath string `protobuf:"bytes,2,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` + // This comment is left unintentionally blank. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + RelativePath string `protobuf:"bytes,2,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` } func (x *RenameRepositoryRequest) Reset() { *x = RenameRepositoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[73] + mi := &file_repository_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4023,7 +4227,7 @@ func (x *RenameRepositoryRequest) String() string { func (*RenameRepositoryRequest) ProtoMessage() {} func (x *RenameRepositoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[73] + mi := &file_repository_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4036,7 +4240,7 @@ func (x *RenameRepositoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RenameRepositoryRequest.ProtoReflect.Descriptor instead. func (*RenameRepositoryRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{73} + return file_repository_proto_rawDescGZIP(), []int{73} } func (x *RenameRepositoryRequest) GetRepository() *Repository { @@ -4053,6 +4257,7 @@ func (x *RenameRepositoryRequest) GetRelativePath() string { return "" } +// This comment is left unintentionally blank. type RenameRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4062,7 +4267,7 @@ type RenameRepositoryResponse struct { func (x *RenameRepositoryResponse) Reset() { *x = RenameRepositoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[74] + mi := &file_repository_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4075,7 +4280,7 @@ func (x *RenameRepositoryResponse) String() string { func (*RenameRepositoryResponse) ProtoMessage() {} func (x *RenameRepositoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[74] + mi := &file_repository_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4088,22 +4293,25 @@ func (x *RenameRepositoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RenameRepositoryResponse.ProtoReflect.Descriptor instead. func (*RenameRepositoryResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{74} + return file_repository_proto_rawDescGZIP(), []int{74} } +// This comment is left unintentionally blank. type ReplicateRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Source *Repository `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + // This comment is left unintentionally blank. + Source *Repository `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` } func (x *ReplicateRepositoryRequest) Reset() { *x = ReplicateRepositoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[75] + mi := &file_repository_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4116,7 +4324,7 @@ func (x *ReplicateRepositoryRequest) String() string { func (*ReplicateRepositoryRequest) ProtoMessage() {} func (x *ReplicateRepositoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[75] + mi := &file_repository_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4129,7 +4337,7 @@ func (x *ReplicateRepositoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReplicateRepositoryRequest.ProtoReflect.Descriptor instead. func (*ReplicateRepositoryRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{75} + return file_repository_proto_rawDescGZIP(), []int{75} } func (x *ReplicateRepositoryRequest) GetRepository() *Repository { @@ -4146,6 +4354,7 @@ func (x *ReplicateRepositoryRequest) GetSource() *Repository { return nil } +// This comment is left unintentionally blank. type ReplicateRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4155,7 +4364,7 @@ type ReplicateRepositoryResponse struct { func (x *ReplicateRepositoryResponse) Reset() { *x = ReplicateRepositoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[76] + mi := &file_repository_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4168,7 +4377,7 @@ func (x *ReplicateRepositoryResponse) String() string { func (*ReplicateRepositoryResponse) ProtoMessage() {} func (x *ReplicateRepositoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[76] + mi := &file_repository_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4181,21 +4390,23 @@ func (x *ReplicateRepositoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReplicateRepositoryResponse.ProtoReflect.Descriptor instead. func (*ReplicateRepositoryResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{76} + return file_repository_proto_rawDescGZIP(), []int{76} } +// This comment is left unintentionally blank. type OptimizeRepositoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *OptimizeRepositoryRequest) Reset() { *x = OptimizeRepositoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[77] + mi := &file_repository_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4208,7 +4419,7 @@ func (x *OptimizeRepositoryRequest) String() string { func (*OptimizeRepositoryRequest) ProtoMessage() {} func (x *OptimizeRepositoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[77] + mi := &file_repository_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4221,7 +4432,7 @@ func (x *OptimizeRepositoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OptimizeRepositoryRequest.ProtoReflect.Descriptor instead. func (*OptimizeRepositoryRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{77} + return file_repository_proto_rawDescGZIP(), []int{77} } func (x *OptimizeRepositoryRequest) GetRepository() *Repository { @@ -4231,6 +4442,7 @@ func (x *OptimizeRepositoryRequest) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type OptimizeRepositoryResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4240,7 +4452,7 @@ type OptimizeRepositoryResponse struct { func (x *OptimizeRepositoryResponse) Reset() { *x = OptimizeRepositoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[78] + mi := &file_repository_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4253,7 +4465,7 @@ func (x *OptimizeRepositoryResponse) String() string { func (*OptimizeRepositoryResponse) ProtoMessage() {} func (x *OptimizeRepositoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[78] + mi := &file_repository_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4266,7 +4478,7 @@ func (x *OptimizeRepositoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OptimizeRepositoryResponse.ProtoReflect.Descriptor instead. func (*OptimizeRepositoryResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{78} + return file_repository_proto_rawDescGZIP(), []int{78} } // PruneUnreachableObjectsRequest is a request for the PruneUnreachableObjects @@ -4276,13 +4488,14 @@ type PruneUnreachableObjectsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *PruneUnreachableObjectsRequest) Reset() { *x = PruneUnreachableObjectsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[79] + mi := &file_repository_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4295,7 +4508,7 @@ func (x *PruneUnreachableObjectsRequest) String() string { func (*PruneUnreachableObjectsRequest) ProtoMessage() {} func (x *PruneUnreachableObjectsRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[79] + mi := &file_repository_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4308,7 +4521,7 @@ func (x *PruneUnreachableObjectsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PruneUnreachableObjectsRequest.ProtoReflect.Descriptor instead. func (*PruneUnreachableObjectsRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{79} + return file_repository_proto_rawDescGZIP(), []int{79} } func (x *PruneUnreachableObjectsRequest) GetRepository() *Repository { @@ -4329,7 +4542,7 @@ type PruneUnreachableObjectsResponse struct { func (x *PruneUnreachableObjectsResponse) Reset() { *x = PruneUnreachableObjectsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[80] + mi := &file_repository_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4342,7 +4555,7 @@ func (x *PruneUnreachableObjectsResponse) String() string { func (*PruneUnreachableObjectsResponse) ProtoMessage() {} func (x *PruneUnreachableObjectsResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[80] + mi := &file_repository_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4355,7 +4568,7 @@ func (x *PruneUnreachableObjectsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PruneUnreachableObjectsResponse.ProtoReflect.Descriptor instead. func (*PruneUnreachableObjectsResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{80} + return file_repository_proto_rawDescGZIP(), []int{80} } // SetFullPathRequest is a request for the SetFullPath RPC. @@ -4373,7 +4586,7 @@ type SetFullPathRequest struct { func (x *SetFullPathRequest) Reset() { *x = SetFullPathRequest{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[81] + mi := &file_repository_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4386,7 +4599,7 @@ func (x *SetFullPathRequest) String() string { func (*SetFullPathRequest) ProtoMessage() {} func (x *SetFullPathRequest) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[81] + mi := &file_repository_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4399,7 +4612,7 @@ func (x *SetFullPathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetFullPathRequest.ProtoReflect.Descriptor instead. func (*SetFullPathRequest) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{81} + return file_repository_proto_rawDescGZIP(), []int{81} } func (x *SetFullPathRequest) GetRepository() *Repository { @@ -4426,7 +4639,7 @@ type SetFullPathResponse struct { func (x *SetFullPathResponse) Reset() { *x = SetFullPathResponse{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[82] + mi := &file_repository_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4439,7 +4652,7 @@ func (x *SetFullPathResponse) String() string { func (*SetFullPathResponse) ProtoMessage() {} func (x *SetFullPathResponse) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[82] + mi := &file_repository_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4452,29 +4665,135 @@ func (x *SetFullPathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetFullPathResponse.ProtoReflect.Descriptor instead. func (*SetFullPathResponse) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{82} + return file_repository_proto_rawDescGZIP(), []int{82} } +// FullPathRequest is a request for the FullPath RPC. +type FullPathRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Repository is the repository whose gitconfig should be read. + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` +} + +func (x *FullPathRequest) Reset() { + *x = FullPathRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_repository_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FullPathRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FullPathRequest) ProtoMessage() {} + +func (x *FullPathRequest) ProtoReflect() protoreflect.Message { + mi := &file_repository_proto_msgTypes[83] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FullPathRequest.ProtoReflect.Descriptor instead. +func (*FullPathRequest) Descriptor() ([]byte, []int) { + return file_repository_proto_rawDescGZIP(), []int{83} +} + +func (x *FullPathRequest) GetRepository() *Repository { + if x != nil { + return x.Repository + } + return nil +} + +// SetFullPathResponse is a response for the SetFullPath RPC. +type FullPathResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path read from the "gitlab.fullpath" config key. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *FullPathResponse) Reset() { + *x = FullPathResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_repository_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FullPathResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FullPathResponse) ProtoMessage() {} + +func (x *FullPathResponse) ProtoReflect() protoreflect.Message { + mi := &file_repository_proto_msgTypes[84] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FullPathResponse.ProtoReflect.Descriptor instead. +func (*FullPathResponse) Descriptor() ([]byte, []int) { + return file_repository_proto_rawDescGZIP(), []int{84} +} + +func (x *FullPathResponse) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +// This comment is left unintentionally blank. type GetRawChangesResponse_RawChange struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - BlobId string `protobuf:"bytes,1,opt,name=blob_id,json=blobId,proto3" json:"blob_id,omitempty"` - Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` - Operation GetRawChangesResponse_RawChange_Operation `protobuf:"varint,5,opt,name=operation,proto3,enum=gitaly.GetRawChangesResponse_RawChange_Operation" json:"operation,omitempty"` - RawOperation string `protobuf:"bytes,6,opt,name=raw_operation,json=rawOperation,proto3" json:"raw_operation,omitempty"` - OldMode int32 `protobuf:"varint,7,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` - NewMode int32 `protobuf:"varint,8,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` + // This comment is left unintentionally blank. + BlobId string `protobuf:"bytes,1,opt,name=blob_id,json=blobId,proto3" json:"blob_id,omitempty"` + // This comment is left unintentionally blank. + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + // This comment is left unintentionally blank. + Operation GetRawChangesResponse_RawChange_Operation `protobuf:"varint,5,opt,name=operation,proto3,enum=gitaly.GetRawChangesResponse_RawChange_Operation" json:"operation,omitempty"` + // This comment is left unintentionally blank. + RawOperation string `protobuf:"bytes,6,opt,name=raw_operation,json=rawOperation,proto3" json:"raw_operation,omitempty"` + // This comment is left unintentionally blank. + OldMode int32 `protobuf:"varint,7,opt,name=old_mode,json=oldMode,proto3" json:"old_mode,omitempty"` + // This comment is left unintentionally blank. + NewMode int32 `protobuf:"varint,8,opt,name=new_mode,json=newMode,proto3" json:"new_mode,omitempty"` // the following fields, 9 and 10, will eventually replace 3 and 4 NewPathBytes []byte `protobuf:"bytes,9,opt,name=new_path_bytes,json=newPathBytes,proto3" json:"new_path_bytes,omitempty"` + // This comment is left unintentionally blank. OldPathBytes []byte `protobuf:"bytes,10,opt,name=old_path_bytes,json=oldPathBytes,proto3" json:"old_path_bytes,omitempty"` } func (x *GetRawChangesResponse_RawChange) Reset() { *x = GetRawChangesResponse_RawChange{} if protoimpl.UnsafeEnabled { - mi := &file_repository_service_proto_msgTypes[83] + mi := &file_repository_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4487,7 +4806,7 @@ func (x *GetRawChangesResponse_RawChange) String() string { func (*GetRawChangesResponse_RawChange) ProtoMessage() {} func (x *GetRawChangesResponse_RawChange) ProtoReflect() protoreflect.Message { - mi := &file_repository_service_proto_msgTypes[83] + mi := &file_repository_proto_msgTypes[85] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4500,7 +4819,7 @@ func (x *GetRawChangesResponse_RawChange) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRawChangesResponse_RawChange.ProtoReflect.Descriptor instead. func (*GetRawChangesResponse_RawChange) Descriptor() ([]byte, []int) { - return file_repository_service_proto_rawDescGZIP(), []int{63, 0} + return file_repository_proto_rawDescGZIP(), []int{63, 0} } func (x *GetRawChangesResponse_RawChange) GetBlobId() string { @@ -4559,491 +4878,507 @@ func (x *GetRawChangesResponse_RawChange) GetOldPathBytes() []byte { return nil } -var File_repository_service_proto protoreflect.FileDescriptor +var File_repository_proto protoreflect.FileDescriptor -var file_repository_service_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x53, 0x0a, 0x17, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x22, 0x32, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x45, - 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, - 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x49, - 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x1b, 0x0a, 0x19, 0x52, - 0x65, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x61, - 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x5f, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x22, 0x14, 0x0a, 0x12, - 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x11, 0x4d, 0x69, 0x64, 0x78, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x22, 0x14, 0x0a, 0x12, 0x4d, 0x69, 0x64, 0x78, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8c, 0x01, 0x0a, 0x15, 0x47, 0x61, 0x72, 0x62, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, - 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x75, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x70, 0x72, 0x75, 0x6e, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x61, 0x72, 0x62, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xcb, 0x01, 0x0a, 0x17, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x53, 0x0a, 0x0d, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, - 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x21, 0x0a, 0x0d, 0x53, - 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x10, 0x0a, 0x0c, - 0x53, 0x69, 0x7a, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x10, 0x00, 0x22, 0x1a, - 0x0a, 0x18, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x47, 0x72, 0x61, - 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x0a, 0x0e, 0x43, 0x6c, - 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x15, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x71, 0x0a, 0x19, 0x41, 0x70, - 0x70, 0x6c, 0x79, 0x47, 0x69, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, - 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x69, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x12, - 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x65, 0x61, - 0x64, 0x22, 0x15, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe3, 0x02, 0x0a, 0x12, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, +var file_repository_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x53, 0x0a, 0x17, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x6e, 0x6f, 0x54, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x75, 0x6e, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x6e, 0x6f, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x0c, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x54, - 0x61, 0x67, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x22, 0x38, - 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x74, 0x61, 0x67, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x7a, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, - 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xea, 0x02, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, - 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x38, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x65, 0x6c, 0x69, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x65, 0x6c, 0x69, 0x64, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x66, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x62, - 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x4c, 0x66, 0x73, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x33, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x12, 0x07, 0x0a, 0x03, 0x5a, 0x49, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, - 0x41, 0x52, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x52, 0x5f, 0x47, 0x5a, 0x10, 0x02, - 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x41, 0x52, 0x5f, 0x42, 0x5a, 0x32, 0x10, 0x03, 0x22, 0x28, 0x0a, - 0x12, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, 0x17, 0x48, 0x61, 0x73, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x30, 0x0a, 0x18, - 0x48, 0x61, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd9, - 0x01, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3f, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x22, 0x33, 0x0a, 0x19, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0x47, 0x0a, 0x0b, 0x46, 0x73, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x24, 0x0a, 0x0c, 0x46, 0x73, 0x63, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xb8, - 0x01, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x6c, - 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x18, 0x0a, 0x10, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4a, 0x04, 0x08, - 0x01, 0x10, 0x02, 0x22, 0x6e, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x2b, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, - 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, - 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x3f, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x22, 0x14, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, - 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, - 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, - 0x6f, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x19, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, - 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x55, - 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x13, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2a, 0x0a, 0x14, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x76, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x66, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x32, 0x0a, 0x18, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x54, 0x0a, + 0x18, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x22, - 0x35, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, - 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x6f, 0x72, 0x79, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x63, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x72, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x69, + 0x74, 0x6d, 0x61, 0x70, 0x22, 0x14, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x46, 0x75, + 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x11, 0x4d, 0x69, + 0x64, 0x78, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x14, 0x0a, 0x12, 0x4d, 0x69, 0x64, + 0x78, 0x52, 0x65, 0x70, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x8c, 0x01, 0x0a, 0x15, 0x47, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x69, + 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x75, 0x6e, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x70, 0x72, 0x75, 0x6e, 0x65, 0x22, 0x18, + 0x0a, 0x16, 0x47, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x17, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x53, + 0x0a, 0x0d, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x22, 0x21, 0x0a, 0x0d, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x79, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x69, 0x7a, 0x65, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x70, 0x6c, 0x65, 0x10, 0x00, 0x22, 0x1a, 0x0a, 0x18, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x4a, 0x0a, 0x0e, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x11, + 0x0a, 0x0f, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x51, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, + 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x22, 0x27, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, - 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, - 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2c, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x22, 0x71, 0x0a, 0x19, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x69, 0x74, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x47, 0x69, + 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x18, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x65, 0x61, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xe3, 0x02, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, + 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x5f, 0x74, 0x61, + 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6e, 0x6f, 0x54, 0x61, 0x67, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, + 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, + 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x68, 0x6f, 0x73, + 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x48, + 0x6f, 0x73, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x75, 0x6e, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, 0x6f, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, + 0x33, 0x0a, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x74, 0x61, + 0x67, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x61, 0x67, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x22, 0x38, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x74, 0x61, 0x67, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x22, 0x7a, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0x1a, 0x0a, 0x18, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xea, 0x02, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x38, 0x0a, + 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, + 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6c, 0x69, 0x64, 0x65, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x6c, 0x69, 0x64, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x6c, 0x66, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x66, 0x73, 0x42, 0x6c, 0x6f, 0x62, 0x73, + 0x22, 0x33, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x07, 0x0a, 0x03, 0x5a, 0x49, + 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x52, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, + 0x54, 0x41, 0x52, 0x5f, 0x47, 0x5a, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x41, 0x52, 0x5f, + 0x42, 0x5a, 0x32, 0x10, 0x03, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x53, 0x0a, 0x17, 0x48, 0x61, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0x30, 0x0a, 0x18, 0x48, 0x61, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd9, 0x01, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, 0x68, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, + 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3f, 0x0a, + 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x10, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, + 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, + 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, + 0x65, 0x66, 0x22, 0x33, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x47, 0x0a, 0x0b, 0x46, 0x73, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, + 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x22, 0x24, 0x0a, 0x0c, 0x46, 0x73, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xb8, 0x01, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x52, 0x65, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x06, 0x10, + 0x07, 0x22, 0x18, 0x0a, 0x10, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x66, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6e, 0x0a, 0x14, 0x46, + 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, + 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, + 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2b, 0x0a, 0x15, 0x46, + 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3f, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x14, 0x0a, 0x12, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xdd, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2f, 0x0a, 0x19, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71, 0x0a, - 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1b, + 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x19, 0x68, + 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, + 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x22, + 0x21, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x22, 0x2a, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x76, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x22, 0x35, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x66, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x4c, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x27, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x22, 0x24, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x43, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x69, 0x63, 0x65, 0x6e, - 0x73, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x54, 0x0a, 0x18, 0x47, - 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, + 0x0a, 0x18, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, + 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0x2f, 0x0a, 0x19, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x24, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, + 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, + 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xd5, + 0x01, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, + 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, + 0x63, 0x65, 0x6e, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x6c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x69, + 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x54, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x3b, 0x0a, 0x19, + 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x18, 0x43, 0x61, 0x6c, + 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, + 0x37, 0x0a, 0x19, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x73, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x22, 0x4e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x29, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0xb4, 0x01, 0x0a, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x74, 0x74, 0x70, 0x55, 0x72, 0x6c, + 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1b, 0x0a, + 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x26, 0x0a, 0x24, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, + 0x6f, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, + 0x6f, 0x6d, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, + 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x74, 0x6f, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x9f, 0x04, 0x0a, 0x15, + 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x1a, + 0xbb, 0x03, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x62, 0x6c, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x4f, 0x0a, 0x09, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x61, 0x77, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x61, 0x77, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, + 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, + 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, + 0x6e, 0x65, 0x77, 0x50, 0x61, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, + 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x22, 0x69, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, + 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x50, 0x49, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0b, + 0x0a, 0x07, 0x52, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x44, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x06, 0x4a, 0x04, 0x08, + 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x22, 0x94, 0x01, + 0x0a, 0x18, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, + 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x1b, 0x53, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x22, 0x3b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x54, - 0x0a, 0x18, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x73, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x22, 0x37, 0x0a, 0x19, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, - 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x22, 0x4e, 0x0a, - 0x12, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x29, 0x0a, - 0x13, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xb4, 0x01, 0x0a, 0x23, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, - 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x74, - 0x74, 0x70, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x74, - 0x74, 0x70, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, - 0x74, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x22, - 0x26, 0x0a, 0x24, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, - 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, - 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x9f, 0x04, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x72, 0x61, - 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x77, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, - 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x1a, 0xbb, 0x03, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, - 0x4f, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, - 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x52, 0x61, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x61, 0x77, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, 0x6f, 0x64, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, - 0x65, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, 0x64, 0x50, 0x61, - 0x74, 0x68, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x69, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x4f, 0x50, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x44, 0x10, 0x05, - 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, - 0x10, 0x06, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x08, - 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x22, 0x94, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, - 0x66, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0xaa, 0x01, 0x0a, - 0x1b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x29, - 0x0a, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x65, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x1c, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0c, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x4f, 0x66, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x22, 0xa6, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, - 0x6c, 0x12, 0x3a, 0x0a, 0x19, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x25, 0x0a, - 0x0e, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x6d, 0x61, 0x70, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x66, - 0x6d, 0x61, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, - 0x74, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x59, 0x0a, - 0x1d, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x34, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4f, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x68, 0x75, + 0x6e, 0x6b, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x1c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, + 0x0c, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x4f, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x22, + 0xa6, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x3a, 0x0a, 0x19, + 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x17, 0x68, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x69, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x6d, 0x61, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0d, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x66, 0x6d, 0x61, 0x70, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x4a, 0x04, 0x08, 0x02, + 0x10, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x59, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, - 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x53, - 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x78, 0x0a, 0x17, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x6f, 0x72, 0x79, 0x22, 0x34, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x53, 0x0a, 0x17, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, - 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2a, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x19, 0x4f, 0x70, 0x74, - 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x1a, + 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x17, 0x52, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x82, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x19, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x1c, 0x0a, 0x1a, 0x4f, + 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x0a, 0x1e, 0x50, 0x72, 0x75, + 0x6e, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x55, 0x6e, + 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x46, + 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x15, 0x0a, 0x13, + 0x53, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x0a, 0x0f, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x22, 0x1c, 0x0a, 0x1a, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, - 0x0a, 0x1e, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, - 0x6c, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, - 0x75, 0x6e, 0x65, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, - 0x12, 0x53, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, - 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x9c, 0x1e, 0x0a, 0x11, 0x52, 0x65, 0x70, + 0x22, 0x26, 0x0a, 0x10, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x32, 0xe3, 0x1e, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, @@ -5285,28 +5620,32 @@ var file_repository_service_proto_rawDesc = []byte{ 0x53, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, - 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x45, 0x0a, 0x08, 0x46, 0x75, 0x6c, 0x6c, 0x50, + 0x61, 0x74, 0x68, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x75, 0x6c, + 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, + 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, + 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, + 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_repository_service_proto_rawDescOnce sync.Once - file_repository_service_proto_rawDescData = file_repository_service_proto_rawDesc + file_repository_proto_rawDescOnce sync.Once + file_repository_proto_rawDescData = file_repository_proto_rawDesc ) -func file_repository_service_proto_rawDescGZIP() []byte { - file_repository_service_proto_rawDescOnce.Do(func() { - file_repository_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_repository_service_proto_rawDescData) +func file_repository_proto_rawDescGZIP() []byte { + file_repository_proto_rawDescOnce.Do(func() { + file_repository_proto_rawDescData = protoimpl.X.CompressGZIP(file_repository_proto_rawDescData) }) - return file_repository_service_proto_rawDescData + return file_repository_proto_rawDescData } -var file_repository_service_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_repository_service_proto_msgTypes = make([]protoimpl.MessageInfo, 84) -var file_repository_service_proto_goTypes = []interface{}{ +var file_repository_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_repository_proto_msgTypes = make([]protoimpl.MessageInfo, 86) +var file_repository_proto_goTypes = []interface{}{ (WriteCommitGraphRequest_SplitStrategy)(0), // 0: gitaly.WriteCommitGraphRequest.SplitStrategy (GetArchiveRequest_Format)(0), // 1: gitaly.GetArchiveRequest.Format (GetRawChangesResponse_RawChange_Operation)(0), // 2: gitaly.GetRawChangesResponse.RawChange.Operation @@ -5393,157 +5732,162 @@ var file_repository_service_proto_goTypes = []interface{}{ (*PruneUnreachableObjectsResponse)(nil), // 83: gitaly.PruneUnreachableObjectsResponse (*SetFullPathRequest)(nil), // 84: gitaly.SetFullPathRequest (*SetFullPathResponse)(nil), // 85: gitaly.SetFullPathResponse - (*GetRawChangesResponse_RawChange)(nil), // 86: gitaly.GetRawChangesResponse.RawChange - (*Repository)(nil), // 87: gitaly.Repository + (*FullPathRequest)(nil), // 86: gitaly.FullPathRequest + (*FullPathResponse)(nil), // 87: gitaly.FullPathResponse + (*GetRawChangesResponse_RawChange)(nil), // 88: gitaly.GetRawChangesResponse.RawChange + (*Repository)(nil), // 89: gitaly.Repository } -var file_repository_service_proto_depIdxs = []int32{ - 87, // 0: gitaly.RepositoryExistsRequest.repository:type_name -> gitaly.Repository - 87, // 1: gitaly.RepackIncrementalRequest.repository:type_name -> gitaly.Repository - 87, // 2: gitaly.RepackFullRequest.repository:type_name -> gitaly.Repository - 87, // 3: gitaly.MidxRepackRequest.repository:type_name -> gitaly.Repository - 87, // 4: gitaly.GarbageCollectRequest.repository:type_name -> gitaly.Repository - 87, // 5: gitaly.WriteCommitGraphRequest.repository:type_name -> gitaly.Repository +var file_repository_proto_depIdxs = []int32{ + 89, // 0: gitaly.RepositoryExistsRequest.repository:type_name -> gitaly.Repository + 89, // 1: gitaly.RepackIncrementalRequest.repository:type_name -> gitaly.Repository + 89, // 2: gitaly.RepackFullRequest.repository:type_name -> gitaly.Repository + 89, // 3: gitaly.MidxRepackRequest.repository:type_name -> gitaly.Repository + 89, // 4: gitaly.GarbageCollectRequest.repository:type_name -> gitaly.Repository + 89, // 5: gitaly.WriteCommitGraphRequest.repository:type_name -> gitaly.Repository 0, // 6: gitaly.WriteCommitGraphRequest.splitStrategy:type_name -> gitaly.WriteCommitGraphRequest.SplitStrategy - 87, // 7: gitaly.CleanupRequest.repository:type_name -> gitaly.Repository - 87, // 8: gitaly.RepositorySizeRequest.repository:type_name -> gitaly.Repository - 87, // 9: gitaly.ApplyGitattributesRequest.repository:type_name -> gitaly.Repository - 87, // 10: gitaly.FetchBundleRequest.repository:type_name -> gitaly.Repository - 87, // 11: gitaly.FetchRemoteRequest.repository:type_name -> gitaly.Repository + 89, // 7: gitaly.CleanupRequest.repository:type_name -> gitaly.Repository + 89, // 8: gitaly.RepositorySizeRequest.repository:type_name -> gitaly.Repository + 89, // 9: gitaly.ApplyGitattributesRequest.repository:type_name -> gitaly.Repository + 89, // 10: gitaly.FetchBundleRequest.repository:type_name -> gitaly.Repository + 89, // 11: gitaly.FetchRemoteRequest.repository:type_name -> gitaly.Repository 71, // 12: gitaly.FetchRemoteRequest.remote_params:type_name -> gitaly.Remote - 87, // 13: gitaly.CreateRepositoryRequest.repository:type_name -> gitaly.Repository - 87, // 14: gitaly.GetArchiveRequest.repository:type_name -> gitaly.Repository + 89, // 13: gitaly.CreateRepositoryRequest.repository:type_name -> gitaly.Repository + 89, // 14: gitaly.GetArchiveRequest.repository:type_name -> gitaly.Repository 1, // 15: gitaly.GetArchiveRequest.format:type_name -> gitaly.GetArchiveRequest.Format - 87, // 16: gitaly.HasLocalBranchesRequest.repository:type_name -> gitaly.Repository - 87, // 17: gitaly.FetchSourceBranchRequest.repository:type_name -> gitaly.Repository - 87, // 18: gitaly.FetchSourceBranchRequest.source_repository:type_name -> gitaly.Repository - 87, // 19: gitaly.FsckRequest.repository:type_name -> gitaly.Repository - 87, // 20: gitaly.WriteRefRequest.repository:type_name -> gitaly.Repository - 87, // 21: gitaly.FindMergeBaseRequest.repository:type_name -> gitaly.Repository - 87, // 22: gitaly.CreateForkRequest.repository:type_name -> gitaly.Repository - 87, // 23: gitaly.CreateForkRequest.source_repository:type_name -> gitaly.Repository - 87, // 24: gitaly.CreateRepositoryFromURLRequest.repository:type_name -> gitaly.Repository - 87, // 25: gitaly.CreateBundleRequest.repository:type_name -> gitaly.Repository - 87, // 26: gitaly.CreateBundleFromRefListRequest.repository:type_name -> gitaly.Repository - 87, // 27: gitaly.GetConfigRequest.repository:type_name -> gitaly.Repository - 87, // 28: gitaly.RestoreCustomHooksRequest.repository:type_name -> gitaly.Repository - 87, // 29: gitaly.BackupCustomHooksRequest.repository:type_name -> gitaly.Repository - 87, // 30: gitaly.CreateRepositoryFromBundleRequest.repository:type_name -> gitaly.Repository - 87, // 31: gitaly.FindLicenseRequest.repository:type_name -> gitaly.Repository - 87, // 32: gitaly.GetInfoAttributesRequest.repository:type_name -> gitaly.Repository - 87, // 33: gitaly.CalculateChecksumRequest.repository:type_name -> gitaly.Repository - 87, // 34: gitaly.GetSnapshotRequest.repository:type_name -> gitaly.Repository - 87, // 35: gitaly.CreateRepositoryFromSnapshotRequest.repository:type_name -> gitaly.Repository - 87, // 36: gitaly.GetRawChangesRequest.repository:type_name -> gitaly.Repository - 86, // 37: gitaly.GetRawChangesResponse.raw_changes:type_name -> gitaly.GetRawChangesResponse.RawChange - 87, // 38: gitaly.SearchFilesByNameRequest.repository:type_name -> gitaly.Repository - 87, // 39: gitaly.SearchFilesByContentRequest.repository:type_name -> gitaly.Repository - 87, // 40: gitaly.GetObjectDirectorySizeRequest.repository:type_name -> gitaly.Repository - 87, // 41: gitaly.RemoveRepositoryRequest.repository:type_name -> gitaly.Repository - 87, // 42: gitaly.RenameRepositoryRequest.repository:type_name -> gitaly.Repository - 87, // 43: gitaly.ReplicateRepositoryRequest.repository:type_name -> gitaly.Repository - 87, // 44: gitaly.ReplicateRepositoryRequest.source:type_name -> gitaly.Repository - 87, // 45: gitaly.OptimizeRepositoryRequest.repository:type_name -> gitaly.Repository - 87, // 46: gitaly.PruneUnreachableObjectsRequest.repository:type_name -> gitaly.Repository - 87, // 47: gitaly.SetFullPathRequest.repository:type_name -> gitaly.Repository - 2, // 48: gitaly.GetRawChangesResponse.RawChange.operation:type_name -> gitaly.GetRawChangesResponse.RawChange.Operation - 3, // 49: gitaly.RepositoryService.RepositoryExists:input_type -> gitaly.RepositoryExistsRequest - 5, // 50: gitaly.RepositoryService.RepackIncremental:input_type -> gitaly.RepackIncrementalRequest - 7, // 51: gitaly.RepositoryService.RepackFull:input_type -> gitaly.RepackFullRequest - 9, // 52: gitaly.RepositoryService.MidxRepack:input_type -> gitaly.MidxRepackRequest - 11, // 53: gitaly.RepositoryService.GarbageCollect:input_type -> gitaly.GarbageCollectRequest - 13, // 54: gitaly.RepositoryService.WriteCommitGraph:input_type -> gitaly.WriteCommitGraphRequest - 17, // 55: gitaly.RepositoryService.RepositorySize:input_type -> gitaly.RepositorySizeRequest - 19, // 56: gitaly.RepositoryService.ApplyGitattributes:input_type -> gitaly.ApplyGitattributesRequest - 23, // 57: gitaly.RepositoryService.FetchRemote:input_type -> gitaly.FetchRemoteRequest - 25, // 58: gitaly.RepositoryService.CreateRepository:input_type -> gitaly.CreateRepositoryRequest - 27, // 59: gitaly.RepositoryService.GetArchive:input_type -> gitaly.GetArchiveRequest - 29, // 60: gitaly.RepositoryService.HasLocalBranches:input_type -> gitaly.HasLocalBranchesRequest - 31, // 61: gitaly.RepositoryService.FetchSourceBranch:input_type -> gitaly.FetchSourceBranchRequest - 33, // 62: gitaly.RepositoryService.Fsck:input_type -> gitaly.FsckRequest - 35, // 63: gitaly.RepositoryService.WriteRef:input_type -> gitaly.WriteRefRequest - 37, // 64: gitaly.RepositoryService.FindMergeBase:input_type -> gitaly.FindMergeBaseRequest - 39, // 65: gitaly.RepositoryService.CreateFork:input_type -> gitaly.CreateForkRequest - 41, // 66: gitaly.RepositoryService.CreateRepositoryFromURL:input_type -> gitaly.CreateRepositoryFromURLRequest - 43, // 67: gitaly.RepositoryService.CreateBundle:input_type -> gitaly.CreateBundleRequest - 45, // 68: gitaly.RepositoryService.CreateBundleFromRefList:input_type -> gitaly.CreateBundleFromRefListRequest - 21, // 69: gitaly.RepositoryService.FetchBundle:input_type -> gitaly.FetchBundleRequest - 53, // 70: gitaly.RepositoryService.CreateRepositoryFromBundle:input_type -> gitaly.CreateRepositoryFromBundleRequest - 47, // 71: gitaly.RepositoryService.GetConfig:input_type -> gitaly.GetConfigRequest - 55, // 72: gitaly.RepositoryService.FindLicense:input_type -> gitaly.FindLicenseRequest - 57, // 73: gitaly.RepositoryService.GetInfoAttributes:input_type -> gitaly.GetInfoAttributesRequest - 59, // 74: gitaly.RepositoryService.CalculateChecksum:input_type -> gitaly.CalculateChecksumRequest - 15, // 75: gitaly.RepositoryService.Cleanup:input_type -> gitaly.CleanupRequest - 61, // 76: gitaly.RepositoryService.GetSnapshot:input_type -> gitaly.GetSnapshotRequest - 63, // 77: gitaly.RepositoryService.CreateRepositoryFromSnapshot:input_type -> gitaly.CreateRepositoryFromSnapshotRequest - 65, // 78: gitaly.RepositoryService.GetRawChanges:input_type -> gitaly.GetRawChangesRequest - 69, // 79: gitaly.RepositoryService.SearchFilesByContent:input_type -> gitaly.SearchFilesByContentRequest - 67, // 80: gitaly.RepositoryService.SearchFilesByName:input_type -> gitaly.SearchFilesByNameRequest - 49, // 81: gitaly.RepositoryService.RestoreCustomHooks:input_type -> gitaly.RestoreCustomHooksRequest - 51, // 82: gitaly.RepositoryService.BackupCustomHooks:input_type -> gitaly.BackupCustomHooksRequest - 72, // 83: gitaly.RepositoryService.GetObjectDirectorySize:input_type -> gitaly.GetObjectDirectorySizeRequest - 74, // 84: gitaly.RepositoryService.RemoveRepository:input_type -> gitaly.RemoveRepositoryRequest - 76, // 85: gitaly.RepositoryService.RenameRepository:input_type -> gitaly.RenameRepositoryRequest - 78, // 86: gitaly.RepositoryService.ReplicateRepository:input_type -> gitaly.ReplicateRepositoryRequest - 80, // 87: gitaly.RepositoryService.OptimizeRepository:input_type -> gitaly.OptimizeRepositoryRequest - 82, // 88: gitaly.RepositoryService.PruneUnreachableObjects:input_type -> gitaly.PruneUnreachableObjectsRequest - 84, // 89: gitaly.RepositoryService.SetFullPath:input_type -> gitaly.SetFullPathRequest - 4, // 90: gitaly.RepositoryService.RepositoryExists:output_type -> gitaly.RepositoryExistsResponse - 6, // 91: gitaly.RepositoryService.RepackIncremental:output_type -> gitaly.RepackIncrementalResponse - 8, // 92: gitaly.RepositoryService.RepackFull:output_type -> gitaly.RepackFullResponse - 10, // 93: gitaly.RepositoryService.MidxRepack:output_type -> gitaly.MidxRepackResponse - 12, // 94: gitaly.RepositoryService.GarbageCollect:output_type -> gitaly.GarbageCollectResponse - 14, // 95: gitaly.RepositoryService.WriteCommitGraph:output_type -> gitaly.WriteCommitGraphResponse - 18, // 96: gitaly.RepositoryService.RepositorySize:output_type -> gitaly.RepositorySizeResponse - 20, // 97: gitaly.RepositoryService.ApplyGitattributes:output_type -> gitaly.ApplyGitattributesResponse - 24, // 98: gitaly.RepositoryService.FetchRemote:output_type -> gitaly.FetchRemoteResponse - 26, // 99: gitaly.RepositoryService.CreateRepository:output_type -> gitaly.CreateRepositoryResponse - 28, // 100: gitaly.RepositoryService.GetArchive:output_type -> gitaly.GetArchiveResponse - 30, // 101: gitaly.RepositoryService.HasLocalBranches:output_type -> gitaly.HasLocalBranchesResponse - 32, // 102: gitaly.RepositoryService.FetchSourceBranch:output_type -> gitaly.FetchSourceBranchResponse - 34, // 103: gitaly.RepositoryService.Fsck:output_type -> gitaly.FsckResponse - 36, // 104: gitaly.RepositoryService.WriteRef:output_type -> gitaly.WriteRefResponse - 38, // 105: gitaly.RepositoryService.FindMergeBase:output_type -> gitaly.FindMergeBaseResponse - 40, // 106: gitaly.RepositoryService.CreateFork:output_type -> gitaly.CreateForkResponse - 42, // 107: gitaly.RepositoryService.CreateRepositoryFromURL:output_type -> gitaly.CreateRepositoryFromURLResponse - 44, // 108: gitaly.RepositoryService.CreateBundle:output_type -> gitaly.CreateBundleResponse - 46, // 109: gitaly.RepositoryService.CreateBundleFromRefList:output_type -> gitaly.CreateBundleFromRefListResponse - 22, // 110: gitaly.RepositoryService.FetchBundle:output_type -> gitaly.FetchBundleResponse - 54, // 111: gitaly.RepositoryService.CreateRepositoryFromBundle:output_type -> gitaly.CreateRepositoryFromBundleResponse - 48, // 112: gitaly.RepositoryService.GetConfig:output_type -> gitaly.GetConfigResponse - 56, // 113: gitaly.RepositoryService.FindLicense:output_type -> gitaly.FindLicenseResponse - 58, // 114: gitaly.RepositoryService.GetInfoAttributes:output_type -> gitaly.GetInfoAttributesResponse - 60, // 115: gitaly.RepositoryService.CalculateChecksum:output_type -> gitaly.CalculateChecksumResponse - 16, // 116: gitaly.RepositoryService.Cleanup:output_type -> gitaly.CleanupResponse - 62, // 117: gitaly.RepositoryService.GetSnapshot:output_type -> gitaly.GetSnapshotResponse - 64, // 118: gitaly.RepositoryService.CreateRepositoryFromSnapshot:output_type -> gitaly.CreateRepositoryFromSnapshotResponse - 66, // 119: gitaly.RepositoryService.GetRawChanges:output_type -> gitaly.GetRawChangesResponse - 70, // 120: gitaly.RepositoryService.SearchFilesByContent:output_type -> gitaly.SearchFilesByContentResponse - 68, // 121: gitaly.RepositoryService.SearchFilesByName:output_type -> gitaly.SearchFilesByNameResponse - 50, // 122: gitaly.RepositoryService.RestoreCustomHooks:output_type -> gitaly.RestoreCustomHooksResponse - 52, // 123: gitaly.RepositoryService.BackupCustomHooks:output_type -> gitaly.BackupCustomHooksResponse - 73, // 124: gitaly.RepositoryService.GetObjectDirectorySize:output_type -> gitaly.GetObjectDirectorySizeResponse - 75, // 125: gitaly.RepositoryService.RemoveRepository:output_type -> gitaly.RemoveRepositoryResponse - 77, // 126: gitaly.RepositoryService.RenameRepository:output_type -> gitaly.RenameRepositoryResponse - 79, // 127: gitaly.RepositoryService.ReplicateRepository:output_type -> gitaly.ReplicateRepositoryResponse - 81, // 128: gitaly.RepositoryService.OptimizeRepository:output_type -> gitaly.OptimizeRepositoryResponse - 83, // 129: gitaly.RepositoryService.PruneUnreachableObjects:output_type -> gitaly.PruneUnreachableObjectsResponse - 85, // 130: gitaly.RepositoryService.SetFullPath:output_type -> gitaly.SetFullPathResponse - 90, // [90:131] is the sub-list for method output_type - 49, // [49:90] is the sub-list for method input_type - 49, // [49:49] is the sub-list for extension type_name - 49, // [49:49] is the sub-list for extension extendee - 0, // [0:49] is the sub-list for field type_name + 89, // 16: gitaly.HasLocalBranchesRequest.repository:type_name -> gitaly.Repository + 89, // 17: gitaly.FetchSourceBranchRequest.repository:type_name -> gitaly.Repository + 89, // 18: gitaly.FetchSourceBranchRequest.source_repository:type_name -> gitaly.Repository + 89, // 19: gitaly.FsckRequest.repository:type_name -> gitaly.Repository + 89, // 20: gitaly.WriteRefRequest.repository:type_name -> gitaly.Repository + 89, // 21: gitaly.FindMergeBaseRequest.repository:type_name -> gitaly.Repository + 89, // 22: gitaly.CreateForkRequest.repository:type_name -> gitaly.Repository + 89, // 23: gitaly.CreateForkRequest.source_repository:type_name -> gitaly.Repository + 89, // 24: gitaly.CreateRepositoryFromURLRequest.repository:type_name -> gitaly.Repository + 89, // 25: gitaly.CreateBundleRequest.repository:type_name -> gitaly.Repository + 89, // 26: gitaly.CreateBundleFromRefListRequest.repository:type_name -> gitaly.Repository + 89, // 27: gitaly.GetConfigRequest.repository:type_name -> gitaly.Repository + 89, // 28: gitaly.RestoreCustomHooksRequest.repository:type_name -> gitaly.Repository + 89, // 29: gitaly.BackupCustomHooksRequest.repository:type_name -> gitaly.Repository + 89, // 30: gitaly.CreateRepositoryFromBundleRequest.repository:type_name -> gitaly.Repository + 89, // 31: gitaly.FindLicenseRequest.repository:type_name -> gitaly.Repository + 89, // 32: gitaly.GetInfoAttributesRequest.repository:type_name -> gitaly.Repository + 89, // 33: gitaly.CalculateChecksumRequest.repository:type_name -> gitaly.Repository + 89, // 34: gitaly.GetSnapshotRequest.repository:type_name -> gitaly.Repository + 89, // 35: gitaly.CreateRepositoryFromSnapshotRequest.repository:type_name -> gitaly.Repository + 89, // 36: gitaly.GetRawChangesRequest.repository:type_name -> gitaly.Repository + 88, // 37: gitaly.GetRawChangesResponse.raw_changes:type_name -> gitaly.GetRawChangesResponse.RawChange + 89, // 38: gitaly.SearchFilesByNameRequest.repository:type_name -> gitaly.Repository + 89, // 39: gitaly.SearchFilesByContentRequest.repository:type_name -> gitaly.Repository + 89, // 40: gitaly.GetObjectDirectorySizeRequest.repository:type_name -> gitaly.Repository + 89, // 41: gitaly.RemoveRepositoryRequest.repository:type_name -> gitaly.Repository + 89, // 42: gitaly.RenameRepositoryRequest.repository:type_name -> gitaly.Repository + 89, // 43: gitaly.ReplicateRepositoryRequest.repository:type_name -> gitaly.Repository + 89, // 44: gitaly.ReplicateRepositoryRequest.source:type_name -> gitaly.Repository + 89, // 45: gitaly.OptimizeRepositoryRequest.repository:type_name -> gitaly.Repository + 89, // 46: gitaly.PruneUnreachableObjectsRequest.repository:type_name -> gitaly.Repository + 89, // 47: gitaly.SetFullPathRequest.repository:type_name -> gitaly.Repository + 89, // 48: gitaly.FullPathRequest.repository:type_name -> gitaly.Repository + 2, // 49: gitaly.GetRawChangesResponse.RawChange.operation:type_name -> gitaly.GetRawChangesResponse.RawChange.Operation + 3, // 50: gitaly.RepositoryService.RepositoryExists:input_type -> gitaly.RepositoryExistsRequest + 5, // 51: gitaly.RepositoryService.RepackIncremental:input_type -> gitaly.RepackIncrementalRequest + 7, // 52: gitaly.RepositoryService.RepackFull:input_type -> gitaly.RepackFullRequest + 9, // 53: gitaly.RepositoryService.MidxRepack:input_type -> gitaly.MidxRepackRequest + 11, // 54: gitaly.RepositoryService.GarbageCollect:input_type -> gitaly.GarbageCollectRequest + 13, // 55: gitaly.RepositoryService.WriteCommitGraph:input_type -> gitaly.WriteCommitGraphRequest + 17, // 56: gitaly.RepositoryService.RepositorySize:input_type -> gitaly.RepositorySizeRequest + 19, // 57: gitaly.RepositoryService.ApplyGitattributes:input_type -> gitaly.ApplyGitattributesRequest + 23, // 58: gitaly.RepositoryService.FetchRemote:input_type -> gitaly.FetchRemoteRequest + 25, // 59: gitaly.RepositoryService.CreateRepository:input_type -> gitaly.CreateRepositoryRequest + 27, // 60: gitaly.RepositoryService.GetArchive:input_type -> gitaly.GetArchiveRequest + 29, // 61: gitaly.RepositoryService.HasLocalBranches:input_type -> gitaly.HasLocalBranchesRequest + 31, // 62: gitaly.RepositoryService.FetchSourceBranch:input_type -> gitaly.FetchSourceBranchRequest + 33, // 63: gitaly.RepositoryService.Fsck:input_type -> gitaly.FsckRequest + 35, // 64: gitaly.RepositoryService.WriteRef:input_type -> gitaly.WriteRefRequest + 37, // 65: gitaly.RepositoryService.FindMergeBase:input_type -> gitaly.FindMergeBaseRequest + 39, // 66: gitaly.RepositoryService.CreateFork:input_type -> gitaly.CreateForkRequest + 41, // 67: gitaly.RepositoryService.CreateRepositoryFromURL:input_type -> gitaly.CreateRepositoryFromURLRequest + 43, // 68: gitaly.RepositoryService.CreateBundle:input_type -> gitaly.CreateBundleRequest + 45, // 69: gitaly.RepositoryService.CreateBundleFromRefList:input_type -> gitaly.CreateBundleFromRefListRequest + 21, // 70: gitaly.RepositoryService.FetchBundle:input_type -> gitaly.FetchBundleRequest + 53, // 71: gitaly.RepositoryService.CreateRepositoryFromBundle:input_type -> gitaly.CreateRepositoryFromBundleRequest + 47, // 72: gitaly.RepositoryService.GetConfig:input_type -> gitaly.GetConfigRequest + 55, // 73: gitaly.RepositoryService.FindLicense:input_type -> gitaly.FindLicenseRequest + 57, // 74: gitaly.RepositoryService.GetInfoAttributes:input_type -> gitaly.GetInfoAttributesRequest + 59, // 75: gitaly.RepositoryService.CalculateChecksum:input_type -> gitaly.CalculateChecksumRequest + 15, // 76: gitaly.RepositoryService.Cleanup:input_type -> gitaly.CleanupRequest + 61, // 77: gitaly.RepositoryService.GetSnapshot:input_type -> gitaly.GetSnapshotRequest + 63, // 78: gitaly.RepositoryService.CreateRepositoryFromSnapshot:input_type -> gitaly.CreateRepositoryFromSnapshotRequest + 65, // 79: gitaly.RepositoryService.GetRawChanges:input_type -> gitaly.GetRawChangesRequest + 69, // 80: gitaly.RepositoryService.SearchFilesByContent:input_type -> gitaly.SearchFilesByContentRequest + 67, // 81: gitaly.RepositoryService.SearchFilesByName:input_type -> gitaly.SearchFilesByNameRequest + 49, // 82: gitaly.RepositoryService.RestoreCustomHooks:input_type -> gitaly.RestoreCustomHooksRequest + 51, // 83: gitaly.RepositoryService.BackupCustomHooks:input_type -> gitaly.BackupCustomHooksRequest + 72, // 84: gitaly.RepositoryService.GetObjectDirectorySize:input_type -> gitaly.GetObjectDirectorySizeRequest + 74, // 85: gitaly.RepositoryService.RemoveRepository:input_type -> gitaly.RemoveRepositoryRequest + 76, // 86: gitaly.RepositoryService.RenameRepository:input_type -> gitaly.RenameRepositoryRequest + 78, // 87: gitaly.RepositoryService.ReplicateRepository:input_type -> gitaly.ReplicateRepositoryRequest + 80, // 88: gitaly.RepositoryService.OptimizeRepository:input_type -> gitaly.OptimizeRepositoryRequest + 82, // 89: gitaly.RepositoryService.PruneUnreachableObjects:input_type -> gitaly.PruneUnreachableObjectsRequest + 84, // 90: gitaly.RepositoryService.SetFullPath:input_type -> gitaly.SetFullPathRequest + 86, // 91: gitaly.RepositoryService.FullPath:input_type -> gitaly.FullPathRequest + 4, // 92: gitaly.RepositoryService.RepositoryExists:output_type -> gitaly.RepositoryExistsResponse + 6, // 93: gitaly.RepositoryService.RepackIncremental:output_type -> gitaly.RepackIncrementalResponse + 8, // 94: gitaly.RepositoryService.RepackFull:output_type -> gitaly.RepackFullResponse + 10, // 95: gitaly.RepositoryService.MidxRepack:output_type -> gitaly.MidxRepackResponse + 12, // 96: gitaly.RepositoryService.GarbageCollect:output_type -> gitaly.GarbageCollectResponse + 14, // 97: gitaly.RepositoryService.WriteCommitGraph:output_type -> gitaly.WriteCommitGraphResponse + 18, // 98: gitaly.RepositoryService.RepositorySize:output_type -> gitaly.RepositorySizeResponse + 20, // 99: gitaly.RepositoryService.ApplyGitattributes:output_type -> gitaly.ApplyGitattributesResponse + 24, // 100: gitaly.RepositoryService.FetchRemote:output_type -> gitaly.FetchRemoteResponse + 26, // 101: gitaly.RepositoryService.CreateRepository:output_type -> gitaly.CreateRepositoryResponse + 28, // 102: gitaly.RepositoryService.GetArchive:output_type -> gitaly.GetArchiveResponse + 30, // 103: gitaly.RepositoryService.HasLocalBranches:output_type -> gitaly.HasLocalBranchesResponse + 32, // 104: gitaly.RepositoryService.FetchSourceBranch:output_type -> gitaly.FetchSourceBranchResponse + 34, // 105: gitaly.RepositoryService.Fsck:output_type -> gitaly.FsckResponse + 36, // 106: gitaly.RepositoryService.WriteRef:output_type -> gitaly.WriteRefResponse + 38, // 107: gitaly.RepositoryService.FindMergeBase:output_type -> gitaly.FindMergeBaseResponse + 40, // 108: gitaly.RepositoryService.CreateFork:output_type -> gitaly.CreateForkResponse + 42, // 109: gitaly.RepositoryService.CreateRepositoryFromURL:output_type -> gitaly.CreateRepositoryFromURLResponse + 44, // 110: gitaly.RepositoryService.CreateBundle:output_type -> gitaly.CreateBundleResponse + 46, // 111: gitaly.RepositoryService.CreateBundleFromRefList:output_type -> gitaly.CreateBundleFromRefListResponse + 22, // 112: gitaly.RepositoryService.FetchBundle:output_type -> gitaly.FetchBundleResponse + 54, // 113: gitaly.RepositoryService.CreateRepositoryFromBundle:output_type -> gitaly.CreateRepositoryFromBundleResponse + 48, // 114: gitaly.RepositoryService.GetConfig:output_type -> gitaly.GetConfigResponse + 56, // 115: gitaly.RepositoryService.FindLicense:output_type -> gitaly.FindLicenseResponse + 58, // 116: gitaly.RepositoryService.GetInfoAttributes:output_type -> gitaly.GetInfoAttributesResponse + 60, // 117: gitaly.RepositoryService.CalculateChecksum:output_type -> gitaly.CalculateChecksumResponse + 16, // 118: gitaly.RepositoryService.Cleanup:output_type -> gitaly.CleanupResponse + 62, // 119: gitaly.RepositoryService.GetSnapshot:output_type -> gitaly.GetSnapshotResponse + 64, // 120: gitaly.RepositoryService.CreateRepositoryFromSnapshot:output_type -> gitaly.CreateRepositoryFromSnapshotResponse + 66, // 121: gitaly.RepositoryService.GetRawChanges:output_type -> gitaly.GetRawChangesResponse + 70, // 122: gitaly.RepositoryService.SearchFilesByContent:output_type -> gitaly.SearchFilesByContentResponse + 68, // 123: gitaly.RepositoryService.SearchFilesByName:output_type -> gitaly.SearchFilesByNameResponse + 50, // 124: gitaly.RepositoryService.RestoreCustomHooks:output_type -> gitaly.RestoreCustomHooksResponse + 52, // 125: gitaly.RepositoryService.BackupCustomHooks:output_type -> gitaly.BackupCustomHooksResponse + 73, // 126: gitaly.RepositoryService.GetObjectDirectorySize:output_type -> gitaly.GetObjectDirectorySizeResponse + 75, // 127: gitaly.RepositoryService.RemoveRepository:output_type -> gitaly.RemoveRepositoryResponse + 77, // 128: gitaly.RepositoryService.RenameRepository:output_type -> gitaly.RenameRepositoryResponse + 79, // 129: gitaly.RepositoryService.ReplicateRepository:output_type -> gitaly.ReplicateRepositoryResponse + 81, // 130: gitaly.RepositoryService.OptimizeRepository:output_type -> gitaly.OptimizeRepositoryResponse + 83, // 131: gitaly.RepositoryService.PruneUnreachableObjects:output_type -> gitaly.PruneUnreachableObjectsResponse + 85, // 132: gitaly.RepositoryService.SetFullPath:output_type -> gitaly.SetFullPathResponse + 87, // 133: gitaly.RepositoryService.FullPath:output_type -> gitaly.FullPathResponse + 92, // [92:134] is the sub-list for method output_type + 50, // [50:92] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name } -func init() { file_repository_service_proto_init() } -func file_repository_service_proto_init() { - if File_repository_service_proto != nil { +func init() { file_repository_proto_init() } +func file_repository_proto_init() { + if File_repository_proto != nil { return } file_lint_proto_init() file_shared_proto_init() if !protoimpl.UnsafeEnabled { - file_repository_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepositoryExistsRequest); i { case 0: return &v.state @@ -5555,7 +5899,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepositoryExistsResponse); i { case 0: return &v.state @@ -5567,7 +5911,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepackIncrementalRequest); i { case 0: return &v.state @@ -5579,7 +5923,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepackIncrementalResponse); i { case 0: return &v.state @@ -5591,7 +5935,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepackFullRequest); i { case 0: return &v.state @@ -5603,7 +5947,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepackFullResponse); i { case 0: return &v.state @@ -5615,7 +5959,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MidxRepackRequest); i { case 0: return &v.state @@ -5627,7 +5971,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MidxRepackResponse); i { case 0: return &v.state @@ -5639,7 +5983,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GarbageCollectRequest); i { case 0: return &v.state @@ -5651,7 +5995,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GarbageCollectResponse); i { case 0: return &v.state @@ -5663,7 +6007,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WriteCommitGraphRequest); i { case 0: return &v.state @@ -5675,7 +6019,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WriteCommitGraphResponse); i { case 0: return &v.state @@ -5687,7 +6031,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CleanupRequest); i { case 0: return &v.state @@ -5699,7 +6043,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CleanupResponse); i { case 0: return &v.state @@ -5711,7 +6055,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepositorySizeRequest); i { case 0: return &v.state @@ -5723,7 +6067,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RepositorySizeResponse); i { case 0: return &v.state @@ -5735,7 +6079,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyGitattributesRequest); i { case 0: return &v.state @@ -5747,7 +6091,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyGitattributesResponse); i { case 0: return &v.state @@ -5759,7 +6103,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchBundleRequest); i { case 0: return &v.state @@ -5771,7 +6115,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchBundleResponse); i { case 0: return &v.state @@ -5783,7 +6127,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchRemoteRequest); i { case 0: return &v.state @@ -5795,7 +6139,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchRemoteResponse); i { case 0: return &v.state @@ -5807,7 +6151,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryRequest); i { case 0: return &v.state @@ -5819,7 +6163,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryResponse); i { case 0: return &v.state @@ -5831,7 +6175,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetArchiveRequest); i { case 0: return &v.state @@ -5843,7 +6187,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetArchiveResponse); i { case 0: return &v.state @@ -5855,7 +6199,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HasLocalBranchesRequest); i { case 0: return &v.state @@ -5867,7 +6211,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HasLocalBranchesResponse); i { case 0: return &v.state @@ -5879,7 +6223,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchSourceBranchRequest); i { case 0: return &v.state @@ -5891,7 +6235,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchSourceBranchResponse); i { case 0: return &v.state @@ -5903,7 +6247,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FsckRequest); i { case 0: return &v.state @@ -5915,7 +6259,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FsckResponse); i { case 0: return &v.state @@ -5927,7 +6271,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WriteRefRequest); i { case 0: return &v.state @@ -5939,7 +6283,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WriteRefResponse); i { case 0: return &v.state @@ -5951,7 +6295,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FindMergeBaseRequest); i { case 0: return &v.state @@ -5963,7 +6307,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FindMergeBaseResponse); i { case 0: return &v.state @@ -5975,7 +6319,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateForkRequest); i { case 0: return &v.state @@ -5987,7 +6331,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateForkResponse); i { case 0: return &v.state @@ -5999,7 +6343,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromURLRequest); i { case 0: return &v.state @@ -6011,7 +6355,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromURLResponse); i { case 0: return &v.state @@ -6023,7 +6367,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateBundleRequest); i { case 0: return &v.state @@ -6035,7 +6379,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateBundleResponse); i { case 0: return &v.state @@ -6047,7 +6391,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateBundleFromRefListRequest); i { case 0: return &v.state @@ -6059,7 +6403,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateBundleFromRefListResponse); i { case 0: return &v.state @@ -6071,7 +6415,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetConfigRequest); i { case 0: return &v.state @@ -6083,7 +6427,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetConfigResponse); i { case 0: return &v.state @@ -6095,7 +6439,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RestoreCustomHooksRequest); i { case 0: return &v.state @@ -6107,7 +6451,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RestoreCustomHooksResponse); i { case 0: return &v.state @@ -6119,7 +6463,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BackupCustomHooksRequest); i { case 0: return &v.state @@ -6131,7 +6475,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BackupCustomHooksResponse); i { case 0: return &v.state @@ -6143,7 +6487,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromBundleRequest); i { case 0: return &v.state @@ -6155,7 +6499,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromBundleResponse); i { case 0: return &v.state @@ -6167,7 +6511,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FindLicenseRequest); i { case 0: return &v.state @@ -6179,7 +6523,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FindLicenseResponse); i { case 0: return &v.state @@ -6191,7 +6535,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetInfoAttributesRequest); i { case 0: return &v.state @@ -6203,7 +6547,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetInfoAttributesResponse); i { case 0: return &v.state @@ -6215,7 +6559,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CalculateChecksumRequest); i { case 0: return &v.state @@ -6227,7 +6571,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CalculateChecksumResponse); i { case 0: return &v.state @@ -6239,7 +6583,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSnapshotRequest); i { case 0: return &v.state @@ -6251,7 +6595,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSnapshotResponse); i { case 0: return &v.state @@ -6263,7 +6607,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromSnapshotRequest); i { case 0: return &v.state @@ -6275,7 +6619,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRepositoryFromSnapshotResponse); i { case 0: return &v.state @@ -6287,7 +6631,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetRawChangesRequest); i { case 0: return &v.state @@ -6299,7 +6643,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetRawChangesResponse); i { case 0: return &v.state @@ -6311,7 +6655,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SearchFilesByNameRequest); i { case 0: return &v.state @@ -6323,7 +6667,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SearchFilesByNameResponse); i { case 0: return &v.state @@ -6335,7 +6679,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SearchFilesByContentRequest); i { case 0: return &v.state @@ -6347,7 +6691,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SearchFilesByContentResponse); i { case 0: return &v.state @@ -6359,7 +6703,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Remote); i { case 0: return &v.state @@ -6371,7 +6715,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetObjectDirectorySizeRequest); i { case 0: return &v.state @@ -6383,7 +6727,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetObjectDirectorySizeResponse); i { case 0: return &v.state @@ -6395,7 +6739,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveRepositoryRequest); i { case 0: return &v.state @@ -6407,7 +6751,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveRepositoryResponse); i { case 0: return &v.state @@ -6419,7 +6763,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RenameRepositoryRequest); i { case 0: return &v.state @@ -6431,7 +6775,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RenameRepositoryResponse); i { case 0: return &v.state @@ -6443,7 +6787,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReplicateRepositoryRequest); i { case 0: return &v.state @@ -6455,7 +6799,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReplicateRepositoryResponse); i { case 0: return &v.state @@ -6467,7 +6811,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OptimizeRepositoryRequest); i { case 0: return &v.state @@ -6479,7 +6823,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OptimizeRepositoryResponse); i { case 0: return &v.state @@ -6491,7 +6835,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PruneUnreachableObjectsRequest); i { case 0: return &v.state @@ -6503,7 +6847,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PruneUnreachableObjectsResponse); i { case 0: return &v.state @@ -6515,7 +6859,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetFullPathRequest); i { case 0: return &v.state @@ -6527,7 +6871,7 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetFullPathResponse); i { case 0: return &v.state @@ -6539,7 +6883,31 @@ func file_repository_service_proto_init() { return nil } } - file_repository_service_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + file_repository_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FullPathRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_repository_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FullPathResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_repository_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetRawChangesResponse_RawChange); i { case 0: return &v.state @@ -6556,19 +6924,19 @@ func file_repository_service_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_repository_service_proto_rawDesc, + RawDescriptor: file_repository_proto_rawDesc, NumEnums: 3, - NumMessages: 84, + NumMessages: 86, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_repository_service_proto_goTypes, - DependencyIndexes: file_repository_service_proto_depIdxs, - EnumInfos: file_repository_service_proto_enumTypes, - MessageInfos: file_repository_service_proto_msgTypes, + GoTypes: file_repository_proto_goTypes, + DependencyIndexes: file_repository_proto_depIdxs, + EnumInfos: file_repository_proto_enumTypes, + MessageInfos: file_repository_proto_msgTypes, }.Build() - File_repository_service_proto = out.File - file_repository_service_proto_rawDesc = nil - file_repository_service_proto_goTypes = nil - file_repository_service_proto_depIdxs = nil + File_repository_proto = out.File + file_repository_proto_rawDesc = nil + file_repository_proto_goTypes = nil + file_repository_proto_depIdxs = nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository_grpc.pb.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository_grpc.pb.go index a0bf03792a..b81ec3de63 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/repository-service_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/repository_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: repository.proto package gitalypb @@ -18,6 +22,7 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RepositoryServiceClient interface { + // This comment is left unintentionally blank. RepositoryExists(ctx context.Context, in *RepositoryExistsRequest, opts ...grpc.CallOption) (*RepositoryExistsResponse, error) // Deprecated: Do not use. // RepackIncremental is deprecated in favor of OptimizeRepository. @@ -34,21 +39,31 @@ type RepositoryServiceClient interface { // Deprecated: Do not use. // WriteCommitGraph is deprecated in favor of OptimizeRepository. WriteCommitGraph(ctx context.Context, in *WriteCommitGraphRequest, opts ...grpc.CallOption) (*WriteCommitGraphResponse, error) + // This comment is left unintentionally blank. RepositorySize(ctx context.Context, in *RepositorySizeRequest, opts ...grpc.CallOption) (*RepositorySizeResponse, error) + // This comment is left unintentionally blank. ApplyGitattributes(ctx context.Context, in *ApplyGitattributesRequest, opts ...grpc.CallOption) (*ApplyGitattributesResponse, error) // FetchRemote fetches references from a remote repository into the local // repository. FetchRemote(ctx context.Context, in *FetchRemoteRequest, opts ...grpc.CallOption) (*FetchRemoteResponse, error) + // This comment is left unintentionally blank. CreateRepository(ctx context.Context, in *CreateRepositoryRequest, opts ...grpc.CallOption) (*CreateRepositoryResponse, error) + // This comment is left unintentionally blank. GetArchive(ctx context.Context, in *GetArchiveRequest, opts ...grpc.CallOption) (RepositoryService_GetArchiveClient, error) + // This comment is left unintentionally blank. HasLocalBranches(ctx context.Context, in *HasLocalBranchesRequest, opts ...grpc.CallOption) (*HasLocalBranchesResponse, error) // FetchSourceBranch fetches a branch from a second (potentially remote) // repository into the given repository. FetchSourceBranch(ctx context.Context, in *FetchSourceBranchRequest, opts ...grpc.CallOption) (*FetchSourceBranchResponse, error) + // This comment is left unintentionally blank. Fsck(ctx context.Context, in *FsckRequest, opts ...grpc.CallOption) (*FsckResponse, error) + // This comment is left unintentionally blank. WriteRef(ctx context.Context, in *WriteRefRequest, opts ...grpc.CallOption) (*WriteRefResponse, error) + // This comment is left unintentionally blank. FindMergeBase(ctx context.Context, in *FindMergeBaseRequest, opts ...grpc.CallOption) (*FindMergeBaseResponse, error) + // This comment is left unintentionally blank. CreateFork(ctx context.Context, in *CreateForkRequest, opts ...grpc.CallOption) (*CreateForkResponse, error) + // This comment is left unintentionally blank. CreateRepositoryFromURL(ctx context.Context, in *CreateRepositoryFromURLRequest, opts ...grpc.CallOption) (*CreateRepositoryFromURLResponse, error) // CreateBundle creates a bundle from all refs CreateBundle(ctx context.Context, in *CreateBundleRequest, opts ...grpc.CallOption) (RepositoryService_CreateBundleClient, error) @@ -59,29 +74,43 @@ type RepositoryServiceClient interface { // Refs will be mirrored to the target repository with the refspec // "+refs/*:refs/*" and refs that do not exist in the bundle will be removed. FetchBundle(ctx context.Context, opts ...grpc.CallOption) (RepositoryService_FetchBundleClient, error) + // This comment is left unintentionally blank. CreateRepositoryFromBundle(ctx context.Context, opts ...grpc.CallOption) (RepositoryService_CreateRepositoryFromBundleClient, error) // GetConfig reads the target repository's gitconfig and streams its contents // back. Returns a NotFound error in case no gitconfig was found. GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (RepositoryService_GetConfigClient, error) + // This comment is left unintentionally blank. FindLicense(ctx context.Context, in *FindLicenseRequest, opts ...grpc.CallOption) (*FindLicenseResponse, error) + // This comment is left unintentionally blank. GetInfoAttributes(ctx context.Context, in *GetInfoAttributesRequest, opts ...grpc.CallOption) (RepositoryService_GetInfoAttributesClient, error) + // This comment is left unintentionally blank. CalculateChecksum(ctx context.Context, in *CalculateChecksumRequest, opts ...grpc.CallOption) (*CalculateChecksumResponse, error) // Deprecated: Do not use. // Cleanup is deprecated in favor of OptimizeRepository. Cleanup(ctx context.Context, in *CleanupRequest, opts ...grpc.CallOption) (*CleanupResponse, error) + // This comment is left unintentionally blank. GetSnapshot(ctx context.Context, in *GetSnapshotRequest, opts ...grpc.CallOption) (RepositoryService_GetSnapshotClient, error) + // This comment is left unintentionally blank. CreateRepositoryFromSnapshot(ctx context.Context, in *CreateRepositoryFromSnapshotRequest, opts ...grpc.CallOption) (*CreateRepositoryFromSnapshotResponse, error) + // This comment is left unintentionally blank. GetRawChanges(ctx context.Context, in *GetRawChangesRequest, opts ...grpc.CallOption) (RepositoryService_GetRawChangesClient, error) + // This comment is left unintentionally blank. SearchFilesByContent(ctx context.Context, in *SearchFilesByContentRequest, opts ...grpc.CallOption) (RepositoryService_SearchFilesByContentClient, error) + // This comment is left unintentionally blank. SearchFilesByName(ctx context.Context, in *SearchFilesByNameRequest, opts ...grpc.CallOption) (RepositoryService_SearchFilesByNameClient, error) + // This comment is left unintentionally blank. RestoreCustomHooks(ctx context.Context, opts ...grpc.CallOption) (RepositoryService_RestoreCustomHooksClient, error) + // This comment is left unintentionally blank. BackupCustomHooks(ctx context.Context, in *BackupCustomHooksRequest, opts ...grpc.CallOption) (RepositoryService_BackupCustomHooksClient, error) + // This comment is left unintentionally blank. GetObjectDirectorySize(ctx context.Context, in *GetObjectDirectorySizeRequest, opts ...grpc.CallOption) (*GetObjectDirectorySizeResponse, error) // RemoveRepository will move the repository to `+gitaly/tmp/_removed` and // eventually remove it. This ensures that even on networked filesystems the // data is actually removed even if there's someone still handling the data. RemoveRepository(ctx context.Context, in *RemoveRepositoryRequest, opts ...grpc.CallOption) (*RemoveRepositoryResponse, error) + // This comment is left unintentionally blank. RenameRepository(ctx context.Context, in *RenameRepositoryRequest, opts ...grpc.CallOption) (*RenameRepositoryResponse, error) + // This comment is left unintentionally blank. ReplicateRepository(ctx context.Context, in *ReplicateRepositoryRequest, opts ...grpc.CallOption) (*ReplicateRepositoryResponse, error) // OptimizeRepository performs all maintenance tasks in a repository to keep // it in an efficient state. It cleans up stale data, repacks objects, @@ -107,6 +136,9 @@ type RepositoryServiceClient interface { // an admin inspects the repository's gitconfig such that he can easily see // what the repository name is. SetFullPath(ctx context.Context, in *SetFullPathRequest, opts ...grpc.CallOption) (*SetFullPathResponse, error) + // FullPath reads the "gitlab.fullpath" configuration from the repository's + // gitconfig. Returns an error in case the full path has not been configured. + FullPath(ctx context.Context, in *FullPathRequest, opts ...grpc.CallOption) (*FullPathResponse, error) } type repositoryServiceClient struct { @@ -796,10 +828,20 @@ func (c *repositoryServiceClient) SetFullPath(ctx context.Context, in *SetFullPa return out, nil } +func (c *repositoryServiceClient) FullPath(ctx context.Context, in *FullPathRequest, opts ...grpc.CallOption) (*FullPathResponse, error) { + out := new(FullPathResponse) + err := c.cc.Invoke(ctx, "/gitaly.RepositoryService/FullPath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RepositoryServiceServer is the server API for RepositoryService service. // All implementations must embed UnimplementedRepositoryServiceServer // for forward compatibility type RepositoryServiceServer interface { + // This comment is left unintentionally blank. RepositoryExists(context.Context, *RepositoryExistsRequest) (*RepositoryExistsResponse, error) // Deprecated: Do not use. // RepackIncremental is deprecated in favor of OptimizeRepository. @@ -816,21 +858,31 @@ type RepositoryServiceServer interface { // Deprecated: Do not use. // WriteCommitGraph is deprecated in favor of OptimizeRepository. WriteCommitGraph(context.Context, *WriteCommitGraphRequest) (*WriteCommitGraphResponse, error) + // This comment is left unintentionally blank. RepositorySize(context.Context, *RepositorySizeRequest) (*RepositorySizeResponse, error) + // This comment is left unintentionally blank. ApplyGitattributes(context.Context, *ApplyGitattributesRequest) (*ApplyGitattributesResponse, error) // FetchRemote fetches references from a remote repository into the local // repository. FetchRemote(context.Context, *FetchRemoteRequest) (*FetchRemoteResponse, error) + // This comment is left unintentionally blank. CreateRepository(context.Context, *CreateRepositoryRequest) (*CreateRepositoryResponse, error) + // This comment is left unintentionally blank. GetArchive(*GetArchiveRequest, RepositoryService_GetArchiveServer) error + // This comment is left unintentionally blank. HasLocalBranches(context.Context, *HasLocalBranchesRequest) (*HasLocalBranchesResponse, error) // FetchSourceBranch fetches a branch from a second (potentially remote) // repository into the given repository. FetchSourceBranch(context.Context, *FetchSourceBranchRequest) (*FetchSourceBranchResponse, error) + // This comment is left unintentionally blank. Fsck(context.Context, *FsckRequest) (*FsckResponse, error) + // This comment is left unintentionally blank. WriteRef(context.Context, *WriteRefRequest) (*WriteRefResponse, error) + // This comment is left unintentionally blank. FindMergeBase(context.Context, *FindMergeBaseRequest) (*FindMergeBaseResponse, error) + // This comment is left unintentionally blank. CreateFork(context.Context, *CreateForkRequest) (*CreateForkResponse, error) + // This comment is left unintentionally blank. CreateRepositoryFromURL(context.Context, *CreateRepositoryFromURLRequest) (*CreateRepositoryFromURLResponse, error) // CreateBundle creates a bundle from all refs CreateBundle(*CreateBundleRequest, RepositoryService_CreateBundleServer) error @@ -841,29 +893,43 @@ type RepositoryServiceServer interface { // Refs will be mirrored to the target repository with the refspec // "+refs/*:refs/*" and refs that do not exist in the bundle will be removed. FetchBundle(RepositoryService_FetchBundleServer) error + // This comment is left unintentionally blank. CreateRepositoryFromBundle(RepositoryService_CreateRepositoryFromBundleServer) error // GetConfig reads the target repository's gitconfig and streams its contents // back. Returns a NotFound error in case no gitconfig was found. GetConfig(*GetConfigRequest, RepositoryService_GetConfigServer) error + // This comment is left unintentionally blank. FindLicense(context.Context, *FindLicenseRequest) (*FindLicenseResponse, error) + // This comment is left unintentionally blank. GetInfoAttributes(*GetInfoAttributesRequest, RepositoryService_GetInfoAttributesServer) error + // This comment is left unintentionally blank. CalculateChecksum(context.Context, *CalculateChecksumRequest) (*CalculateChecksumResponse, error) // Deprecated: Do not use. // Cleanup is deprecated in favor of OptimizeRepository. Cleanup(context.Context, *CleanupRequest) (*CleanupResponse, error) + // This comment is left unintentionally blank. GetSnapshot(*GetSnapshotRequest, RepositoryService_GetSnapshotServer) error + // This comment is left unintentionally blank. CreateRepositoryFromSnapshot(context.Context, *CreateRepositoryFromSnapshotRequest) (*CreateRepositoryFromSnapshotResponse, error) + // This comment is left unintentionally blank. GetRawChanges(*GetRawChangesRequest, RepositoryService_GetRawChangesServer) error + // This comment is left unintentionally blank. SearchFilesByContent(*SearchFilesByContentRequest, RepositoryService_SearchFilesByContentServer) error + // This comment is left unintentionally blank. SearchFilesByName(*SearchFilesByNameRequest, RepositoryService_SearchFilesByNameServer) error + // This comment is left unintentionally blank. RestoreCustomHooks(RepositoryService_RestoreCustomHooksServer) error + // This comment is left unintentionally blank. BackupCustomHooks(*BackupCustomHooksRequest, RepositoryService_BackupCustomHooksServer) error + // This comment is left unintentionally blank. GetObjectDirectorySize(context.Context, *GetObjectDirectorySizeRequest) (*GetObjectDirectorySizeResponse, error) // RemoveRepository will move the repository to `+gitaly/tmp/_removed` and // eventually remove it. This ensures that even on networked filesystems the // data is actually removed even if there's someone still handling the data. RemoveRepository(context.Context, *RemoveRepositoryRequest) (*RemoveRepositoryResponse, error) + // This comment is left unintentionally blank. RenameRepository(context.Context, *RenameRepositoryRequest) (*RenameRepositoryResponse, error) + // This comment is left unintentionally blank. ReplicateRepository(context.Context, *ReplicateRepositoryRequest) (*ReplicateRepositoryResponse, error) // OptimizeRepository performs all maintenance tasks in a repository to keep // it in an efficient state. It cleans up stale data, repacks objects, @@ -889,6 +955,9 @@ type RepositoryServiceServer interface { // an admin inspects the repository's gitconfig such that he can easily see // what the repository name is. SetFullPath(context.Context, *SetFullPathRequest) (*SetFullPathResponse, error) + // FullPath reads the "gitlab.fullpath" configuration from the repository's + // gitconfig. Returns an error in case the full path has not been configured. + FullPath(context.Context, *FullPathRequest) (*FullPathResponse, error) mustEmbedUnimplementedRepositoryServiceServer() } @@ -1019,6 +1088,9 @@ func (UnimplementedRepositoryServiceServer) PruneUnreachableObjects(context.Cont func (UnimplementedRepositoryServiceServer) SetFullPath(context.Context, *SetFullPathRequest) (*SetFullPathResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SetFullPath not implemented") } +func (UnimplementedRepositoryServiceServer) FullPath(context.Context, *FullPathRequest) (*FullPathResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FullPath not implemented") +} func (UnimplementedRepositoryServiceServer) mustEmbedUnimplementedRepositoryServiceServer() {} // UnsafeRepositoryServiceServer may be embedded to opt out of forward compatibility for this service. @@ -1829,6 +1901,24 @@ func _RepositoryService_SetFullPath_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _RepositoryService_FullPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FullPathRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).FullPath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gitaly.RepositoryService/FullPath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).FullPath(ctx, req.(*FullPathRequest)) + } + return interceptor(ctx, in, info, handler) +} + // RepositoryService_ServiceDesc is the grpc.ServiceDesc for RepositoryService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1948,6 +2038,10 @@ var RepositoryService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SetFullPath", Handler: _RepositoryService_SetFullPath_Handler, }, + { + MethodName: "FullPath", + Handler: _RepositoryService_FullPath_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -2017,5 +2111,5 @@ var RepositoryService_ServiceDesc = grpc.ServiceDesc{ ServerStreams: true, }, }, - Metadata: "repository-service.proto", + Metadata: "repository.proto", } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server.pb.go new file mode 100644 index 0000000000..00c93809ae --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server.pb.go @@ -0,0 +1,1120 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.21.1 +// source: server.proto + +package gitalypb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This comment is left unintentionally blank. +type ServerInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ServerInfoRequest) Reset() { + *x = ServerInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerInfoRequest) ProtoMessage() {} + +func (x *ServerInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerInfoRequest.ProtoReflect.Descriptor instead. +func (*ServerInfoRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{0} +} + +// This comment is left unintentionally blank. +type ServerInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // This comment is left unintentionally blank. + ServerVersion string `protobuf:"bytes,1,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"` + // This comment is left unintentionally blank. + GitVersion string `protobuf:"bytes,2,opt,name=git_version,json=gitVersion,proto3" json:"git_version,omitempty"` + // This comment is left unintentionally blank. + StorageStatuses []*ServerInfoResponse_StorageStatus `protobuf:"bytes,3,rep,name=storage_statuses,json=storageStatuses,proto3" json:"storage_statuses,omitempty"` +} + +func (x *ServerInfoResponse) Reset() { + *x = ServerInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerInfoResponse) ProtoMessage() {} + +func (x *ServerInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerInfoResponse.ProtoReflect.Descriptor instead. +func (*ServerInfoResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{1} +} + +func (x *ServerInfoResponse) GetServerVersion() string { + if x != nil { + return x.ServerVersion + } + return "" +} + +func (x *ServerInfoResponse) GetGitVersion() string { + if x != nil { + return x.GitVersion + } + return "" +} + +func (x *ServerInfoResponse) GetStorageStatuses() []*ServerInfoResponse_StorageStatus { + if x != nil { + return x.StorageStatuses + } + return nil +} + +// This comment is left unintentionally blank. +type DiskStatisticsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DiskStatisticsRequest) Reset() { + *x = DiskStatisticsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiskStatisticsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiskStatisticsRequest) ProtoMessage() {} + +func (x *DiskStatisticsRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiskStatisticsRequest.ProtoReflect.Descriptor instead. +func (*DiskStatisticsRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{2} +} + +// This comment is left unintentionally blank. +type DiskStatisticsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // This comment is left unintentionally blank. + StorageStatuses []*DiskStatisticsResponse_StorageStatus `protobuf:"bytes,1,rep,name=storage_statuses,json=storageStatuses,proto3" json:"storage_statuses,omitempty"` +} + +func (x *DiskStatisticsResponse) Reset() { + *x = DiskStatisticsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiskStatisticsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiskStatisticsResponse) ProtoMessage() {} + +func (x *DiskStatisticsResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiskStatisticsResponse.ProtoReflect.Descriptor instead. +func (*DiskStatisticsResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{3} +} + +func (x *DiskStatisticsResponse) GetStorageStatuses() []*DiskStatisticsResponse_StorageStatus { + if x != nil { + return x.StorageStatuses + } + return nil +} + +// ClockSyncedRequest contains settings to be used for the system clock synchronisation check. +type ClockSyncedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // NtpHost is a URL to the external NTP service that should be used for clock sync check. + // Default is "ntp.pool.org" + NtpHost string `protobuf:"bytes,1,opt,name=ntp_host,json=ntpHost,proto3" json:"ntp_host,omitempty"` + // DriftThreshold is an allowed drift from the NTP service. + DriftThreshold *durationpb.Duration `protobuf:"bytes,3,opt,name=drift_threshold,json=driftThreshold,proto3" json:"drift_threshold,omitempty"` +} + +func (x *ClockSyncedRequest) Reset() { + *x = ClockSyncedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClockSyncedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClockSyncedRequest) ProtoMessage() {} + +func (x *ClockSyncedRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClockSyncedRequest.ProtoReflect.Descriptor instead. +func (*ClockSyncedRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{4} +} + +func (x *ClockSyncedRequest) GetNtpHost() string { + if x != nil { + return x.NtpHost + } + return "" +} + +func (x *ClockSyncedRequest) GetDriftThreshold() *durationpb.Duration { + if x != nil { + return x.DriftThreshold + } + return nil +} + +// ClockSyncedRequest represents result of the system clock synchronisation check. +type ClockSyncedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Synced is set to true if system clock has an affordable drift compared to NTP service. + Synced bool `protobuf:"varint,1,opt,name=synced,proto3" json:"synced,omitempty"` +} + +func (x *ClockSyncedResponse) Reset() { + *x = ClockSyncedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClockSyncedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClockSyncedResponse) ProtoMessage() {} + +func (x *ClockSyncedResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClockSyncedResponse.ProtoReflect.Descriptor instead. +func (*ClockSyncedResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{5} +} + +func (x *ClockSyncedResponse) GetSynced() bool { + if x != nil { + return x.Synced + } + return false +} + +// ReadinessCheckRequest is used to verify if the service is in operational state. +type ReadinessCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timeout is an amount of milliseconds for the check to run before give up and mark as failed. + Timeout *durationpb.Duration `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` +} + +func (x *ReadinessCheckRequest) Reset() { + *x = ReadinessCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadinessCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadinessCheckRequest) ProtoMessage() {} + +func (x *ReadinessCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadinessCheckRequest.ProtoReflect.Descriptor instead. +func (*ReadinessCheckRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{6} +} + +func (x *ReadinessCheckRequest) GetTimeout() *durationpb.Duration { + if x != nil { + return x.Timeout + } + return nil +} + +// ReadinessCheckResponse is just a stub now and contains no information. +// If the service is not in the operational state the error will be returned instead. +type ReadinessCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Result: + // *ReadinessCheckResponse_OkResponse + // *ReadinessCheckResponse_FailureResponse + Result isReadinessCheckResponse_Result `protobuf_oneof:"Result"` +} + +func (x *ReadinessCheckResponse) Reset() { + *x = ReadinessCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadinessCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadinessCheckResponse) ProtoMessage() {} + +func (x *ReadinessCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadinessCheckResponse.ProtoReflect.Descriptor instead. +func (*ReadinessCheckResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{7} +} + +func (m *ReadinessCheckResponse) GetResult() isReadinessCheckResponse_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *ReadinessCheckResponse) GetOkResponse() *ReadinessCheckResponse_Ok { + if x, ok := x.GetResult().(*ReadinessCheckResponse_OkResponse); ok { + return x.OkResponse + } + return nil +} + +func (x *ReadinessCheckResponse) GetFailureResponse() *ReadinessCheckResponse_Failure { + if x, ok := x.GetResult().(*ReadinessCheckResponse_FailureResponse); ok { + return x.FailureResponse + } + return nil +} + +type isReadinessCheckResponse_Result interface { + isReadinessCheckResponse_Result() +} + +type ReadinessCheckResponse_OkResponse struct { + // OkResponse is set when all checks pass. + OkResponse *ReadinessCheckResponse_Ok `protobuf:"bytes,1,opt,name=ok_response,json=okResponse,proto3,oneof"` +} + +type ReadinessCheckResponse_FailureResponse struct { + // FailureResponse is set if at least one check failed. + FailureResponse *ReadinessCheckResponse_Failure `protobuf:"bytes,2,opt,name=failure_response,json=failureResponse,proto3,oneof"` +} + +func (*ReadinessCheckResponse_OkResponse) isReadinessCheckResponse_Result() {} + +func (*ReadinessCheckResponse_FailureResponse) isReadinessCheckResponse_Result() {} + +// This comment is left unintentionally blank. +type ServerInfoResponse_StorageStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // This comment is left unintentionally blank. + StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` + // This comment is left unintentionally blank. + Readable bool `protobuf:"varint,2,opt,name=readable,proto3" json:"readable,omitempty"` + // This comment is left unintentionally blank. + Writeable bool `protobuf:"varint,3,opt,name=writeable,proto3" json:"writeable,omitempty"` + // This comment is left unintentionally blank. + FsType string `protobuf:"bytes,4,opt,name=fs_type,json=fsType,proto3" json:"fs_type,omitempty"` + // This comment is left unintentionally blank. + FilesystemId string `protobuf:"bytes,5,opt,name=filesystem_id,json=filesystemId,proto3" json:"filesystem_id,omitempty"` + // This comment is left unintentionally blank. + ReplicationFactor uint32 `protobuf:"varint,6,opt,name=replication_factor,json=replicationFactor,proto3" json:"replication_factor,omitempty"` +} + +func (x *ServerInfoResponse_StorageStatus) Reset() { + *x = ServerInfoResponse_StorageStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerInfoResponse_StorageStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerInfoResponse_StorageStatus) ProtoMessage() {} + +func (x *ServerInfoResponse_StorageStatus) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerInfoResponse_StorageStatus.ProtoReflect.Descriptor instead. +func (*ServerInfoResponse_StorageStatus) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *ServerInfoResponse_StorageStatus) GetStorageName() string { + if x != nil { + return x.StorageName + } + return "" +} + +func (x *ServerInfoResponse_StorageStatus) GetReadable() bool { + if x != nil { + return x.Readable + } + return false +} + +func (x *ServerInfoResponse_StorageStatus) GetWriteable() bool { + if x != nil { + return x.Writeable + } + return false +} + +func (x *ServerInfoResponse_StorageStatus) GetFsType() string { + if x != nil { + return x.FsType + } + return "" +} + +func (x *ServerInfoResponse_StorageStatus) GetFilesystemId() string { + if x != nil { + return x.FilesystemId + } + return "" +} + +func (x *ServerInfoResponse_StorageStatus) GetReplicationFactor() uint32 { + if x != nil { + return x.ReplicationFactor + } + return 0 +} + +// This comment is left unintentionally blank. +type DiskStatisticsResponse_StorageStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // When both available and used fields are equal 0 that means that + // Gitaly was unable to determine storage stats. + StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` + // This comment is left unintentionally blank. + Available int64 `protobuf:"varint,2,opt,name=available,proto3" json:"available,omitempty"` + // This comment is left unintentionally blank. + Used int64 `protobuf:"varint,3,opt,name=used,proto3" json:"used,omitempty"` +} + +func (x *DiskStatisticsResponse_StorageStatus) Reset() { + *x = DiskStatisticsResponse_StorageStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiskStatisticsResponse_StorageStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiskStatisticsResponse_StorageStatus) ProtoMessage() {} + +func (x *DiskStatisticsResponse_StorageStatus) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiskStatisticsResponse_StorageStatus.ProtoReflect.Descriptor instead. +func (*DiskStatisticsResponse_StorageStatus) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *DiskStatisticsResponse_StorageStatus) GetStorageName() string { + if x != nil { + return x.StorageName + } + return "" +} + +func (x *DiskStatisticsResponse_StorageStatus) GetAvailable() int64 { + if x != nil { + return x.Available + } + return 0 +} + +func (x *DiskStatisticsResponse_StorageStatus) GetUsed() int64 { + if x != nil { + return x.Used + } + return 0 +} + +// Ok represents response if none checks failed. +type ReadinessCheckResponse_Ok struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReadinessCheckResponse_Ok) Reset() { + *x = ReadinessCheckResponse_Ok{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadinessCheckResponse_Ok) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadinessCheckResponse_Ok) ProtoMessage() {} + +func (x *ReadinessCheckResponse_Ok) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadinessCheckResponse_Ok.ProtoReflect.Descriptor instead. +func (*ReadinessCheckResponse_Ok) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{7, 0} +} + +// Failure represents response if at least one check failed. +type ReadinessCheckResponse_Failure struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FailedChecks is a list of failed checks. + FailedChecks []*ReadinessCheckResponse_Failure_Response `protobuf:"bytes,1,rep,name=failed_checks,json=failedChecks,proto3" json:"failed_checks,omitempty"` +} + +func (x *ReadinessCheckResponse_Failure) Reset() { + *x = ReadinessCheckResponse_Failure{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadinessCheckResponse_Failure) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadinessCheckResponse_Failure) ProtoMessage() {} + +func (x *ReadinessCheckResponse_Failure) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadinessCheckResponse_Failure.ProtoReflect.Descriptor instead. +func (*ReadinessCheckResponse_Failure) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *ReadinessCheckResponse_Failure) GetFailedChecks() []*ReadinessCheckResponse_Failure_Response { + if x != nil { + return x.FailedChecks + } + return nil +} + +// Response contains information about failed check. +type ReadinessCheckResponse_Failure_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name is a name of the check that was performed. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // ErrorMessage is a cause of the check failure. + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` +} + +func (x *ReadinessCheckResponse_Failure_Response) Reset() { + *x = ReadinessCheckResponse_Failure_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadinessCheckResponse_Failure_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadinessCheckResponse_Failure_Response) ProtoMessage() {} + +func (x *ReadinessCheckResponse_Failure_Response) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadinessCheckResponse_Failure_Response.ProtoReflect.Descriptor instead. +func (*ReadinessCheckResponse_Failure_Response) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{7, 1, 0} +} + +func (x *ReadinessCheckResponse_Failure_Response) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ReadinessCheckResponse_Failure_Response) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +var File_server_proto protoreflect.FileDescriptor + +var file_server_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x69, 0x74, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x69, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x1a, 0xd9, 0x01, 0x0a, 0x0d, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x73, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xd7, 0x01, 0x0a, 0x16, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, + 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x76, 0x61, + 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x12, 0x43, + 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x74, 0x70, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x74, 0x70, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0f, + 0x64, 0x72, 0x69, 0x66, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0e, 0x64, 0x72, 0x69, 0x66, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x16, 0x64, 0x72, 0x69, 0x66, 0x74, 0x5f, 0x74, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x22, 0x2d, + 0x0a, 0x13, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x22, 0x4c, 0x0a, + 0x15, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xea, 0x02, 0x0a, 0x16, + 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x6b, 0x48, 0x00, + 0x52, 0x0a, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, + 0x52, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x04, 0x0a, 0x02, 0x4f, 0x6b, 0x1a, 0xa4, 0x01, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x12, 0x54, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, + 0x72, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0c, 0x66, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, + 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0xc4, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4f, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, 0x12, + 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, + 0x6e, 0x63, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x42, + 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, + 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, + 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_server_proto_rawDescOnce sync.Once + file_server_proto_rawDescData = file_server_proto_rawDesc +) + +func file_server_proto_rawDescGZIP() []byte { + file_server_proto_rawDescOnce.Do(func() { + file_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_server_proto_rawDescData) + }) + return file_server_proto_rawDescData +} + +var file_server_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_server_proto_goTypes = []interface{}{ + (*ServerInfoRequest)(nil), // 0: gitaly.ServerInfoRequest + (*ServerInfoResponse)(nil), // 1: gitaly.ServerInfoResponse + (*DiskStatisticsRequest)(nil), // 2: gitaly.DiskStatisticsRequest + (*DiskStatisticsResponse)(nil), // 3: gitaly.DiskStatisticsResponse + (*ClockSyncedRequest)(nil), // 4: gitaly.ClockSyncedRequest + (*ClockSyncedResponse)(nil), // 5: gitaly.ClockSyncedResponse + (*ReadinessCheckRequest)(nil), // 6: gitaly.ReadinessCheckRequest + (*ReadinessCheckResponse)(nil), // 7: gitaly.ReadinessCheckResponse + (*ServerInfoResponse_StorageStatus)(nil), // 8: gitaly.ServerInfoResponse.StorageStatus + (*DiskStatisticsResponse_StorageStatus)(nil), // 9: gitaly.DiskStatisticsResponse.StorageStatus + (*ReadinessCheckResponse_Ok)(nil), // 10: gitaly.ReadinessCheckResponse.Ok + (*ReadinessCheckResponse_Failure)(nil), // 11: gitaly.ReadinessCheckResponse.Failure + (*ReadinessCheckResponse_Failure_Response)(nil), // 12: gitaly.ReadinessCheckResponse.Failure.Response + (*durationpb.Duration)(nil), // 13: google.protobuf.Duration +} +var file_server_proto_depIdxs = []int32{ + 8, // 0: gitaly.ServerInfoResponse.storage_statuses:type_name -> gitaly.ServerInfoResponse.StorageStatus + 9, // 1: gitaly.DiskStatisticsResponse.storage_statuses:type_name -> gitaly.DiskStatisticsResponse.StorageStatus + 13, // 2: gitaly.ClockSyncedRequest.drift_threshold:type_name -> google.protobuf.Duration + 13, // 3: gitaly.ReadinessCheckRequest.timeout:type_name -> google.protobuf.Duration + 10, // 4: gitaly.ReadinessCheckResponse.ok_response:type_name -> gitaly.ReadinessCheckResponse.Ok + 11, // 5: gitaly.ReadinessCheckResponse.failure_response:type_name -> gitaly.ReadinessCheckResponse.Failure + 12, // 6: gitaly.ReadinessCheckResponse.Failure.failed_checks:type_name -> gitaly.ReadinessCheckResponse.Failure.Response + 0, // 7: gitaly.ServerService.ServerInfo:input_type -> gitaly.ServerInfoRequest + 2, // 8: gitaly.ServerService.DiskStatistics:input_type -> gitaly.DiskStatisticsRequest + 4, // 9: gitaly.ServerService.ClockSynced:input_type -> gitaly.ClockSyncedRequest + 6, // 10: gitaly.ServerService.ReadinessCheck:input_type -> gitaly.ReadinessCheckRequest + 1, // 11: gitaly.ServerService.ServerInfo:output_type -> gitaly.ServerInfoResponse + 3, // 12: gitaly.ServerService.DiskStatistics:output_type -> gitaly.DiskStatisticsResponse + 5, // 13: gitaly.ServerService.ClockSynced:output_type -> gitaly.ClockSyncedResponse + 7, // 14: gitaly.ServerService.ReadinessCheck:output_type -> gitaly.ReadinessCheckResponse + 11, // [11:15] is the sub-list for method output_type + 7, // [7:11] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_server_proto_init() } +func file_server_proto_init() { + if File_server_proto != nil { + return + } + file_lint_proto_init() + if !protoimpl.UnsafeEnabled { + file_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerInfoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiskStatisticsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiskStatisticsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClockSyncedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClockSyncedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadinessCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadinessCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerInfoResponse_StorageStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiskStatisticsResponse_StorageStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadinessCheckResponse_Ok); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadinessCheckResponse_Failure); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadinessCheckResponse_Failure_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_server_proto_msgTypes[7].OneofWrappers = []interface{}{ + (*ReadinessCheckResponse_OkResponse)(nil), + (*ReadinessCheckResponse_FailureResponse)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_server_proto_rawDesc, + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_server_proto_goTypes, + DependencyIndexes: file_server_proto_depIdxs, + MessageInfos: file_server_proto_msgTypes, + }.Build() + File_server_proto = out.File + file_server_proto_rawDesc = nil + file_server_proto_goTypes = nil + file_server_proto_depIdxs = nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server_grpc.pb.go similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server_grpc.pb.go index 7c23f806f7..ac706dd5d8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/server_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/server_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: server.proto package gitalypb @@ -18,11 +22,15 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ServerServiceClient interface { + // This comment is left unintentionally blank. ServerInfo(ctx context.Context, in *ServerInfoRequest, opts ...grpc.CallOption) (*ServerInfoResponse, error) + // This comment is left unintentionally blank. DiskStatistics(ctx context.Context, in *DiskStatisticsRequest, opts ...grpc.CallOption) (*DiskStatisticsResponse, error) // ClockSynced checks if machine clock is synced // (the offset is less that the one passed in the request). ClockSynced(ctx context.Context, in *ClockSyncedRequest, opts ...grpc.CallOption) (*ClockSyncedResponse, error) + // ReadinessCheck runs the set of the checks to make sure service is in operational state. + ReadinessCheck(ctx context.Context, in *ReadinessCheckRequest, opts ...grpc.CallOption) (*ReadinessCheckResponse, error) } type serverServiceClient struct { @@ -60,15 +68,28 @@ func (c *serverServiceClient) ClockSynced(ctx context.Context, in *ClockSyncedRe return out, nil } +func (c *serverServiceClient) ReadinessCheck(ctx context.Context, in *ReadinessCheckRequest, opts ...grpc.CallOption) (*ReadinessCheckResponse, error) { + out := new(ReadinessCheckResponse) + err := c.cc.Invoke(ctx, "/gitaly.ServerService/ReadinessCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ServerServiceServer is the server API for ServerService service. // All implementations must embed UnimplementedServerServiceServer // for forward compatibility type ServerServiceServer interface { + // This comment is left unintentionally blank. ServerInfo(context.Context, *ServerInfoRequest) (*ServerInfoResponse, error) + // This comment is left unintentionally blank. DiskStatistics(context.Context, *DiskStatisticsRequest) (*DiskStatisticsResponse, error) // ClockSynced checks if machine clock is synced // (the offset is less that the one passed in the request). ClockSynced(context.Context, *ClockSyncedRequest) (*ClockSyncedResponse, error) + // ReadinessCheck runs the set of the checks to make sure service is in operational state. + ReadinessCheck(context.Context, *ReadinessCheckRequest) (*ReadinessCheckResponse, error) mustEmbedUnimplementedServerServiceServer() } @@ -85,6 +106,9 @@ func (UnimplementedServerServiceServer) DiskStatistics(context.Context, *DiskSta func (UnimplementedServerServiceServer) ClockSynced(context.Context, *ClockSyncedRequest) (*ClockSyncedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ClockSynced not implemented") } +func (UnimplementedServerServiceServer) ReadinessCheck(context.Context, *ReadinessCheckRequest) (*ReadinessCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadinessCheck not implemented") +} func (UnimplementedServerServiceServer) mustEmbedUnimplementedServerServiceServer() {} // UnsafeServerServiceServer may be embedded to opt out of forward compatibility for this service. @@ -152,6 +176,24 @@ func _ServerService_ClockSynced_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _ServerService_ReadinessCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadinessCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServerServiceServer).ReadinessCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gitaly.ServerService/ReadinessCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServerServiceServer).ReadinessCheck(ctx, req.(*ReadinessCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ServerService_ServiceDesc is the grpc.ServiceDesc for ServerService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -171,6 +213,10 @@ var ServerService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ClockSynced", Handler: _ServerService_ClockSynced_Handler, }, + { + MethodName: "ReadinessCheck", + Handler: _ServerService_ReadinessCheck_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "server.proto", diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/shared.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/shared.pb.go similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/shared.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/shared.pb.go index 47098ee0b3..cd8ced3a87 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/shared.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/shared.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: shared.proto package gitalypb @@ -21,14 +21,20 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type ObjectType int32 const ( - ObjectType_UNKNOWN ObjectType = 0 - ObjectType_COMMIT ObjectType = 1 - ObjectType_BLOB ObjectType = 2 - ObjectType_TREE ObjectType = 3 - ObjectType_TAG ObjectType = 4 + // This comment is left unintentionally blank. + ObjectType_UNKNOWN ObjectType = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ObjectType_COMMIT ObjectType = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ObjectType_BLOB ObjectType = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ObjectType_TREE ObjectType = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ObjectType_TAG ObjectType = 4 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for ObjectType. @@ -76,13 +82,18 @@ func (ObjectType) EnumDescriptor() ([]byte, []int) { return file_shared_proto_rawDescGZIP(), []int{0} } +// This comment is left unintentionally blank. type SignatureType int32 const ( - SignatureType_NONE SignatureType = 0 - SignatureType_PGP SignatureType = 1 - SignatureType_X509 SignatureType = 2 - SignatureType_SSH SignatureType = 3 // maybe add X509+TSA or other combinations at a later step + // This comment is left unintentionally blank. + SignatureType_NONE SignatureType = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + SignatureType_PGP SignatureType = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + SignatureType_X509 SignatureType = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + SignatureType_SSH SignatureType = 3 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for SignatureType. @@ -133,9 +144,9 @@ type SortDirection int32 const ( // ASCENDING sorts by the sort key in ascending order. - SortDirection_ASCENDING SortDirection = 0 + SortDirection_ASCENDING SortDirection = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // DESCENDING sorts by the sort key in descending order. - SortDirection_DESCENDING SortDirection = 1 + SortDirection_DESCENDING SortDirection = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for SortDirection. @@ -177,12 +188,15 @@ func (SortDirection) EnumDescriptor() ([]byte, []int) { return file_shared_proto_rawDescGZIP(), []int{2} } +// This comment is left unintentionally blank. type Repository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StorageName string `protobuf:"bytes,2,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` + // This comment is left unintentionally blank. + StorageName string `protobuf:"bytes,2,opt,name=storage_name,json=storageName,proto3" json:"storage_name,omitempty"` + // This comment is left unintentionally blank. RelativePath string `protobuf:"bytes,3,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` // Sets the GIT_OBJECT_DIRECTORY envvar on git commands to the value of this field. // It influences the object storage directory the SHA1 directories are created underneath. @@ -335,22 +349,96 @@ func (x *CommitTrailer) GetValue() []byte { return nil } +// CommitStatInfo includes the number of changed lines and files in the commit. +type CommitStatInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // additions is the number of line additions in the commit. + Additions int32 `protobuf:"varint,1,opt,name=additions,proto3" json:"additions,omitempty"` + // deletions is the number of lines deleted in the commit. + Deletions int32 `protobuf:"varint,2,opt,name=deletions,proto3" json:"deletions,omitempty"` + // changed_files is the number of files changed in the commit. + ChangedFiles int32 `protobuf:"varint,3,opt,name=changed_files,json=changedFiles,proto3" json:"changed_files,omitempty"` +} + +func (x *CommitStatInfo) Reset() { + *x = CommitStatInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_shared_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitStatInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitStatInfo) ProtoMessage() {} + +func (x *CommitStatInfo) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommitStatInfo.ProtoReflect.Descriptor instead. +func (*CommitStatInfo) Descriptor() ([]byte, []int) { + return file_shared_proto_rawDescGZIP(), []int{2} +} + +func (x *CommitStatInfo) GetAdditions() int32 { + if x != nil { + return x.Additions + } + return 0 +} + +func (x *CommitStatInfo) GetDeletions() int32 { + if x != nil { + return x.Deletions + } + return 0 +} + +func (x *CommitStatInfo) GetChangedFiles() int32 { + if x != nil { + return x.ChangedFiles + } + return 0 +} + // Corresponds to Gitlab::Git::Commit type GitCommit struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Subject []byte `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` - Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` - Author *CommitAuthor `protobuf:"bytes,4,opt,name=author,proto3" json:"author,omitempty"` + // This comment is left unintentionally blank. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // This comment is left unintentionally blank. + Subject []byte `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + // This comment is left unintentionally blank. + Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` + // This comment is left unintentionally blank. + Author *CommitAuthor `protobuf:"bytes,4,opt,name=author,proto3" json:"author,omitempty"` + // This comment is left unintentionally blank. Committer *CommitAuthor `protobuf:"bytes,5,opt,name=committer,proto3" json:"committer,omitempty"` - ParentIds []string `protobuf:"bytes,6,rep,name=parent_ids,json=parentIds,proto3" json:"parent_ids,omitempty"` + // This comment is left unintentionally blank. + ParentIds []string `protobuf:"bytes,6,rep,name=parent_ids,json=parentIds,proto3" json:"parent_ids,omitempty"` // If body exceeds a certain threshold, it will be nullified, // but its size will be set in body_size so we can know if // a commit had a body in the first place. - BodySize int64 `protobuf:"varint,7,opt,name=body_size,json=bodySize,proto3" json:"body_size,omitempty"` + BodySize int64 `protobuf:"varint,7,opt,name=body_size,json=bodySize,proto3" json:"body_size,omitempty"` + // This comment is left unintentionally blank. SignatureType SignatureType `protobuf:"varint,8,opt,name=signature_type,json=signatureType,proto3,enum=gitaly.SignatureType" json:"signature_type,omitempty"` // The tree ID will always be filled, even if the tree is empty. In that case // the value will be `4b825dc642cb6eb9a060e54bf8d69288fbee4904`. @@ -361,12 +449,15 @@ type GitCommit struct { // sizes are limited. If a trailer exceeds these size limits, it and any // trailers that follow it are not included. Trailers []*CommitTrailer `protobuf:"bytes,10,rep,name=trailers,proto3" json:"trailers,omitempty"` + // The stats include additions, deletions and changed_files, + // they are only set when `include_shortstat == true`. + ShortStats *CommitStatInfo `protobuf:"bytes,11,opt,name=short_stats,json=shortStats,proto3" json:"short_stats,omitempty"` } func (x *GitCommit) Reset() { *x = GitCommit{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[2] + mi := &file_shared_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -379,7 +470,7 @@ func (x *GitCommit) String() string { func (*GitCommit) ProtoMessage() {} func (x *GitCommit) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[2] + mi := &file_shared_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -392,7 +483,7 @@ func (x *GitCommit) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommit.ProtoReflect.Descriptor instead. func (*GitCommit) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{2} + return file_shared_proto_rawDescGZIP(), []int{3} } func (x *GitCommit) GetId() string { @@ -465,21 +556,33 @@ func (x *GitCommit) GetTrailers() []*CommitTrailer { return nil } +func (x *GitCommit) GetShortStats() *CommitStatInfo { + if x != nil { + return x.ShortStats + } + return nil +} + +// This comment is left unintentionally blank. type CommitAuthor struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` - Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"` - Timezone []byte `protobuf:"bytes,4,opt,name=timezone,proto3" json:"timezone,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // This comment is left unintentionally blank. + Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"` + // This comment is left unintentionally blank. + Timezone []byte `protobuf:"bytes,4,opt,name=timezone,proto3" json:"timezone,omitempty"` } func (x *CommitAuthor) Reset() { *x = CommitAuthor{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[3] + mi := &file_shared_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -492,7 +595,7 @@ func (x *CommitAuthor) String() string { func (*CommitAuthor) ProtoMessage() {} func (x *CommitAuthor) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[3] + mi := &file_shared_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -505,7 +608,7 @@ func (x *CommitAuthor) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitAuthor.ProtoReflect.Descriptor instead. func (*CommitAuthor) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{3} + return file_shared_proto_rawDescGZIP(), []int{4} } func (x *CommitAuthor) GetName() []byte { @@ -536,18 +639,20 @@ func (x *CommitAuthor) GetTimezone() []byte { return nil } +// This comment is left unintentionally blank. type ExitStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` } func (x *ExitStatus) Reset() { *x = ExitStatus{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[4] + mi := &file_shared_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -560,7 +665,7 @@ func (x *ExitStatus) String() string { func (*ExitStatus) ProtoMessage() {} func (x *ExitStatus) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[4] + mi := &file_shared_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -573,7 +678,7 @@ func (x *ExitStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ExitStatus.ProtoReflect.Descriptor instead. func (*ExitStatus) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{4} + return file_shared_proto_rawDescGZIP(), []int{5} } func (x *ExitStatus) GetValue() int32 { @@ -589,14 +694,16 @@ type Branch struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. TargetCommit *GitCommit `protobuf:"bytes,2,opt,name=target_commit,json=targetCommit,proto3" json:"target_commit,omitempty"` } func (x *Branch) Reset() { *x = Branch{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[5] + mi := &file_shared_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -609,7 +716,7 @@ func (x *Branch) String() string { func (*Branch) ProtoMessage() {} func (x *Branch) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[5] + mi := &file_shared_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -622,7 +729,7 @@ func (x *Branch) ProtoReflect() protoreflect.Message { // Deprecated: Use Branch.ProtoReflect.Descriptor instead. func (*Branch) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{5} + return file_shared_proto_rawDescGZIP(), []int{6} } func (x *Branch) GetName() []byte { @@ -639,27 +746,34 @@ func (x *Branch) GetTargetCommit() *GitCommit { return nil } +// This comment is left unintentionally blank. type Tag struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // This comment is left unintentionally blank. TargetCommit *GitCommit `protobuf:"bytes,3,opt,name=target_commit,json=targetCommit,proto3" json:"target_commit,omitempty"` // If message exceeds a certain threshold, it will be nullified, // but its size will be set in message_size so we can know if // a tag had a message in the first place. - Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` - MessageSize int64 `protobuf:"varint,5,opt,name=message_size,json=messageSize,proto3" json:"message_size,omitempty"` - Tagger *CommitAuthor `protobuf:"bytes,6,opt,name=tagger,proto3" json:"tagger,omitempty"` + Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` + // This comment is left unintentionally blank. + MessageSize int64 `protobuf:"varint,5,opt,name=message_size,json=messageSize,proto3" json:"message_size,omitempty"` + // This comment is left unintentionally blank. + Tagger *CommitAuthor `protobuf:"bytes,6,opt,name=tagger,proto3" json:"tagger,omitempty"` + // This comment is left unintentionally blank. SignatureType SignatureType `protobuf:"varint,7,opt,name=signature_type,json=signatureType,proto3,enum=gitaly.SignatureType" json:"signature_type,omitempty"` } func (x *Tag) Reset() { *x = Tag{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[6] + mi := &file_shared_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -672,7 +786,7 @@ func (x *Tag) String() string { func (*Tag) ProtoMessage() {} func (x *Tag) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[6] + mi := &file_shared_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -685,7 +799,7 @@ func (x *Tag) ProtoReflect() protoreflect.Message { // Deprecated: Use Tag.ProtoReflect.Descriptor instead. func (*Tag) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{6} + return file_shared_proto_rawDescGZIP(), []int{7} } func (x *Tag) GetName() []byte { @@ -737,14 +851,19 @@ func (x *Tag) GetSignatureType() SignatureType { return SignatureType_NONE } +// This comment is left unintentionally blank. type User struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GlId string `protobuf:"bytes,1,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` - Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Email []byte `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + // This comment is left unintentionally blank. + GlId string `protobuf:"bytes,1,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Email []byte `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + // This comment is left unintentionally blank. GlUsername string `protobuf:"bytes,4,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` // Timezone is the timezone as configured by the user in the web interface. This // timezone may be used when new commits are created via RPC calls. @@ -754,7 +873,7 @@ type User struct { func (x *User) Reset() { *x = User{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[7] + mi := &file_shared_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -767,7 +886,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[7] + mi := &file_shared_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -780,7 +899,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{7} + return file_shared_proto_rawDescGZIP(), []int{8} } func (x *User) GetGlId() string { @@ -818,18 +937,20 @@ func (x *User) GetTimezone() string { return "" } +// This comment is left unintentionally blank. type ObjectPool struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` } func (x *ObjectPool) Reset() { *x = ObjectPool{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[8] + mi := &file_shared_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -842,7 +963,7 @@ func (x *ObjectPool) String() string { func (*ObjectPool) ProtoMessage() {} func (x *ObjectPool) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[8] + mi := &file_shared_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -855,7 +976,7 @@ func (x *ObjectPool) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectPool.ProtoReflect.Descriptor instead. func (*ObjectPool) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{8} + return file_shared_proto_rawDescGZIP(), []int{9} } func (x *ObjectPool) GetRepository() *Repository { @@ -865,6 +986,7 @@ func (x *ObjectPool) GetRepository() *Repository { return nil } +// This comment is left unintentionally blank. type PaginationParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -888,7 +1010,7 @@ type PaginationParameter struct { func (x *PaginationParameter) Reset() { *x = PaginationParameter{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[9] + mi := &file_shared_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -901,7 +1023,7 @@ func (x *PaginationParameter) String() string { func (*PaginationParameter) ProtoMessage() {} func (x *PaginationParameter) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[9] + mi := &file_shared_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -914,7 +1036,7 @@ func (x *PaginationParameter) ProtoReflect() protoreflect.Message { // Deprecated: Use PaginationParameter.ProtoReflect.Descriptor instead. func (*PaginationParameter) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{9} + return file_shared_proto_rawDescGZIP(), []int{10} } func (x *PaginationParameter) GetPageToken() string { @@ -931,6 +1053,7 @@ func (x *PaginationParameter) GetLimit() int32 { return 0 } +// This comment is left unintentionally blank. type PaginationCursor struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -944,7 +1067,7 @@ type PaginationCursor struct { func (x *PaginationCursor) Reset() { *x = PaginationCursor{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[10] + mi := &file_shared_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -957,7 +1080,7 @@ func (x *PaginationCursor) String() string { func (*PaginationCursor) ProtoMessage() {} func (x *PaginationCursor) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[10] + mi := &file_shared_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -970,7 +1093,7 @@ func (x *PaginationCursor) ProtoReflect() protoreflect.Message { // Deprecated: Use PaginationCursor.ProtoReflect.Descriptor instead. func (*PaginationCursor) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{10} + return file_shared_proto_rawDescGZIP(), []int{11} } func (x *PaginationCursor) GetNextCursor() string { @@ -993,7 +1116,7 @@ type GlobalOptions struct { func (x *GlobalOptions) Reset() { *x = GlobalOptions{} if protoimpl.UnsafeEnabled { - mi := &file_shared_proto_msgTypes[11] + mi := &file_shared_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1006,7 +1129,7 @@ func (x *GlobalOptions) String() string { func (*GlobalOptions) ProtoMessage() {} func (x *GlobalOptions) ProtoReflect() protoreflect.Message { - mi := &file_shared_proto_msgTypes[11] + mi := &file_shared_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1019,7 +1142,7 @@ func (x *GlobalOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use GlobalOptions.ProtoReflect.Descriptor instead. func (*GlobalOptions) Descriptor() ([]byte, []int) { - return file_shared_proto_rawDescGZIP(), []int{11} + return file_shared_proto_rawDescGZIP(), []int{12} } func (x *GlobalOptions) GetLiteralPathspecs() bool { @@ -1058,103 +1181,113 @@ var file_shared_proto_rawDesc = []byte{ 0x70, 0x61, 0x74, 0x68, 0x22, 0x37, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xf1, 0x02, - 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, - 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6f, - 0x64, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x62, - 0x6f, 0x64, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, 0x12, 0x31, - 0x0a, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x54, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, - 0x73, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 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, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x45, 0x78, 0x69, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x54, 0x0a, 0x06, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x71, 0x0a, + 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x22, 0xaa, 0x03, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2c, 0x0a, 0x06, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x08, 0x62, 0x6f, 0x64, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, + 0x64, 0x12, 0x31, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x54, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x08, 0x74, 0x72, 0x61, 0x69, + 0x6c, 0x65, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x84, 0x01, + 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x03, 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, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, + 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, + 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x45, 0x78, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x54, 0x0a, 0x06, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x8a, + 0x02, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0d, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, - 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, - 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x06, 0x74, 0x61, 0x67, 0x67, 0x65, - 0x72, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, - 0x82, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x67, 0x6c, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x6c, - 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, - 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x90, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x4a, 0x0a, 0x13, - 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x10, 0x50, 0x61, 0x67, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, - 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x3c, 0x0a, - 0x0d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, - 0x0a, 0x11, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, - 0x65, 0x63, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, - 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2a, 0x42, 0x0a, 0x0a, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, - 0x54, 0x52, 0x45, 0x45, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x04, 0x2a, - 0x35, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x47, - 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x58, 0x35, 0x30, 0x39, 0x10, 0x02, 0x12, 0x07, 0x0a, - 0x03, 0x53, 0x53, 0x48, 0x10, 0x03, 0x2a, 0x2e, 0x0a, 0x0d, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, - 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, - 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x2c, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x06, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x3c, 0x0a, + 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x04, + 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x67, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x6c, 0x55, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, + 0x22, 0x46, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x38, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x90, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x4a, 0x0a, 0x13, 0x50, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, + 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x10, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, + 0x65, 0x78, 0x74, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x3c, 0x0a, 0x0d, 0x47, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x6c, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, + 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2a, 0x42, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x01, 0x12, 0x08, + 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, + 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x04, 0x2a, 0x35, 0x0a, 0x0d, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, + 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x47, 0x50, 0x10, 0x01, 0x12, + 0x08, 0x0a, 0x04, 0x58, 0x35, 0x30, 0x39, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x53, 0x48, + 0x10, 0x03, 0x2a, 0x2e, 0x0a, 0x0d, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1170,41 +1303,43 @@ func file_shared_proto_rawDescGZIP() []byte { } var file_shared_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_shared_proto_goTypes = []interface{}{ (ObjectType)(0), // 0: gitaly.ObjectType (SignatureType)(0), // 1: gitaly.SignatureType (SortDirection)(0), // 2: gitaly.SortDirection (*Repository)(nil), // 3: gitaly.Repository (*CommitTrailer)(nil), // 4: gitaly.CommitTrailer - (*GitCommit)(nil), // 5: gitaly.GitCommit - (*CommitAuthor)(nil), // 6: gitaly.CommitAuthor - (*ExitStatus)(nil), // 7: gitaly.ExitStatus - (*Branch)(nil), // 8: gitaly.Branch - (*Tag)(nil), // 9: gitaly.Tag - (*User)(nil), // 10: gitaly.User - (*ObjectPool)(nil), // 11: gitaly.ObjectPool - (*PaginationParameter)(nil), // 12: gitaly.PaginationParameter - (*PaginationCursor)(nil), // 13: gitaly.PaginationCursor - (*GlobalOptions)(nil), // 14: gitaly.GlobalOptions - (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp + (*CommitStatInfo)(nil), // 5: gitaly.CommitStatInfo + (*GitCommit)(nil), // 6: gitaly.GitCommit + (*CommitAuthor)(nil), // 7: gitaly.CommitAuthor + (*ExitStatus)(nil), // 8: gitaly.ExitStatus + (*Branch)(nil), // 9: gitaly.Branch + (*Tag)(nil), // 10: gitaly.Tag + (*User)(nil), // 11: gitaly.User + (*ObjectPool)(nil), // 12: gitaly.ObjectPool + (*PaginationParameter)(nil), // 13: gitaly.PaginationParameter + (*PaginationCursor)(nil), // 14: gitaly.PaginationCursor + (*GlobalOptions)(nil), // 15: gitaly.GlobalOptions + (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp } var file_shared_proto_depIdxs = []int32{ - 6, // 0: gitaly.GitCommit.author:type_name -> gitaly.CommitAuthor - 6, // 1: gitaly.GitCommit.committer:type_name -> gitaly.CommitAuthor + 7, // 0: gitaly.GitCommit.author:type_name -> gitaly.CommitAuthor + 7, // 1: gitaly.GitCommit.committer:type_name -> gitaly.CommitAuthor 1, // 2: gitaly.GitCommit.signature_type:type_name -> gitaly.SignatureType 4, // 3: gitaly.GitCommit.trailers:type_name -> gitaly.CommitTrailer - 15, // 4: gitaly.CommitAuthor.date:type_name -> google.protobuf.Timestamp - 5, // 5: gitaly.Branch.target_commit:type_name -> gitaly.GitCommit - 5, // 6: gitaly.Tag.target_commit:type_name -> gitaly.GitCommit - 6, // 7: gitaly.Tag.tagger:type_name -> gitaly.CommitAuthor - 1, // 8: gitaly.Tag.signature_type:type_name -> gitaly.SignatureType - 3, // 9: gitaly.ObjectPool.repository:type_name -> gitaly.Repository - 10, // [10:10] is the sub-list for method output_type - 10, // [10:10] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 5, // 4: gitaly.GitCommit.short_stats:type_name -> gitaly.CommitStatInfo + 16, // 5: gitaly.CommitAuthor.date:type_name -> google.protobuf.Timestamp + 6, // 6: gitaly.Branch.target_commit:type_name -> gitaly.GitCommit + 6, // 7: gitaly.Tag.target_commit:type_name -> gitaly.GitCommit + 7, // 8: gitaly.Tag.tagger:type_name -> gitaly.CommitAuthor + 1, // 9: gitaly.Tag.signature_type:type_name -> gitaly.SignatureType + 3, // 10: gitaly.ObjectPool.repository:type_name -> gitaly.Repository + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_shared_proto_init() } @@ -1239,7 +1374,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GitCommit); i { + switch v := v.(*CommitStatInfo); i { case 0: return &v.state case 1: @@ -1251,7 +1386,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitAuthor); i { + switch v := v.(*GitCommit); i { case 0: return &v.state case 1: @@ -1263,7 +1398,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExitStatus); i { + switch v := v.(*CommitAuthor); i { case 0: return &v.state case 1: @@ -1275,7 +1410,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Branch); i { + switch v := v.(*ExitStatus); i { case 0: return &v.state case 1: @@ -1287,7 +1422,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Tag); i { + switch v := v.(*Branch); i { case 0: return &v.state case 1: @@ -1299,7 +1434,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*User); i { + switch v := v.(*Tag); i { case 0: return &v.state case 1: @@ -1311,7 +1446,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ObjectPool); i { + switch v := v.(*User); i { case 0: return &v.state case 1: @@ -1323,7 +1458,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PaginationParameter); i { + switch v := v.(*ObjectPool); i { case 0: return &v.state case 1: @@ -1335,7 +1470,7 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PaginationCursor); i { + switch v := v.(*PaginationParameter); i { case 0: return &v.state case 1: @@ -1347,6 +1482,18 @@ func file_shared_proto_init() { } } file_shared_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PaginationCursor); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_shared_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GlobalOptions); i { case 0: return &v.state @@ -1365,7 +1512,7 @@ func file_shared_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_shared_proto_rawDesc, NumEnums: 3, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp.pb.go index e7ec4a48a8..027d8840cd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: smarthttp.proto package gitalypb @@ -20,11 +20,13 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type InfoRefsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Parameters to use with git -c (key=value pairs) GitConfigOptions []string `protobuf:"bytes,2,rep,name=git_config_options,json=gitConfigOptions,proto3" json:"git_config_options,omitempty"` @@ -85,11 +87,13 @@ func (x *InfoRefsRequest) GetGitProtocol() string { return "" } +// This comment is left unintentionally blank. type InfoRefsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } @@ -132,6 +136,7 @@ func (x *InfoRefsResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type PostUploadPackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -207,6 +212,7 @@ func (x *PostUploadPackRequest) GetGitProtocol() string { return "" } +// This comment is left unintentionally blank. type PostUploadPackResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -255,6 +261,7 @@ func (x *PostUploadPackResponse) GetData() []byte { return nil } +// This comment is left unintentionally blank. type PostUploadPackWithSidechannelRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -321,6 +328,7 @@ func (x *PostUploadPackWithSidechannelRequest) GetGitProtocol() string { return "" } +// This comment is left unintentionally blank. type PostUploadPackWithSidechannelResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -359,6 +367,7 @@ func (*PostUploadPackWithSidechannelResponse) Descriptor() ([]byte, []int) { return file_smarthttp_proto_rawDescGZIP(), []int{5} } +// This comment is left unintentionally blank. type PostReceivePackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -370,9 +379,11 @@ type PostReceivePackRequest struct { Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // gl_id, gl_repository, and gl_username become env variables, used by the Git {pre,post}-receive // hooks. They should only be present in the first message of the stream. - GlId string `protobuf:"bytes,3,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + GlId string `protobuf:"bytes,3,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + // This comment is left unintentionally blank. GlRepository string `protobuf:"bytes,4,opt,name=gl_repository,json=glRepository,proto3" json:"gl_repository,omitempty"` - GlUsername string `protobuf:"bytes,5,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` + // This comment is left unintentionally blank. + GlUsername string `protobuf:"bytes,5,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` // Git protocol version GitProtocol string `protobuf:"bytes,6,opt,name=git_protocol,json=gitProtocol,proto3" json:"git_protocol,omitempty"` // Parameters to use with git -c (key=value pairs) @@ -460,6 +471,7 @@ func (x *PostReceivePackRequest) GetGitConfigOptions() []string { return nil } +// This comment is left unintentionally blank. type PostReceivePackResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -609,7 +621,7 @@ var file_smarthttp_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp_grpc.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp_grpc.pb.go index 5233035203..aa7b171ec3 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/smarthttp_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/smarthttp_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: smarthttp.proto package gitalypb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh.pb.go similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh.pb.go index 32a62d738b..d3ab1fd228 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: ssh.proto package gitalypb @@ -20,6 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type SSHUploadPackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -95,6 +96,7 @@ func (x *SSHUploadPackRequest) GetGitProtocol() string { return "" } +// This comment is left unintentionally blank. type SSHUploadPackResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -162,6 +164,7 @@ func (x *SSHUploadPackResponse) GetExitStatus() *ExitStatus { return nil } +// This comment is left unintentionally blank. type SSHUploadPackWithSidechannelRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -228,6 +231,7 @@ func (x *SSHUploadPackWithSidechannelRequest) GetGitProtocol() string { return "" } +// This comment is left unintentionally blank. type SSHUploadPackWithSidechannelResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -266,6 +270,7 @@ func (*SSHUploadPackWithSidechannelResponse) Descriptor() ([]byte, []int) { return file_ssh_proto_rawDescGZIP(), []int{3} } +// This comment is left unintentionally blank. type SSHReceivePackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -277,9 +282,11 @@ type SSHReceivePackRequest struct { Stdin []byte `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"` // Contents of GL_ID, GL_REPOSITORY, and GL_USERNAME environment variables // for 'git receive-pack' - GlId string `protobuf:"bytes,3,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + GlId string `protobuf:"bytes,3,opt,name=gl_id,json=glId,proto3" json:"gl_id,omitempty"` + // This comment is left unintentionally blank. GlRepository string `protobuf:"bytes,4,opt,name=gl_repository,json=glRepository,proto3" json:"gl_repository,omitempty"` - GlUsername string `protobuf:"bytes,5,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` + // This comment is left unintentionally blank. + GlUsername string `protobuf:"bytes,5,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"` // Git protocol version GitProtocol string `protobuf:"bytes,6,opt,name=git_protocol,json=gitProtocol,proto3" json:"git_protocol,omitempty"` // Parameters to use with git -c (key=value pairs) @@ -367,6 +374,7 @@ func (x *SSHReceivePackRequest) GetGitConfigOptions() []string { return nil } +// This comment is left unintentionally blank. type SSHReceivePackResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -434,6 +442,7 @@ func (x *SSHReceivePackResponse) GetExitStatus() *ExitStatus { return nil } +// This comment is left unintentionally blank. type SSHUploadArchiveRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -491,6 +500,7 @@ func (x *SSHUploadArchiveRequest) GetStdin() []byte { return nil } +// This comment is left unintentionally blank. type SSHUploadArchiveResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -666,7 +676,7 @@ var file_ssh_proto_rawDesc = []byte{ 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, + 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh_grpc.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh_grpc.pb.go index 21f761b8e7..6fb6cac450 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/ssh_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/ssh_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: ssh.proto package gitalypb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction.pb.go similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction.pb.go index 66956d5279..9f258577e7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: transaction.proto package gitalypb @@ -20,20 +20,21 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type VoteTransactionRequest_Phase int32 const ( // UNKNOWN_PHASE is the unknown voting phase. This value has been the // default because phases have been introduced. Eventually, using this // phase will become unsupported. - VoteTransactionRequest_UNKNOWN_PHASE VoteTransactionRequest_Phase = 0 + VoteTransactionRequest_UNKNOWN_PHASE VoteTransactionRequest_Phase = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // PREPARED_PHASE is the prepratory phase. The data that is about to change // is locked for concurrent modification, but changes have not yet been // written to disk. - VoteTransactionRequest_PREPARED_PHASE VoteTransactionRequest_Phase = 1 + VoteTransactionRequest_PREPARED_PHASE VoteTransactionRequest_Phase = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // COMMITTED_PHASE is the committing phase. Data has been committed to disk // and will be visible in all subsequent requests. - VoteTransactionRequest_COMMITTED_PHASE VoteTransactionRequest_Phase = 2 + VoteTransactionRequest_COMMITTED_PHASE VoteTransactionRequest_Phase = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for VoteTransactionRequest_Phase. @@ -82,9 +83,12 @@ func (VoteTransactionRequest_Phase) EnumDescriptor() ([]byte, []int) { type VoteTransactionResponse_TransactionState int32 const ( - VoteTransactionResponse_COMMIT VoteTransactionResponse_TransactionState = 0 - VoteTransactionResponse_ABORT VoteTransactionResponse_TransactionState = 1 - VoteTransactionResponse_STOP VoteTransactionResponse_TransactionState = 2 + // This comment is left unintentionally blank. + VoteTransactionResponse_COMMIT VoteTransactionResponse_TransactionState = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + VoteTransactionResponse_ABORT VoteTransactionResponse_TransactionState = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + VoteTransactionResponse_STOP VoteTransactionResponse_TransactionState = 2 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for VoteTransactionResponse_TransactionState. @@ -128,11 +132,13 @@ func (VoteTransactionResponse_TransactionState) EnumDescriptor() ([]byte, []int) return file_transaction_proto_rawDescGZIP(), []int{1, 0} } +// This comment is left unintentionally blank. type VoteTransactionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // ID of the transaction we're processing TransactionId uint64 `protobuf:"varint,2,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` @@ -211,11 +217,13 @@ func (x *VoteTransactionRequest) GetPhase() VoteTransactionRequest_Phase { return VoteTransactionRequest_UNKNOWN_PHASE } +// This comment is left unintentionally blank. type VoteTransactionResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. State VoteTransactionResponse_TransactionState `protobuf:"varint,1,opt,name=state,proto3,enum=gitaly.VoteTransactionResponse_TransactionState" json:"state,omitempty"` } @@ -258,11 +266,13 @@ func (x *VoteTransactionResponse) GetState() VoteTransactionResponse_Transaction return VoteTransactionResponse_COMMIT } +// This comment is left unintentionally blank. type StopTransactionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // ID of the transaction we're processing TransactionId uint64 `protobuf:"varint,2,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` @@ -314,6 +324,7 @@ func (x *StopTransactionRequest) GetTransactionId() uint64 { return 0 } +// This comment is left unintentionally blank. type StopTransactionResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -411,7 +422,7 @@ var file_transaction_proto_rawDesc = []byte{ 0x74, 0x6f, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, + 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction_grpc.pb.go similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction_grpc.pb.go index e0bff1022a..f786ee6257 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/transaction_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/transaction_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: transaction.proto package gitalypb @@ -18,7 +22,28 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RefTransactionClient interface { + // VoteTransaction casts a vote on a transaction to establish whether the + // node is doing the same change as all the other nodes part of the + // transaction. This RPC blocks until quorum has been reached, which may be + // _before_ all nodes have cast a vote. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. VoteTransaction(ctx context.Context, in *VoteTransactionRequest, opts ...grpc.CallOption) (*VoteTransactionResponse, error) + // StopTransaction gracefully stops a transaction. This RPC can be used if + // only a subset of nodes executes specific code which may cause the + // transaction to fail. One such example is Git hooks, which only execute on + // the primary Gitaly noded. Other nodes which vote on this transaction will + // get a response with the `STOP` state being set. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. StopTransaction(ctx context.Context, in *StopTransactionRequest, opts ...grpc.CallOption) (*StopTransactionResponse, error) } @@ -52,7 +77,28 @@ func (c *refTransactionClient) StopTransaction(ctx context.Context, in *StopTran // All implementations must embed UnimplementedRefTransactionServer // for forward compatibility type RefTransactionServer interface { + // VoteTransaction casts a vote on a transaction to establish whether the + // node is doing the same change as all the other nodes part of the + // transaction. This RPC blocks until quorum has been reached, which may be + // _before_ all nodes have cast a vote. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. VoteTransaction(context.Context, *VoteTransactionRequest) (*VoteTransactionResponse, error) + // StopTransaction gracefully stops a transaction. This RPC can be used if + // only a subset of nodes executes specific code which may cause the + // transaction to fail. One such example is Git hooks, which only execute on + // the primary Gitaly noded. Other nodes which vote on this transaction will + // get a response with the `STOP` state being set. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. StopTransaction(context.Context, *StopTransactionRequest) (*StopTransactionResponse, error) mustEmbedUnimplementedRefTransactionServer() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki.pb.go similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki.pb.go index 647a412b60..69b7c801f7 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.28.0 +// protoc v3.21.1 // source: wiki.proto package gitalypb @@ -20,11 +20,14 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This comment is left unintentionally blank. type WikiGetAllPagesRequest_SortBy int32 const ( - WikiGetAllPagesRequest_TITLE WikiGetAllPagesRequest_SortBy = 0 - WikiGetAllPagesRequest_CREATED_AT WikiGetAllPagesRequest_SortBy = 1 + // This comment is left unintentionally blank. + WikiGetAllPagesRequest_TITLE WikiGetAllPagesRequest_SortBy = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + WikiGetAllPagesRequest_CREATED_AT WikiGetAllPagesRequest_SortBy = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for WikiGetAllPagesRequest_SortBy. @@ -66,11 +69,14 @@ func (WikiGetAllPagesRequest_SortBy) EnumDescriptor() ([]byte, []int) { return file_wiki_proto_rawDescGZIP(), []int{9, 0} } +// This comment is left unintentionally blank. type WikiListPagesRequest_SortBy int32 const ( - WikiListPagesRequest_TITLE WikiListPagesRequest_SortBy = 0 - WikiListPagesRequest_CREATED_AT WikiListPagesRequest_SortBy = 1 + // This comment is left unintentionally blank. + WikiListPagesRequest_TITLE WikiListPagesRequest_SortBy = 0 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + WikiListPagesRequest_CREATED_AT WikiListPagesRequest_SortBy = 1 // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ) // Enum value maps for WikiListPagesRequest_SortBy. @@ -112,15 +118,21 @@ func (WikiListPagesRequest_SortBy) EnumDescriptor() ([]byte, []int) { return file_wiki_proto_rawDescGZIP(), []int{11, 0} } +// This comment is left unintentionally blank. type WikiCommitDetails struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - UserId int32 `protobuf:"varint,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Email []byte `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // This comment is left unintentionally blank. + Message []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + // This comment is left unintentionally blank. + UserId int32 `protobuf:"varint,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // This comment is left unintentionally blank. UserName []byte `protobuf:"bytes,5,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` } @@ -191,13 +203,16 @@ func (x *WikiCommitDetails) GetUserName() []byte { return nil } +// This comment is left unintentionally blank. type WikiPageVersion struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Commit *GitCommit `protobuf:"bytes,1,opt,name=commit,proto3" json:"commit,omitempty"` - Format string `protobuf:"bytes,2,opt,name=format,proto3" json:"format,omitempty"` + // This comment is left unintentionally blank. + Format string `protobuf:"bytes,2,opt,name=format,proto3" json:"format,omitempty"` } func (x *WikiPageVersion) Reset() { @@ -246,19 +261,26 @@ func (x *WikiPageVersion) GetFormat() string { return "" } +// This comment is left unintentionally blank. type WikiPage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // These fields are only present in the first message of a WikiPage stream - Version *WikiPageVersion `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Format string `protobuf:"bytes,2,opt,name=format,proto3" json:"format,omitempty"` - Title []byte `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` - UrlPath string `protobuf:"bytes,4,opt,name=url_path,json=urlPath,proto3" json:"url_path,omitempty"` - Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` - Name []byte `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` - Historical bool `protobuf:"varint,7,opt,name=historical,proto3" json:"historical,omitempty"` + Version *WikiPageVersion `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // This comment is left unintentionally blank. + Format string `protobuf:"bytes,2,opt,name=format,proto3" json:"format,omitempty"` + // This comment is left unintentionally blank. + Title []byte `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` + // This comment is left unintentionally blank. + UrlPath string `protobuf:"bytes,4,opt,name=url_path,json=urlPath,proto3" json:"url_path,omitempty"` + // This comment is left unintentionally blank. + Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Historical bool `protobuf:"varint,7,opt,name=historical,proto3" json:"historical,omitempty"` // This field is present in all messages of a WikiPage stream RawData []byte `protobuf:"bytes,8,opt,name=raw_data,json=rawData,proto3" json:"raw_data,omitempty"` } @@ -358,9 +380,12 @@ type WikiWritePageRequest struct { unknownFields protoimpl.UnknownFields // These following fields are only present in the first message. - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // This comment is left unintentionally blank. + Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` + // This comment is left unintentionally blank. CommitDetails *WikiCommitDetails `protobuf:"bytes,4,opt,name=commit_details,json=commitDetails,proto3" json:"commit_details,omitempty"` // This field is present in all messages. Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"` @@ -433,11 +458,13 @@ func (x *WikiWritePageRequest) GetContent() []byte { return nil } +// This comment is left unintentionally blank. type WikiWritePageResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. DuplicateError []byte `protobuf:"bytes,1,opt,name=duplicate_error,json=duplicateError,proto3" json:"duplicate_error,omitempty"` } @@ -480,16 +507,21 @@ func (x *WikiWritePageResponse) GetDuplicateError() []byte { return nil } +// This comment is left unintentionally blank. type WikiUpdatePageRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // There fields are only present in the first message of the stream - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - PagePath []byte `protobuf:"bytes,2,opt,name=page_path,json=pagePath,proto3" json:"page_path,omitempty"` - Title []byte `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` - Format string `protobuf:"bytes,4,opt,name=format,proto3" json:"format,omitempty"` + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + // This comment is left unintentionally blank. + PagePath []byte `protobuf:"bytes,2,opt,name=page_path,json=pagePath,proto3" json:"page_path,omitempty"` + // This comment is left unintentionally blank. + Title []byte `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` + // This comment is left unintentionally blank. + Format string `protobuf:"bytes,4,opt,name=format,proto3" json:"format,omitempty"` + // This comment is left unintentionally blank. CommitDetails *WikiCommitDetails `protobuf:"bytes,5,opt,name=commit_details,json=commitDetails,proto3" json:"commit_details,omitempty"` // This field is present in all messages Content []byte `protobuf:"bytes,6,opt,name=content,proto3" json:"content,omitempty"` @@ -569,11 +601,13 @@ func (x *WikiUpdatePageRequest) GetContent() []byte { return nil } +// This comment is left unintentionally blank. type WikiUpdatePageResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Error []byte `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` } @@ -616,15 +650,20 @@ func (x *WikiUpdatePageResponse) GetError() []byte { return nil } +// This comment is left unintentionally blank. type WikiFindPageRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` - Revision []byte `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` - Directory []byte `protobuf:"bytes,4,opt,name=directory,proto3" json:"directory,omitempty"` + // This comment is left unintentionally blank. + Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + // This comment is left unintentionally blank. + Revision []byte `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` + // This comment is left unintentionally blank. + Directory []byte `protobuf:"bytes,4,opt,name=directory,proto3" json:"directory,omitempty"` // prevents the content from being sent over the response SkipContent bool `protobuf:"varint,5,opt,name=skip_content,json=skipContent,proto3" json:"skip_content,omitempty"` } @@ -703,6 +742,7 @@ type WikiFindPageResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Page *WikiPage `protobuf:"bytes,1,opt,name=page,proto3" json:"page,omitempty"` } @@ -745,16 +785,20 @@ func (x *WikiFindPageResponse) GetPage() *WikiPage { return nil } +// This comment is left unintentionally blank. type WikiGetAllPagesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Passing 0 means no limit is applied - Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - DirectionDesc bool `protobuf:"varint,3,opt,name=direction_desc,json=directionDesc,proto3" json:"direction_desc,omitempty"` - Sort WikiGetAllPagesRequest_SortBy `protobuf:"varint,4,opt,name=sort,proto3,enum=gitaly.WikiGetAllPagesRequest_SortBy" json:"sort,omitempty"` + Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // This comment is left unintentionally blank. + DirectionDesc bool `protobuf:"varint,3,opt,name=direction_desc,json=directionDesc,proto3" json:"direction_desc,omitempty"` + // This comment is left unintentionally blank. + Sort WikiGetAllPagesRequest_SortBy `protobuf:"varint,4,opt,name=sort,proto3,enum=gitaly.WikiGetAllPagesRequest_SortBy" json:"sort,omitempty"` } func (x *WikiGetAllPagesRequest) Reset() { @@ -823,6 +867,7 @@ type WikiGetAllPagesResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Page *WikiPage `protobuf:"bytes,1,opt,name=page,proto3" json:"page,omitempty"` // When end_of_page is true it signals a change of page for the next Response message (if any) EndOfPage bool `protobuf:"varint,2,opt,name=end_of_page,json=endOfPage,proto3" json:"end_of_page,omitempty"` @@ -874,17 +919,22 @@ func (x *WikiGetAllPagesResponse) GetEndOfPage() bool { return false } +// This comment is left unintentionally blank. type WikiListPagesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` // Passing 0 means no limit is applied - Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - DirectionDesc bool `protobuf:"varint,3,opt,name=direction_desc,json=directionDesc,proto3" json:"direction_desc,omitempty"` - Sort WikiListPagesRequest_SortBy `protobuf:"varint,4,opt,name=sort,proto3,enum=gitaly.WikiListPagesRequest_SortBy" json:"sort,omitempty"` - Offset uint32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // This comment is left unintentionally blank. + DirectionDesc bool `protobuf:"varint,3,opt,name=direction_desc,json=directionDesc,proto3" json:"direction_desc,omitempty"` + // This comment is left unintentionally blank. + Sort WikiListPagesRequest_SortBy `protobuf:"varint,4,opt,name=sort,proto3,enum=gitaly.WikiListPagesRequest_SortBy" json:"sort,omitempty"` + // This comment is left unintentionally blank. + Offset uint32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` } func (x *WikiListPagesRequest) Reset() { @@ -960,6 +1010,7 @@ type WikiListPagesResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // This comment is left unintentionally blank. Page *WikiPage `protobuf:"bytes,1,opt,name=page,proto3" json:"page,omitempty"` } @@ -1162,7 +1213,7 @@ var file_wiki_proto_rawDesc = []byte{ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, + 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki_grpc.pb.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki_grpc.pb.go index 3c1f5bf96a..5c07887594 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb/wiki_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb/wiki_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: wiki.proto package gitalypb @@ -18,11 +22,15 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type WikiServiceClient interface { + // This comment is left unintentionally blank. WikiWritePage(ctx context.Context, opts ...grpc.CallOption) (WikiService_WikiWritePageClient, error) + // This comment is left unintentionally blank. WikiUpdatePage(ctx context.Context, opts ...grpc.CallOption) (WikiService_WikiUpdatePageClient, error) // WikiFindPage returns a stream because the page's raw_data field may be arbitrarily large. WikiFindPage(ctx context.Context, in *WikiFindPageRequest, opts ...grpc.CallOption) (WikiService_WikiFindPageClient, error) + // This comment is left unintentionally blank. WikiGetAllPages(ctx context.Context, in *WikiGetAllPagesRequest, opts ...grpc.CallOption) (WikiService_WikiGetAllPagesClient, error) + // This comment is left unintentionally blank. WikiListPages(ctx context.Context, in *WikiListPagesRequest, opts ...grpc.CallOption) (WikiService_WikiListPagesClient, error) } @@ -202,11 +210,15 @@ func (x *wikiServiceWikiListPagesClient) Recv() (*WikiListPagesResponse, error) // All implementations must embed UnimplementedWikiServiceServer // for forward compatibility type WikiServiceServer interface { + // This comment is left unintentionally blank. WikiWritePage(WikiService_WikiWritePageServer) error + // This comment is left unintentionally blank. WikiUpdatePage(WikiService_WikiUpdatePageServer) error // WikiFindPage returns a stream because the page's raw_data field may be arbitrarily large. WikiFindPage(*WikiFindPageRequest, WikiService_WikiFindPageServer) error + // This comment is left unintentionally blank. WikiGetAllPages(*WikiGetAllPagesRequest, WikiService_WikiGetAllPagesServer) error + // This comment is left unintentionally blank. WikiListPages(*WikiListPagesRequest, WikiService_WikiListPagesServer) error mustEmbedUnimplementedWikiServiceServer() } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/hook.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/hook.proto new file mode 100644 index 0000000000..7d9fa4174b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/hook.proto @@ -0,0 +1,170 @@ +syntax = "proto3"; + +package gitaly; + +import "lint.proto"; +import "shared.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// HookService is a service which provides the implementation of a subset of +// Git hooks. These are typically invoked via the `gitaly-hooks` binary to +// ensure that the actual hook logic is executed in the context of the server. +service HookService { + + // This comment is left unintentionally blank. + rpc PreReceiveHook(stream PreReceiveHookRequest) returns (stream PreReceiveHookResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc PostReceiveHook(stream PostReceiveHookRequest) returns (stream PostReceiveHookResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc UpdateHook(UpdateHookRequest) returns (stream UpdateHookResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // This comment is left unintentionally blank. + rpc ReferenceTransactionHook(stream ReferenceTransactionHookRequest) returns (stream ReferenceTransactionHookResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + + // PackObjectsHookWithSidechannel is an optimized version of PackObjectsHook that uses + // a unix socket side channel. + rpc PackObjectsHookWithSidechannel(PackObjectsHookWithSidechannelRequest) returns (PackObjectsHookWithSidechannelResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + +} + +// This comment is left unintentionally blank. +message PreReceiveHookRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + repeated string environment_variables = 2; + // This comment is left unintentionally blank. + bytes stdin = 4; + // This comment is left unintentionally blank. + repeated string git_push_options = 5; +} + +// This comment is left unintentionally blank. +message PreReceiveHookResponse{ + // This comment is left unintentionally blank. + bytes stdout = 1; + // This comment is left unintentionally blank. + bytes stderr = 2; + // This comment is left unintentionally blank. + ExitStatus exit_status = 3; +} + +// This comment is left unintentionally blank. +message PostReceiveHookRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + repeated string environment_variables = 2; + // This comment is left unintentionally blank. + bytes stdin = 3; + // This comment is left unintentionally blank. + repeated string git_push_options = 4; +} + +// This comment is left unintentionally blank. +message PostReceiveHookResponse{ + // This comment is left unintentionally blank. + bytes stdout = 1; + // This comment is left unintentionally blank. + bytes stderr = 2; + // This comment is left unintentionally blank. + ExitStatus exit_status = 3; +} + +// This comment is left unintentionally blank. +message UpdateHookRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + repeated string environment_variables = 2; + // This comment is left unintentionally blank. + bytes ref = 3; + // This comment is left unintentionally blank. + string old_value = 4; + // This comment is left unintentionally blank. + string new_value = 5; +} + +// This comment is left unintentionally blank. +message UpdateHookResponse{ + // This comment is left unintentionally blank. + bytes stdout = 1; + // This comment is left unintentionally blank. + bytes stderr = 2; + // This comment is left unintentionally blank. + ExitStatus exit_status = 3; +} + +// This comment is left unintentionally blank. +message ReferenceTransactionHookRequest { + // This comment is left unintentionally blank. + enum State { + // This comment is left unintentionally blank. + PREPARED = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + COMMITTED = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ABORTED = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + repeated string environment_variables = 2; + // This comment is left unintentionally blank. + bytes stdin = 3; + // This comment is left unintentionally blank. + State state = 4; +} + +// This comment is left unintentionally blank. +message ReferenceTransactionHookResponse { + // This comment is left unintentionally blank. + bytes stdout = 1; + // This comment is left unintentionally blank. + bytes stderr = 2; + // This comment is left unintentionally blank. + ExitStatus exit_status = 3; +} + +// This comment is left unintentionally blank. +message PackObjectsHookWithSidechannelRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // args contains the arguments passed to the pack-objects hook, without the leading "git" + repeated string args = 2; + // GlId is the user id of the initator of the fetch + string gl_id = 3; + // GlUsername is the username of the initator of the fetch + string gl_username = 5; + // GitProtocol is the protocol used for the fetch + string git_protocol = 6; + +} + +// This comment is left unintentionally blank. +message PackObjectsHookWithSidechannelResponse { +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/internal.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/internal.proto similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/internal.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/internal.proto index 1cacb3bc51..fb678b51f2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/internal.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/internal.proto @@ -2,10 +2,10 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; import "google/protobuf/timestamp.proto"; +import "lint.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; // InternalGitaly is a gRPC service meant to be served by a Gitaly node, but // only reachable by Praefect or other Gitalies @@ -20,11 +20,15 @@ service InternalGitaly { } } +// This comment is left unintentionally blank. message WalkReposRequest { + // This comment is left unintentionally blank. string storage_name = 1 [(storage)=true]; } +// This comment is left unintentionally blank. message WalkReposResponse { + // This comment is left unintentionally blank. string relative_path = 1; // modification_time is the modification time of the repository directory. // This can be used as a proxy for when the repository was last diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/lint.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/lint.proto similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/lint.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/lint.proto index e656e1710f..6606e42383 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/lint.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/lint.proto @@ -2,28 +2,38 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "google/protobuf/descriptor.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// This comment is left unintentionally blank. message OperationMsg { + // This comment is left unintentionally blank. enum Operation { - UNKNOWN = 0; - MUTATOR = 1; - ACCESSOR = 2; - MAINTENANCE = 3; + // This comment is left unintentionally blank. + UNKNOWN = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + MUTATOR = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ACCESSOR = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + MAINTENANCE = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } - Operation op = 1; - + // This comment is left unintentionally blank. enum Scope { - REPOSITORY = 0; - STORAGE = 2; + // This comment is left unintentionally blank. + REPOSITORY = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + STORAGE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX reserved 1; reserved "SERVER"; } + // This comment is left unintentionally blank. + Operation op = 1; + // Scope level indicates what level an RPC interacts with a server: // - REPOSITORY: scoped to only a single repo // - SERVER: affects the entire server and potentially all repos diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/namespace.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/namespace.proto new file mode 100644 index 0000000000..cc4818feee --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/namespace.proto @@ -0,0 +1,98 @@ +syntax = "proto3"; + +package gitaly; + +import "lint.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// NamespaceService is a service which provides RPCs to manage namespaces of a +// storage. Namespaces had been used before Gitaly migrated to hashed storages +// and shouldn't be used nowadays anymore. +service NamespaceService { + + // This comment is left unintentionally blank. + rpc AddNamespace(AddNamespaceRequest) returns (AddNamespaceResponse) { + option (op_type) = { + op: MUTATOR + scope_level: STORAGE, + }; + } + + // This comment is left unintentionally blank. + rpc RemoveNamespace(RemoveNamespaceRequest) returns (RemoveNamespaceResponse) { + option (op_type) = { + op: MUTATOR + scope_level: STORAGE, + }; + } + + // This comment is left unintentionally blank. + rpc RenameNamespace(RenameNamespaceRequest) returns (RenameNamespaceResponse) { + option (op_type) = { + op: MUTATOR + scope_level: STORAGE, + }; + } + + // This comment is left unintentionally blank. + rpc NamespaceExists(NamespaceExistsRequest) returns (NamespaceExistsResponse) { + option (op_type) = { + op: ACCESSOR + scope_level: STORAGE, + }; + } + +} + +// This comment is left unintentionally blank. +message AddNamespaceRequest { + // This comment is left unintentionally blank. + string storage_name = 1 [(storage)=true]; + // This comment is left unintentionally blank. + string name = 2; +} + +// This comment is left unintentionally blank. +message RemoveNamespaceRequest { + // This comment is left unintentionally blank. + string storage_name = 1 [(storage)=true]; + // This comment is left unintentionally blank. + string name = 2; +} + +// This comment is left unintentionally blank. +message RenameNamespaceRequest { + // This comment is left unintentionally blank. + string storage_name = 1 [(storage)=true]; + // This comment is left unintentionally blank. + string from = 2; + // This comment is left unintentionally blank. + string to = 3; +} + +// This comment is left unintentionally blank. +message NamespaceExistsRequest { + // This comment is left unintentionally blank. + string storage_name = 1 [(storage)=true]; + // This comment is left unintentionally blank. + string name = 2; +} + +// This comment is left unintentionally blank. +message NamespaceExistsResponse { + // This comment is left unintentionally blank. + bool exists = 1; +} + +// This comment is left unintentionally blank. +message AddNamespaceResponse { +} + +// This comment is left unintentionally blank. +message RemoveNamespaceResponse { +} + +// This comment is left unintentionally blank. +message RenameNamespaceResponse { +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/objectpool.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/objectpool.proto new file mode 100644 index 0000000000..9634f62c71 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/objectpool.proto @@ -0,0 +1,153 @@ +syntax = "proto3"; + +package gitaly; + +import "lint.proto"; +import "shared.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// ObjectPoolService is a service containing RPCs to manipulate object pools. +// An object pool is a separate repository that can be linked to from multiple +// satellite repositories in order to deduplicate common objects between them. +// This is mostly used in the contexet of repository forks. +service ObjectPoolService { + + // This comment is left unintentionally blank. + rpc CreateObjectPool(CreateObjectPoolRequest) returns (CreateObjectPoolResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // This comment is left unintentionally blank. + rpc DeleteObjectPool(DeleteObjectPoolRequest) returns (DeleteObjectPoolResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // Repositories are assumed to be stored on the same disk + rpc LinkRepositoryToObjectPool(LinkRepositoryToObjectPoolRequest) returns (LinkRepositoryToObjectPoolResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // This comment is left unintentionally blank. + rpc ReduplicateRepository(ReduplicateRepositoryRequest) returns (ReduplicateRepositoryResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // This comment is left unintentionally blank. + rpc DisconnectGitAlternates(DisconnectGitAlternatesRequest) returns (DisconnectGitAlternatesResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // FetchIntoObjectPool fetches all references from a pool member into an object pool so that + // objects shared between this repository and other pool members can be deduplicated. This RPC + // will perform housekeeping tasks after the object pool has been updated to ensure that the pool + // is in an optimal state. + rpc FetchIntoObjectPool(FetchIntoObjectPoolRequest) returns (FetchIntoObjectPoolResponse) { + option (op_type) = { + op: MUTATOR + }; + } + + // This comment is left unintentionally blank. + rpc GetObjectPool(GetObjectPoolRequest) returns (GetObjectPoolResponse) { + option (op_type) = { + op: ACCESSOR + }; + } + +} + +// Creates an object pool from the repository. The client is responsible for +// joining this pool later with this repository. +message CreateObjectPoolRequest { + // This comment is left unintentionally blank. + ObjectPool object_pool = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + Repository origin = 2 [(additional_repository)=true]; +} + +// This comment is left unintentionally blank. +message CreateObjectPoolResponse { +} + +// Removes the directory from disk, caller is responsible for leaving the object +// pool before calling this RPC +message DeleteObjectPoolRequest { + // This comment is left unintentionally blank. + ObjectPool object_pool = 1 [(target_repository)=true]; +} + +// This comment is left unintentionally blank. +message DeleteObjectPoolResponse { +} + +// This comment is left unintentionally blank. +message LinkRepositoryToObjectPoolRequest { + // This comment is left unintentionally blank. + ObjectPool object_pool = 1 [(additional_repository)=true]; + // This comment is left unintentionally blank. + Repository repository = 2 [(target_repository)=true]; +} + +// This comment is left unintentionally blank. +message LinkRepositoryToObjectPoolResponse { +} + +// This comment is left unintentionally blank. +message ReduplicateRepositoryRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; +} + +// This comment is left unintentionally blank. +message ReduplicateRepositoryResponse { +} + +// This comment is left unintentionally blank. +message DisconnectGitAlternatesRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; +} + +// This comment is left unintentionally blank. +message DisconnectGitAlternatesResponse { +} + +// FetchIntoObjectPoolRequest is a request for the FetchIntoObjectPool RPC. +message FetchIntoObjectPoolRequest { + // Origin is the repository to fetch changes from. + Repository origin = 1 [(additional_repository)=true]; + // ObjectPool is the repository to fetch changes into. + ObjectPool object_pool = 2 [(target_repository)=true]; + + // Repack had the intent to control whether FetchIntoObjectPool would perform housekeeping tasks + // in the pool repository or not. This flag wasn't ever honored though and is thus doing nothing. + reserved 3; + reserved "repack"; +} + +// FetchIntoObjectPoolResponse is a response for the FetchIntoObjectPool RPC. +message FetchIntoObjectPoolResponse { +} + +// This comment is left unintentionally blank. +message GetObjectPoolRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; +} + +// This comment is left unintentionally blank. +message GetObjectPoolResponse { + // This comment is left unintentionally blank. + ObjectPool object_pool = 1; +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/operations.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/operations.proto similarity index 73% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/operations.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/operations.proto index 7f0b952519..2932ee6a9d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/operations.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/operations.proto @@ -2,40 +2,62 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - -import "lint.proto"; -import "shared.proto"; import "errors.proto"; import "google/protobuf/timestamp.proto"; +import "lint.proto"; +import "shared.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; // OperationService provides an interface for performing mutating git // operations on a repository on behalf of a user. The user's operation is // treated as untrusted. Any reference update is thus checked against GitLab's // '/allowed' endpoint. service OperationService { + + // This comment is left unintentionally blank. rpc UserCreateBranch(UserCreateBranchRequest) returns (UserCreateBranchResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc UserUpdateBranch(UserUpdateBranchRequest) returns (UserUpdateBranchResponse) { option (op_type) = { op: MUTATOR }; } + + // UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes + // hooks and contacts Rails to verify that the user is indeed allowed to delete that branch. The + // following known error conditions may happen: + // + // - Returns `InvalidArgument` in case either the branch name or user are not set. + // - Returns `FailedPrecondition` in case the branch does not exist. + // - Returns `OK` with a `PreReceiveError` in case custom hooks refused the update. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is enabled this error case will + // instead return `PermissionDenied` with either a `CustomHook` or AccessCheck` structured + // error. + // - Returns `FailedPrecondition` in case updating the reference fails because + // of a concurrent write to the same reference. If the + // `gitaly_user_delete_branch_structured_errors` feature flag is set this error case will + // instead return `FailedPrecondition` with a `ReferenceUpdate` structured error. rpc UserDeleteBranch(UserDeleteBranchRequest) returns (UserDeleteBranchResponse) { option (op_type) = { op: MUTATOR }; } - // UserCreateTag creates a new tag. + // UserCreateTag creates a new tag. This RPC knows to create both lightweight and annotated tags + // depending on whether a message is set. rpc UserCreateTag(UserCreateTagRequest) returns (UserCreateTagResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc UserDeleteTag(UserDeleteTagRequest) returns (UserDeleteTagResponse) { option (op_type) = { op: MUTATOR @@ -140,72 +162,135 @@ service OperationService { op: MUTATOR }; } + } +// This comment is left unintentionally blank. message UserCreateBranchRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes branch_name = 2; + // This comment is left unintentionally blank. User user = 3; + // This comment is left unintentionally blank. bytes start_point = 4; } +// This comment is left unintentionally blank. message UserCreateBranchResponse { + // This comment is left unintentionally blank. Branch branch = 1; // Error returned by the pre-receive hook. If no error was thrown, // it's the empty string ("") string pre_receive_error = 2; } +// UserCreateBranchError is an error returned by the UserCreateBranch RPC in some specific well +// defined error cases. +message UserCreateBranchError { + oneof error { + // CustomHookError is set if any custom hook which has running as part of + // this RPC call has returned a non-zero exit code. + CustomHookError custom_hook = 1; + } +} + +// This comment is left unintentionally blank. message UserUpdateBranchRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes branch_name = 2; + // This comment is left unintentionally blank. User user = 3; + // This comment is left unintentionally blank. bytes newrev = 4; + // This comment is left unintentionally blank. bytes oldrev = 5; } +// This comment is left unintentionally blank. message UserUpdateBranchResponse { + // This comment is left unintentionally blank. string pre_receive_error = 1; } +// UserDeleteBranchRequest is a request for the UserDeleteBranch RPC. message UserDeleteBranchRequest { + // Repository is the repository to delete the branch in. Repository repository = 1 [(target_repository)=true]; + // BranchName is the name of the branch that shall be deleted. This is expected to be the branch + // name only, e.g. in case you want to delete `refs/heads/main` the request needs to only contain + // `main` as the branch name. bytes branch_name = 2; + // User is the user on whose behalf we should delete the branch. This information is used to + // perform access checks against the Rails `/internal/allowed` API. This user is also exposed to + // any custom hooks executed as part of this RPC call. User user = 3; } +// UserDeleteBranchResponse is a response for the UserDeleteBranch RPC. message UserDeleteBranchResponse { - string pre_receive_error = 1; + // PreReceiveError is never set anymore. This RPC will instead return a UserDeleteBranchError for + // a subset of well-defined error cases. + string pre_receive_error = 1 [deprecated=true]; } +// UserDeleteBranchError is an error returned by the UserDeleteBranch RPC in some specific well +// defined error cases. +message UserDeleteBranchError { + oneof error { + // AccessCheckError is set if the RPC failed because `/internal/allowed` failed. + AccessCheckError access_check = 1; + // ReferenceUpdateError is set if the RPC failed because updating the + // reference to the new object ID has failed. + ReferenceUpdateError reference_update = 2; + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHookError custom_hook = 3; + } +} + +// This comment is left unintentionally blank. message UserDeleteTagRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes tag_name = 2; + // This comment is left unintentionally blank. User user = 3; } +// This comment is left unintentionally blank. message UserDeleteTagResponse { + // This comment is left unintentionally blank. string pre_receive_error = 1; } +// UserCreateTagRequest is a request for the UserCreateTag RPC. message UserCreateTagRequest { - // repository is the repository in which the tag shall be created. + // Repository is the repository in which the tag shall be created. Repository repository = 1 [(target_repository)=true]; - // tag_name is the name of the tag that shall be created. + // TagName is the name of the tag that shall be created. Note that this should be set to the name + // only: if you want to create a tag `refs/heads/v1.0`, you need to pass `v1.0` as TagName. bytes tag_name = 2; - // user is the user as which the tag shall be created. + // User is the user as which the tag shall be created. This user is used to perform access checks + // against Rails' `/internal/allowed` endpoint. User user = 3; - // target_revision is the revision which the tag should point to. + // TargetRevision is the revision that the newly created tag should be pointing to. Note that if + // the revision points to a tag, that tag will be peeled to the commit it is pointing to. If the + // TargetRevision does not point to a commit then the RPC will return an error. bytes target_revision = 4; - // message is the message of the tag. If it is empty, a lightweight tag is - // created. Otherwise, an annotated tag is created. + // Message is the message of the tag. If it is empty, a lightweight tag is created. Otherwise, an + // annotated tag is created. bytes message = 5; - // timestamp is the optional timestamp to use for the created tag tags. If - // it's not set, the current time will be used. It's only used if an - // annotated tag is being created. + // Timestamp is the optional timestamp to use for the created tag tags. If it's not set, the + // current time will be used. It's only used if an annotated tag is being created. google.protobuf.Timestamp timestamp = 7; } +// UserCreateTagResponse is a response for the UserCreateTag RPC. message UserCreateTagResponse { // tag is the newly created tag. Tag tag = 1; @@ -216,6 +301,24 @@ message UserCreateTagResponse { string pre_receive_error = 3; } +// UserCreateTagError includes error descriptions which may be set as error details in case +// UserCreateTag fails. +message UserCreateTagError { + oneof error { + // AccessCheckError is set if the RPC failed because `/internal/allowed` failed. + AccessCheckError access_check = 1; + // ReferenceUpdateError is set if the RPC failed because updating the + // reference to the new object ID has failed. + ReferenceUpdateError reference_update = 2; + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHookError custom_hook = 3; + // ReferenceExistsError is set if the tag reference exists already. + ReferenceExistsError reference_exists = 4; + } +} + +// This comment is left unintentionally blank. message UserMergeBranchRequest { // The following parameters must only be set in the first message to declare // parameters for the merge. @@ -243,6 +346,7 @@ message UserMergeBranchRequest { bool apply = 6; } +// This comment is left unintentionally blank. message UserMergeBranchResponse { // First message // The merge commit the branch will be updated to. The caller can still abort the merge. @@ -252,9 +356,12 @@ message UserMergeBranchResponse { // Second message // If set, the merge has been applied to the branch. OperationBranchUpdate branch_update = 3; - // PreReceiveError is never set. Instead, we return a proper gRPC error with - // UserMergeBranchError details set to an AccessCheckError. - string pre_receive_error = 4 [deprecated=true]; + + // PreReceiveError had previously been set in case access checks refused the merge. This has been + // changed to Instead we return a proper gRPC error with UserMergeBranchError details set to an + // AccessCheckError. + reserved "pre_receive_error"; + reserved 4; } // UserMergeBranchError includes error descriptions which may be set as error @@ -266,9 +373,15 @@ message UserMergeBranchError { // ReferenceUpdateError is set if the RPC failed because updating the // reference to the new object ID has failed. ReferenceUpdateError reference_update = 2; + // CustomHook is set if any custom hook which has running as part of this RPC call has returned + // a non-zero exit code. + CustomHookError custom_hook = 3; + // MergeConflictError is set if merging the revisions has resulted in conflicting files. + MergeConflictError merge_conflict = 4; } } +// This comment is left unintentionally blank. message UserMergeToRefRequest { // repository is the repository in which the merge shall be computed. Repository repository = 1 [(target_repository)=true]; @@ -298,12 +411,15 @@ message UserMergeToRefRequest { google.protobuf.Timestamp timestamp = 9; } +// This comment is left unintentionally blank. message UserMergeToRefResponse { // commit_id is the object ID of the computed merge commit. string commit_id = 1; - // PreReceiveError is never set because this RPC does not perform - // authentication via `/internal/allowed`. - string pre_receive_error = 2 [deprecated=true]; + + // PreReceiveError had never been set because this RPC does not perform authentication via + // `/internal/allowed`. This field was thus removed without replacement. + reserved "pre_receive_error"; + reserved 2; } // OperationBranchUpdate contains the details of a branch update. @@ -333,11 +449,15 @@ message UserFFBranchRequest { bytes branch = 4; } +// This comment is left unintentionally blank. message UserFFBranchResponse { + // This comment is left unintentionally blank. OperationBranchUpdate branch_update = 1; + // This comment is left unintentionally blank. string pre_receive_error = 2; } +// This comment is left unintentionally blank. message UserCherryPickRequest { // repository is the repository into which the cherry-pick shall be // performed. @@ -366,17 +486,18 @@ message UserCherryPickRequest { google.protobuf.Timestamp timestamp = 9; } +// This comment is left unintentionally blank. message UserCherryPickResponse { // CreateTreeError represents an error which happened when computing the // cherry-pick. enum CreateTreeError { // NONE denotes that no error occurred. - NONE = 0; + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // EMPTY denotes that the cherry-pick would've resulted in an empty commit, // typically because it has already been applied to the target branch. - EMPTY = 1; + EMPTY = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CONFLICT denotes that the cherry-pick resulted in a conflict. - CONFLICT = 2; + CONFLICT = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } // branch_update represents details about the updated branch. @@ -394,6 +515,28 @@ message UserCherryPickResponse { CreateTreeError create_tree_error_code = 5; } +// UserCherryPickError is an error returned by the UserCherryPick RPC. +message UserCherryPickError { + oneof error { + // CherryPickConflict is returned if there is a conflict when applying the cherry + // pick. + MergeConflictError cherry_pick_conflict = 1; + // TargetBranchDiverged is returned whenever the tip commit of the branch we're + // about to apply the new commit on is not a direct ancestor of the newly created + // cherry-picked commit. This may happen either due to a race where the reference + // is modified while we compute the cherry-picked commit, or alternatively if the + // commit fetched from the start branch of the remote repository is not an ancestor + // of of the local target branch. + NotAncestorError target_branch_diverged = 2; + // ChangesAlreadyApplied is returned if the result after applying the cherry pick is empty. + ChangesAlreadyAppliedError changes_already_applied = 3; + // AccessCheck is returned in case GitLab's `/internal/allowed` endpoint rejected + // the change. + AccessCheckError access_check = 4; + } +} + +// This comment is left unintentionally blank. message UserRevertRequest { // repository is the repository in which the revert shall be applied. Repository repository = 1 [(target_repository)=true]; @@ -421,17 +564,18 @@ message UserRevertRequest { google.protobuf.Timestamp timestamp = 9; } +// This comment is left unintentionally blank. message UserRevertResponse { // CreateTreeError represents an error which happened when computing the // revert. enum CreateTreeError { // NONE denotes that no error occurred. - NONE = 0; + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // EMPTY denotes that the revert would've resulted in an empty commit, // typically because it has already been applied to the target branch. - EMPTY = 1; + EMPTY = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CONFLICT denotes that the revert resulted in a conflict. - CONFLICT = 2; + CONFLICT = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } // branch_update represents details about the updated branch. @@ -451,20 +595,22 @@ message UserRevertResponse { // UserCommitFilesActionHeader contains the details of the action to be performed. message UserCommitFilesActionHeader { + // This comment is left unintentionally blank. enum ActionType { // CREATE creates a new file. - CREATE = 0; + CREATE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH // CREATE_DIR creates a new directory. - CREATE_DIR = 1; + CREATE_DIR = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // UPDATE updates an existing file. - UPDATE = 2; + UPDATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // MOVE moves an existing file to a new path. - MOVE = 3; + MOVE = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // DELETE deletes an existing file. - DELETE = 4; + DELETE = 4; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX // CHMOD changes the permissions of an existing file. - CHMOD = 5; + CHMOD = 5; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // action is the type of the action taken to build a commit. Not all fields are // used for all of the actions. ActionType action = 1; @@ -561,6 +707,7 @@ message UserCommitFilesResponse { string pre_receive_error = 3; } +// This comment is left unintentionally blank. message UserRebaseConfirmableRequest { // Header contains information to compute the rebase and must be sent as // first message. @@ -603,6 +750,7 @@ message UserRebaseConfirmableRequest { } } +// This comment is left unintentionally blank. message UserRebaseConfirmableResponse { oneof user_rebase_confirmable_response_payload { // The first response will contain the rebase commit the branch will @@ -619,6 +767,7 @@ message UserRebaseConfirmableResponse { string git_error = 4; } +// This comment is left unintentionally blank. message UserSquashRequest { // repository is the repository into which the squashed commit shall be // written. @@ -643,9 +792,11 @@ message UserSquashRequest { reserved "squash_id"; } +// This comment is left unintentionally blank. message UserSquashResponse { // squash_sha is the object ID of the squashed commit. string squash_sha = 1; + // DEPRECATED: https://gitlab.com/gitlab-org/gitaly/proto/merge_requests/161 reserved 2; reserved "pre_receive_error"; @@ -653,13 +804,16 @@ message UserSquashResponse { // GitError is not used anymore. Instead, this RPC always returns a real // error with an optional UserRebaseConfirmableError, which may be set on // special errors. - string git_error = 3 [deprecated=true]; + reserved 3; + reserved "git_error"; } +// This comment is left unintentionally blank. message UserRebaseConfirmableError { oneof error { // RebaseConflict is returned in case rebasing commits on top of the start - // commit fails with a merge conflict. + // commit fails with a merge conflict and in case merge squashing commits + // fails with a merge conflict. MergeConflictError rebase_conflict = 1; // AccessCheckError is returned in case GitLab's `/internal/allowed` endpoint rejected // the change. @@ -680,6 +834,7 @@ message UserSquashError { } } +// This comment is left unintentionally blank. message UserApplyPatchRequest { // Header contains information about how to apply the patches. message Header { @@ -703,11 +858,13 @@ message UserApplyPatchRequest { } } +// This comment is left unintentionally blank. message UserApplyPatchResponse { // branch_update contains information about the updated branch. OperationBranchUpdate branch_update = 1; } +// This comment is left unintentionally blank. message UserUpdateSubmoduleRequest { // repository is the repository in which the submodule shall be updated. Repository repository = 1 [(target_repository)=true]; @@ -729,6 +886,7 @@ message UserUpdateSubmoduleRequest { google.protobuf.Timestamp timestamp = 7; } +// This comment is left unintentionally blank. message UserUpdateSubmoduleResponse { // branch_update contains information about the updated branch. OperationBranchUpdate branch_update = 1; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/praefect.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/praefect.proto similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/praefect.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/praefect.proto index 2e913b99f0..a75136f9de 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/praefect.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/praefect.proto @@ -2,15 +2,18 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - +import "google/protobuf/timestamp.proto"; import "lint.proto"; import "shared.proto"; -import "google/protobuf/timestamp.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// PraefectInfoService is a service which provides RPCs to query and modify +// Praefect-specific parameters. service PraefectInfoService { option (intercepted) = true; + // This comment is left unintentionally blank. rpc RepositoryReplicas(RepositoryReplicasRequest) returns (RepositoryReplicasResponse); // DatalossCheck checks for unavailable repositories. @@ -34,8 +37,10 @@ service PraefectInfoService { // from a Praefect node that does not yet know about a new node. As assignments of unconfigured storages are ignored, replication // factor of repositories assigned to a storage node removed from the cluster is effectively decreased. rpc SetReplicationFactor(SetReplicationFactorRequest) returns (SetReplicationFactorResponse); + // GetRepositoryMetadata returns the cluster metadata for a repository. Returns NotFound if the repository does not exist. rpc GetRepositoryMetadata(GetRepositoryMetadataRequest) returns (GetRepositoryMetadataResponse); + } // MarkUnverifiedRequest specifies the replicas which to mark unverified. @@ -68,6 +73,7 @@ message MarkUnverifiedResponse { // GetRepositoryMetadataRequest specifies the repository to retrieve metadata for. message GetRepositoryMetadataRequest { + // This comment is left unintentionally blank. message Path { // virtual_storage is the virtual storage where the repository is. string virtual_storage = 1; @@ -85,6 +91,7 @@ message GetRepositoryMetadataRequest { // GeRepositoryMetadataResponse contains the repository's cluster metadata. message GetRepositoryMetadataResponse { + // This comment is left unintentionally blank. message Replica { // storage is the name of the replica's storage. string storage = 1; @@ -133,23 +140,34 @@ message SetReplicationFactorResponse { repeated string storages = 1; } +// This comment is left unintentionally blank. message SetAuthoritativeStorageRequest { + // This comment is left unintentionally blank. string virtual_storage = 1; + // This comment is left unintentionally blank. string relative_path = 2; + // This comment is left unintentionally blank. string authoritative_storage = 3; } -message SetAuthoritativeStorageResponse {} +// This comment is left unintentionally blank. +message SetAuthoritativeStorageResponse { +} +// This comment is left unintentionally blank. message DatalossCheckRequest { + // This comment is left unintentionally blank. string virtual_storage = 1; // include_partially_unavailable indicates whether to include repositories which are available but // are unavailable on some assigned storages. bool include_partially_replicated = 2; } +// This comment is left unintentionally blank. message DatalossCheckResponse { + // This comment is left unintentionally blank. message Repository { + // This comment is left unintentionally blank. message Storage { // name of the storage string name = 1; @@ -178,16 +196,24 @@ message DatalossCheckResponse { repeated Repository repositories = 2; } +// This comment is left unintentionally blank. message RepositoryReplicasRequest{ + // This comment is left unintentionally blank. Repository repository = 1; } +// This comment is left unintentionally blank. message RepositoryReplicasResponse{ + // This comment is left unintentionally blank. message RepositoryDetails { + // This comment is left unintentionally blank. Repository repository = 1; + // This comment is left unintentionally blank. string checksum = 2; }; + // This comment is left unintentionally blank. RepositoryDetails primary = 1; + // This comment is left unintentionally blank. repeated RepositoryDetails replicas = 2; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ref.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ref.proto similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ref.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ref.proto index 72eb62c355..a2ab81d7f6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ref.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ref.proto @@ -2,56 +2,76 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - +import "errors.proto"; +import "google/protobuf/timestamp.proto"; import "lint.proto"; import "shared.proto"; -import "google/protobuf/timestamp.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// RefService is a service that provides RPCs to list and modify Git references. service RefService { + + // This comment is left unintentionally blank. rpc FindDefaultBranchName(FindDefaultBranchNameRequest) returns (FindDefaultBranchNameResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindAllBranchNames(FindAllBranchNamesRequest) returns (stream FindAllBranchNamesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindAllTagNames(FindAllTagNamesRequest) returns (stream FindAllTagNamesResponse) { option (op_type) = { op: ACCESSOR }; } + // Return a stream so we can divide the response in chunks of branches rpc FindLocalBranches(FindLocalBranchesRequest) returns (stream FindLocalBranchesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindAllBranches(FindAllBranchesRequest) returns (stream FindAllBranchesResponse) { option (op_type) = { op: ACCESSOR }; } + // Returns a stream of tags repository has. rpc FindAllTags(FindAllTagsRequest) returns (stream FindAllTagsResponse) { option (op_type) = { op: ACCESSOR }; } + + // FindTag looks up a tag by its name and returns it to the caller if it exists. This RPC supports + // both lightweight and annotated tags. Note: this RPC returns an `Internal` error if the tag was + // not found. rpc FindTag(FindTagRequest) returns (FindTagResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc FindAllRemoteBranches(FindAllRemoteBranchesRequest) returns (stream FindAllRemoteBranchesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc RefExists(RefExistsRequest) returns (RefExistsResponse) { option (op_type) = { op: ACCESSOR @@ -65,17 +85,22 @@ service RefService { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc DeleteRefs(DeleteRefsRequest) returns (DeleteRefsResponse) { option (op_type) = { op: MUTATOR }; } + // This comment is left unintentionally blank. rpc ListBranchNamesContainingCommit(ListBranchNamesContainingCommitRequest) returns (stream ListBranchNamesContainingCommitResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ListTagNamesContainingCommit(ListTagNamesContainingCommitRequest) returns (stream ListTagNamesContainingCommitResponse) { option (op_type) = { op: ACCESSOR @@ -92,6 +117,7 @@ service RefService { }; } + // This comment is left unintentionally blank. rpc GetTagMessages(GetTagMessagesRequest) returns (stream GetTagMessagesResponse) { option (op_type) = { op: ACCESSOR @@ -123,39 +149,60 @@ service RefService { op: ACCESSOR }; } + } +// This comment is left unintentionally blank. message FindDefaultBranchNameRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message FindDefaultBranchNameResponse { + // This comment is left unintentionally blank. bytes name = 1; } +// This comment is left unintentionally blank. message FindAllBranchNamesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message FindAllBranchNamesResponse { + // This comment is left unintentionally blank. repeated bytes names = 1; } +// This comment is left unintentionally blank. message FindAllTagNamesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message FindAllTagNamesResponse { + // This comment is left unintentionally blank. repeated bytes names = 1; } +// This comment is left unintentionally blank. message FindLocalBranchesRequest { - Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. enum SortBy { - NAME = 0; - UPDATED_ASC = 1; - UPDATED_DESC = 2; + // This comment is left unintentionally blank. + NAME = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + UPDATED_ASC = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + UPDATED_DESC = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. SortBy sort_by = 2; // The page token is the branch name, with the `refs/heads/` prefix, for // example "refs/heads/master". After the first branch name is encountered @@ -164,27 +211,47 @@ message FindLocalBranchesRequest { PaginationParameter pagination_params = 3; } +// This comment is left unintentionally blank. message FindLocalBranchesResponse { + // This field is duplicated by 'local_branches' and will be marked deprecated + // as we add the implementation for 'local_branches'. + // Issue: https://gitlab.com/gitlab-org/gitaly/-/issues/1294 repeated FindLocalBranchResponse branches = 1; + // This comment is left unintentionally blank. + repeated Branch local_branches = 2; } +// This comment is left unintentionally blank. message FindLocalBranchResponse { + // This comment is left unintentionally blank. bytes name = 1; + // This comment is left unintentionally blank. string commit_id = 2; + // This comment is left unintentionally blank. bytes commit_subject = 3; + // This comment is left unintentionally blank. FindLocalBranchCommitAuthor commit_author = 4; + // This comment is left unintentionally blank. FindLocalBranchCommitAuthor commit_committer = 5; + // This comment is left unintentionally blank. GitCommit commit = 6; } +// This comment is left unintentionally blank. message FindLocalBranchCommitAuthor { + // This comment is left unintentionally blank. bytes name = 1; + // This comment is left unintentionally blank. bytes email = 2; + // This comment is left unintentionally blank. google.protobuf.Timestamp date = 3; + // This comment is left unintentionally blank. bytes timezone = 4; } +// This comment is left unintentionally blank. message FindAllBranchesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Only return branches that are merged into root ref bool merged_only = 2; @@ -193,85 +260,141 @@ message FindAllBranchesRequest { repeated bytes merged_branches = 3; } +// This comment is left unintentionally blank. message FindAllBranchesResponse { + // This comment is left unintentionally blank. message Branch { + // This comment is left unintentionally blank. bytes name = 1; + // This comment is left unintentionally blank. GitCommit target = 2; } + + // This comment is left unintentionally blank. repeated Branch branches = 1; } +// FindTagRequest is a request for the FindTag RPC. message FindTagRequest { + // Repository is the repository to look up the tag in. Repository repository = 1 [(target_repository)=true]; + // TagName is the name of the tag that should be looked up. The caller is supposed to pass in the + // tag name only, so if e.g. a tag `refs/tags/v1.0.0` exists, then the caller should pass `v1.0.0` + // as argument. bytes tag_name = 2; } +// FindTagResponse is a response for the FindTag RPC. message FindTagResponse { + // Tag is the tag that was found. Tag tag = 1; } +// FindTagError is an error that will be returned by the FindTag RPC under specific error +// conditions. +message FindTagError { + oneof error { + // TagNotFound indicates that the tag was not found. + ReferenceNotFoundError tag_not_found = 1; + } +} + +// This comment is left unintentionally blank. message FindAllTagsRequest { - Repository repository = 1 [(target_repository)=true]; // SortBy allows to specify desired order of the elements. message SortBy { // Key is a key used for sorting. enum Key { - REFNAME = 0; - CREATORDATE = 1; + // This comment is left unintentionally blank. + REFNAME = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + CREATORDATE = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // VERSION_REFNAME sorts tags by their semantic versions (https://semver.org/). + // Tag names that are not semantic versions are sorted lexicographically. They come before + // the semantic versions if the direction is ascending and after the semantic versions if + // the direction is descending. + VERSION_REFNAME = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // This comment is left unintentionally blank. Key key = 1; + // This comment is left unintentionally blank. SortDirection direction = 2; } + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; // SortBy allows to request tags in particular order. SortBy sort_by = 2; - // The page token is the tags name, with the `refs/tags/` prefix, for // example "refs/tags/v1.0.0". When the tag name matches the page token, // the tag following it will be the first result send as part of the response. PaginationParameter pagination_params = 3; } +// This comment is left unintentionally blank. message FindAllTagsResponse { + // This comment is left unintentionally blank. repeated Tag tags = 1; } +// This comment is left unintentionally blank. message RefExistsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Any ref, e.g. 'refs/heads/master' or 'refs/tags/v1.0.1'. Must start with 'refs/'. bytes ref = 2; } +// This comment is left unintentionally blank. message RefExistsResponse { + // This comment is left unintentionally blank. bool value = 1; } +// This comment is left unintentionally blank. message CreateBranchRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes name = 2; + // This comment is left unintentionally blank. bytes start_point = 3; } +// This comment is left unintentionally blank. message CreateBranchResponse { + // This comment is left unintentionally blank. enum Status { - OK = 0; - ERR_EXISTS = 1; - ERR_INVALID = 2; - ERR_INVALID_START_POINT = 3; + // This comment is left unintentionally blank. + OK = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ERR_EXISTS = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ERR_INVALID = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + ERR_INVALID_START_POINT = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + + // This comment is left unintentionally blank. Status status = 1; + // This comment is left unintentionally blank. Branch branch = 2; } +// This comment is left unintentionally blank. message DeleteBranchRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes name = 2; } // Not clear if we need to do status signaling; we can add fields later. -message DeleteBranchResponse {} +message DeleteBranchResponse { +} +// This comment is left unintentionally blank. message FindBranchRequest { // repository is the repository in which the branch should be looked up. Repository repository = 1 [(target_repository)=true]; @@ -280,46 +403,73 @@ message FindBranchRequest { bytes name = 2; } +// This comment is left unintentionally blank. message FindBranchResponse { + // This comment is left unintentionally blank. Branch branch = 1; } +// This comment is left unintentionally blank. message DeleteRefsRequest{ + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // The following two fields are mutually exclusive - repeated bytes except_with_prefix = 2; + repeated bytes except_with_prefix = 2; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED + // This comment is left unintentionally blank. repeated bytes refs = 3; } +// This comment is left unintentionally blank. message DeleteRefsResponse { + // This comment is left unintentionally blank. string git_error = 1; } -message ListBranchNamesContainingCommitRequest { - Repository repository = 1 [(target_repository)=true]; - string commit_id = 2; +// DeleteRefsError is returned when DeleteRefs fails to delete refs +message DeleteRefsError { + oneof error { + // InvalidFormat is returned when one or more of the refs to be deleted + // have an invalid format. + InvalidRefFormatError invalid_format = 1; + // ReferencesLocked is returned when the references to be deleted are already + // locked by another process. + ReferencesLockedError references_locked = 2; + } +} +// This comment is left unintentionally blank. +message ListBranchNamesContainingCommitRequest { + // This comment is left unintentionally blank. + Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. + string commit_id = 2; // Limit the number of tag names to be returned // If the limit is set to zero, all items will be returned uint32 limit = 3; } +// This comment is left unintentionally blank. message ListBranchNamesContainingCommitResponse { reserved 1; + // This comment is left unintentionally blank. repeated bytes branch_names = 2; } +// This comment is left unintentionally blank. message ListTagNamesContainingCommitRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string commit_id = 2; - // Limit the number of tag names to be returned // If the limit is set to zero, all items will be returned uint32 limit = 3; } +// This comment is left unintentionally blank. message ListTagNamesContainingCommitResponse { reserved 1; + // This comment is left unintentionally blank. repeated bytes tag_names = 2; } @@ -354,33 +504,45 @@ message GetTagSignaturesResponse { repeated TagSignature signatures = 1; } +// This comment is left unintentionally blank. message GetTagMessagesRequest { reserved 2; reserved "tag_names"; + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. repeated string tag_ids = 3; } +// This comment is left unintentionally blank. message GetTagMessagesResponse { reserved 1; reserved "tag_name"; + // This comment is left unintentionally blank. bytes message = 2; // Only present for a new tag message string tag_id = 3; } +// This comment is left unintentionally blank. message FindAllRemoteBranchesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string remote_name = 2; } +// This comment is left unintentionally blank. message FindAllRemoteBranchesResponse { + // This comment is left unintentionally blank. repeated Branch branches = 1; } +// This comment is left unintentionally blank. message PackRefsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // DEPRECATED: https://gitlab.com/gitlab-org/gitaly/-/issues/3997 @@ -388,10 +550,32 @@ message PackRefsRequest { reserved "all_refs"; } -message PackRefsResponse{} +// This comment is left unintentionally blank. +message PackRefsResponse{ +} // ListRefsRequest is a request for the ListRefs RPC. message ListRefsRequest { + // This comment is left unintentionally blank. + message SortBy { + // This comment is left unintentionally blank. + enum Key { + // This comment is left unintentionally blank. + REFNAME = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + CREATORDATE = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + AUTHORDATE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + COMMITTERDATE = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // Key is a key used for sorting. + Key key = 1; + // This comment is left unintentionally blank. + SortDirection direction = 2; + } + // Repository is the repository in which references should be listed in. Repository repository = 1 [(target_repository)=true]; // Patterns contains all patterns which shall be listed. Patterns should be in the format @@ -401,20 +585,6 @@ message ListRefsRequest { // Head determines whether the RPC should also return the HEAD reference. By default, // pseudo-refs are not included in the response. bool head = 3; - - message SortBy { - enum Key { - REFNAME = 0; - CREATORDATE = 1; - AUTHORDATE = 2; - COMMITTERDATE = 3; - } - - // Key is a key used for sorting. - Key key = 1; - SortDirection direction = 2; - } - // SortBy allows to request SHAs in particular order. SortBy sort_by = 4; } @@ -434,6 +604,7 @@ message ListRefsResponse{ repeated Reference references = 1; } +// This comment is left unintentionally blank. message FindRefsByOIDRequest { // repository is the repository in which references will be looked for. Repository repository = 1 [(target_repository)=true]; @@ -450,6 +621,7 @@ message FindRefsByOIDRequest { uint32 limit = 5; } +// This comment is left unintentionally blank. message FindRefsByOIDResponse { // refs is the set of fully-qualified references which have been found. repeated string refs = 1; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/remote.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/remote.proto similarity index 67% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/remote.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/remote.proto index acfa3fa988..06c3d7e000 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/remote.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/remote.proto @@ -2,43 +2,49 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// RemoteService is a service providing RPCs to interact with a remote +// repository that is hosted on another Git server. service RemoteService { - // UpdateRemoteMirror compares the references in the target repository and its remote mirror - // repository. Any differences in the references are then addressed by pushing the differing - // references to the mirror. Created and modified references are updated, removed references are - // deleted from the mirror. UpdateRemoteMirror updates all tags. Branches are updated if they match - // the patterns specified in the requests. - rpc UpdateRemoteMirror(stream UpdateRemoteMirrorRequest) returns (UpdateRemoteMirrorResponse) { - option (op_type) = { + // UpdateRemoteMirror compares the references in the target repository and its remote mirror + // repository. Any differences in the references are then addressed by pushing the differing + // references to the mirror. Created and modified references are updated, removed references are + // deleted from the mirror. UpdateRemoteMirror updates all tags. Branches are updated if they match + // the patterns specified in the requests. + rpc UpdateRemoteMirror(stream UpdateRemoteMirrorRequest) returns (UpdateRemoteMirrorResponse) { + option (op_type) = { op: ACCESSOR }; - } - rpc FindRemoteRepository(FindRemoteRepositoryRequest) returns (FindRemoteRepositoryResponse) { - option (op_type) = { + } + + // This comment is left unintentionally blank. + rpc FindRemoteRepository(FindRemoteRepositoryRequest) returns (FindRemoteRepositoryResponse) { + option (op_type) = { op: ACCESSOR scope_level: STORAGE }; - } + } - // FindRemoteRootRef tries to find the root reference of a remote - // repository. The root reference is the default branch as pointed to by - // the remotes HEAD reference. Returns an InvalidArgument error if the - // specified remote does not exist and a NotFound error in case no HEAD - // branch was found. - rpc FindRemoteRootRef(FindRemoteRootRefRequest) returns (FindRemoteRootRefResponse) { - option (op_type) = { + // FindRemoteRootRef tries to find the root reference of a remote + // repository. The root reference is the default branch as pointed to by + // the remotes HEAD reference. Returns an InvalidArgument error if the + // specified remote does not exist and a NotFound error in case no HEAD + // branch was found. + rpc FindRemoteRootRef(FindRemoteRootRefRequest) returns (FindRemoteRootRefResponse) { + option (op_type) = { op: ACCESSOR }; - } + } } +// This comment is left unintentionally blank. message UpdateRemoteMirrorRequest { + // This comment is left unintentionally blank. message Remote { // URL is the URL of the remote repository. string url = 1; @@ -63,7 +69,7 @@ message UpdateRemoteMirrorRequest { // branch name without the 'refs/heads/' prefix. "*" can be used as a // wildcard to match anything. only_branches_matching can be streamed to the // server over multiple messages. Optional. - repeated bytes only_branches_matching = 3; + repeated bytes only_branches_matching = 3; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED // SshKey is the SSH key to use for accessing to the mirror repository. // Optional. string ssh_key = 4; @@ -78,13 +84,16 @@ message UpdateRemoteMirrorRequest { reserved "ref_name"; } +// This comment is left unintentionally blank. message UpdateRemoteMirrorResponse { // DivergentRefs contains a list of references that had diverged in the // mirror from the source repository. repeated bytes divergent_refs = 1; } +// This comment is left unintentionally blank. message FindRemoteRepositoryRequest { + // This comment is left unintentionally blank. string remote = 1; // This field is used to redirect request to proper storage where it can be handled. // As of now it doesn't matter what storage will be used, but it still must be a valid. @@ -95,6 +104,7 @@ message FindRemoteRepositoryRequest { // This migth throw a GRPC Unavailable code, to signal the request failure // is transient. message FindRemoteRepositoryResponse { + // This comment is left unintentionally blank. bool exists = 1; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/repository-service.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/repository.proto similarity index 63% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/repository-service.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/repository.proto index 3fda65d1c7..8962504878 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/repository-service.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/repository.proto @@ -2,12 +2,15 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// RepositoryService is a service providing RPCs accessing repositories as a whole. service RepositoryService { + + // This comment is left unintentionally blank. rpc RepositoryExists(RepositoryExistsRequest) returns (RepositoryExistsResponse) { option (op_type) = { op: ACCESSOR @@ -54,11 +57,14 @@ service RepositoryService { }; } + // This comment is left unintentionally blank. rpc RepositorySize(RepositorySizeRequest) returns (RepositorySizeResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc ApplyGitattributes(ApplyGitattributesRequest) returns (ApplyGitattributesResponse) { option (op_type) = { op: MUTATOR @@ -72,16 +78,22 @@ service RepositoryService { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc CreateRepository(CreateRepositoryRequest) returns (CreateRepositoryResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc GetArchive(GetArchiveRequest) returns (stream GetArchiveResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc HasLocalBranches(HasLocalBranchesRequest) returns (HasLocalBranchesResponse) { option (op_type) = { op: ACCESSOR @@ -95,27 +107,36 @@ service RepositoryService { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc Fsck(FsckRequest) returns (FsckResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc WriteRef(WriteRefRequest) returns (WriteRefResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc FindMergeBase(FindMergeBaseRequest) returns (FindMergeBaseResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CreateFork(CreateForkRequest) returns (CreateForkResponse) { option (op_type) = { op: MUTATOR }; } + // This comment is left unintentionally blank. rpc CreateRepositoryFromURL(CreateRepositoryFromURLRequest) returns (CreateRepositoryFromURLResponse) { option (op_type) = { op: MUTATOR @@ -146,6 +167,7 @@ service RepositoryService { }; } + // This comment is left unintentionally blank. rpc CreateRepositoryFromBundle(stream CreateRepositoryFromBundleRequest) returns (CreateRepositoryFromBundleResponse) { option (op_type) = { op: MUTATOR @@ -160,16 +182,21 @@ service RepositoryService { }; } + // This comment is left unintentionally blank. rpc FindLicense(FindLicenseRequest) returns (FindLicenseResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc GetInfoAttributes(GetInfoAttributesRequest) returns (stream GetInfoAttributesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CalculateChecksum(CalculateChecksumRequest) returns (CalculateChecksumResponse) { option (op_type) = { op: ACCESSOR @@ -184,46 +211,62 @@ service RepositoryService { }; } + // This comment is left unintentionally blank. rpc GetSnapshot(GetSnapshotRequest) returns (stream GetSnapshotResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc CreateRepositoryFromSnapshot(CreateRepositoryFromSnapshotRequest) returns (CreateRepositoryFromSnapshotResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc GetRawChanges(GetRawChangesRequest) returns (stream GetRawChangesResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc SearchFilesByContent(SearchFilesByContentRequest) returns (stream SearchFilesByContentResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc SearchFilesByName(SearchFilesByNameRequest) returns (stream SearchFilesByNameResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc RestoreCustomHooks(stream RestoreCustomHooksRequest) returns (RestoreCustomHooksResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc BackupCustomHooks(BackupCustomHooksRequest) returns (stream BackupCustomHooksResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc GetObjectDirectorySize(GetObjectDirectorySizeRequest) returns (GetObjectDirectorySizeResponse) { option (op_type) = { op: ACCESSOR }; } + // RemoveRepository will move the repository to `+gitaly/tmp/_removed` and // eventually remove it. This ensures that even on networked filesystems the // data is actually removed even if there's someone still handling the data. @@ -232,11 +275,15 @@ service RepositoryService { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc RenameRepository(RenameRepositoryRequest) returns (RenameRepositoryResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc ReplicateRepository(ReplicateRepositoryRequest) returns (ReplicateRepositoryResponse) { option (op_type) = { op: MUTATOR @@ -281,37 +328,65 @@ service RepositoryService { op: MUTATOR }; } + + // FullPath reads the "gitlab.fullpath" configuration from the repository's + // gitconfig. Returns an error in case the full path has not been configured. + rpc FullPath(FullPathRequest) returns (FullPathResponse) { + option (op_type) = { + op: ACCESSOR + }; + } } +// This comment is left unintentionally blank. message RepositoryExistsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message RepositoryExistsResponse { + // This comment is left unintentionally blank. bool exists = 1; } +// This comment is left unintentionally blank. message RepackIncrementalRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } -message RepackIncrementalResponse {} +// This comment is left unintentionally blank. +message RepackIncrementalResponse { +} +// This comment is left unintentionally blank. message RepackFullRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bool create_bitmap = 2; } -message RepackFullResponse {} +// This comment is left unintentionally blank. +message RepackFullResponse { +} +// This comment is left unintentionally blank. message MidxRepackRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } -message MidxRepackResponse {} +// This comment is left unintentionally blank. +message MidxRepackResponse { +} +// This comment is left unintentionally blank. message GarbageCollectRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bool create_bitmap = 2; // If set to 'true' the 'gc' will be triggered with '--prune=30.minutes.ago' flag. // This will remove dangling objects from the object storage that were not modified in the last 30 minutes. @@ -321,44 +396,65 @@ message GarbageCollectRequest { bool prune = 3; } -message GarbageCollectResponse {} +// This comment is left unintentionally blank. +message GarbageCollectResponse { +} +// This comment is left unintentionally blank. message WriteCommitGraphRequest { + // This comment is left unintentionally blank. enum SplitStrategy { // SizeMultiple requires to use '--split --size-multiple=4' strategy to create/update commit graph. // https://git-scm.com/docs/git-commit-graph#Documentation/git-commit-graph.txt-emwriteem // It is a default, there is no need to explicitly set it in the request. - SizeMultiple = 0; + SizeMultiple = 0; // protolint:disable:this ENUM_FIELD_NAMES_UPPER_SNAKE_CASE ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH } + + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // SplitStrategy is a strategy used to create/update commit graph. - SplitStrategy splitStrategy = 2; + SplitStrategy splitStrategy = 2; // protolint:disable:this FIELD_NAMES_LOWER_SNAKE_CASE } -message WriteCommitGraphResponse {} +// This comment is left unintentionally blank. +message WriteCommitGraphResponse { +} +// This comment is left unintentionally blank. message CleanupRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } -message CleanupResponse {} +// This comment is left unintentionally blank. +message CleanupResponse { +} +// This comment is left unintentionally blank. message RepositorySizeRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message RepositorySizeResponse { // Repository size in kilobytes int64 size = 1; } +// This comment is left unintentionally blank. message ApplyGitattributesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes revision = 2; } -message ApplyGitattributesResponse {} +// This comment is left unintentionally blank. +message ApplyGitattributesResponse { +} +// This comment is left unintentionally blank. message FetchBundleRequest { // Repository into which the reference shall be fetched. Repository repository = 1 [(target_repository)=true]; @@ -370,9 +466,13 @@ message FetchBundleRequest { bool update_head = 3; } -message FetchBundleResponse {} +// This comment is left unintentionally blank. +message FetchBundleResponse { +} +// This comment is left unintentionally blank. message FetchRemoteRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // force determines if references should be force-updated in case they have // diverged. @@ -381,7 +481,9 @@ message FetchRemoteRequest { bool no_tags = 4; // timeout specifies a timeout for the fetch. int32 timeout = 5; + // This comment is left unintentionally blank. string ssh_key = 6; + // This comment is left unintentionally blank. string known_hosts = 7; reserved 8; // no_prune will the fetch to not prune remote references which do not exist @@ -399,6 +501,7 @@ message FetchRemoteRequest { reserved "remote"; } +// This comment is left unintentionally blank. message FetchRemoteResponse { // If check_tags_changed was set in the FetchRemoteRequest, the FetchRemote // RPC will return false when no tags were changed, and true if tags were @@ -406,7 +509,9 @@ message FetchRemoteResponse { bool tags_changed = 1; } +// This comment is left unintentionally blank. message CreateRepositoryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Provide a branch name to set as the default branch of a newly created // repository. Note, this will be treated as the branch name and not a @@ -414,22 +519,36 @@ message CreateRepositoryRequest { bytes default_branch = 2; } -message CreateRepositoryResponse {} +// This comment is left unintentionally blank. +message CreateRepositoryResponse { +} +// This comment is left unintentionally blank. message GetArchiveRequest { + // This comment is left unintentionally blank. enum Format { - ZIP = 0; - TAR = 1; - TAR_GZ = 2; - TAR_BZ2 = 3; + // This comment is left unintentionally blank. + ZIP = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + TAR = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TAR_GZ = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TAR_BZ2 = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string commit_id = 2; + // This comment is left unintentionally blank. string prefix = 3; + // This comment is left unintentionally blank. Format format = 4; + // This comment is left unintentionally blank. bytes path = 5; - repeated bytes exclude = 6; + // This comment is left unintentionally blank. + repeated bytes exclude = 6; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED // If `elide_path` is true and `path` refers to a subdirectory, that // subdirectory will be elided from archive entries. For example, if `dir` // contains `README.md`, with `elide_path = false` the corresponding entry @@ -437,21 +556,29 @@ message GetArchiveRequest { // `README.md`. `elide_path` has no effect if `path` refers to the repository // root. `elide_path = true` is not supported if `path` refers to a file. bool elide_path = 7; + // This comment is left unintentionally blank. bool include_lfs_blobs = 8; } +// This comment is left unintentionally blank. message GetArchiveResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message HasLocalBranchesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message HasLocalBranchesResponse { + // This comment is left unintentionally blank. bool value = 1; } +// This comment is left unintentionally blank. message FetchSourceBranchRequest { // Repository into which the reference shall be fetched. After a successful // call, it should contain the target reference which points to the same @@ -466,38 +593,52 @@ message FetchSourceBranchRequest { bytes target_ref = 4; } +// This comment is left unintentionally blank. message FetchSourceBranchResponse { // True if the source branch was successfully fetched into the target // repository, false if resolving the remote reference or fetching it failed. bool result = 1; } +// This comment is left unintentionally blank. message FsckRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message FsckResponse { + // This comment is left unintentionally blank. bytes error = 1; } +// This comment is left unintentionally blank. message WriteRefRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes ref = 2; + // This comment is left unintentionally blank. bytes revision = 3; + // This comment is left unintentionally blank. bytes old_revision = 4; + // This comment is left unintentionally blank. bool force = 5; // This used to be a boolean indicating whether or not to shell out or use // the rugged implementation reserved 6; } +// This comment is left unintentionally blank. message WriteRefResponse { // This used to contain an error message. Since we're shelling out // all exceptions are wrapped in GRPC errors. reserved 1; } +// This comment is left unintentionally blank. message FindMergeBaseRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // We use a repeated field because rugged supports finding a base // for more than 2 revisions, so if we needed that in the future we don't @@ -505,19 +646,29 @@ message FindMergeBaseRequest { repeated bytes revisions = 2; } +// This comment is left unintentionally blank. message FindMergeBaseResponse { + // This comment is left unintentionally blank. string base = 1; } +// This comment is left unintentionally blank. message CreateForkRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. Repository source_repository = 2; } -message CreateForkResponse {} +// This comment is left unintentionally blank. +message CreateForkResponse { +} +// This comment is left unintentionally blank. message CreateRepositoryFromURLRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string url = 2; // HttpHost is the hostname of the remote repository. Use this when the // URL hostname has already been resolved to an IP address to prevent DNS @@ -534,16 +685,23 @@ message CreateRepositoryFromURLRequest { bool mirror = 5; } -message CreateRepositoryFromURLResponse {} +// This comment is left unintentionally blank. +message CreateRepositoryFromURLResponse { +} +// This comment is left unintentionally blank. message CreateBundleRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message CreateBundleResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message CreateBundleFromRefListRequest { // Repository is the repository that the bundle is created from. Repository repository = 1 [(target_repository)=true]; @@ -554,7 +712,9 @@ message CreateBundleFromRefListRequest { repeated bytes patterns = 2; } +// This comment is left unintentionally blank. message CreateBundleFromRefListResponse { + // This comment is left unintentionally blank. bytes data = 1; } @@ -571,64 +731,110 @@ message GetConfigResponse { bytes data = 1; } +// This comment is left unintentionally blank. message RestoreCustomHooksRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes data = 2; } -message RestoreCustomHooksResponse {} +// This comment is left unintentionally blank. +message RestoreCustomHooksResponse { +} +// This comment is left unintentionally blank. message BackupCustomHooksRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message BackupCustomHooksResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message CreateRepositoryFromBundleRequest { // Only available on the first message Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes data = 2; } -message CreateRepositoryFromBundleResponse {} +// This comment is left unintentionally blank. +message CreateRepositoryFromBundleResponse { +} +// This comment is left unintentionally blank. message FindLicenseRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// FindLicenseResponse contains the result of detecting the license used in the repository. +// If there is nothing that looks like a license file, the empty response is returned. +// If there is something that looks like a license, but that license can't be found in the +// list of known licenses, we return a pre-defined response with "Other" license. message FindLicenseResponse { + // LicenseShortName is the license unique SPDX identifier or a short name. + // It is always returned lower-cased. string license_short_name = 1; + // LicenseName is the license full name. + string license_name = 2; + // LicenseUrl is a URL to the license on the internet. + string license_url = 3; + // LicensePath is a path to the file that contains the text of the license. + string license_path = 4; + // LicenseNickname is a shortened full name for better readability. + // It exists only for a small set of licenses and an empty value is returned in most cases. + string license_nickname = 5; } +// This comment is left unintentionally blank. message GetInfoAttributesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message GetInfoAttributesResponse { + // This comment is left unintentionally blank. bytes attributes = 1; } +// This comment is left unintentionally blank. message CalculateChecksumRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message CalculateChecksumResponse { + // This comment is left unintentionally blank. string checksum = 1; } +// This comment is left unintentionally blank. message GetSnapshotRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message GetSnapshotResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message CreateRepositoryFromSnapshotRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string http_url = 2; + // This comment is left unintentionally blank. string http_auth = 3; // HttpHost is the hostname of the remote snapshot. Use this when the // URL hostname has already been resolved to an IP address to prevent DNS @@ -636,27 +842,45 @@ message CreateRepositoryFromSnapshotRequest { string http_host = 4; } -message CreateRepositoryFromSnapshotResponse {} +// This comment is left unintentionally blank. +message CreateRepositoryFromSnapshotResponse { +} +// This comment is left unintentionally blank. message GetRawChangesRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string from_revision = 2; + // This comment is left unintentionally blank. string to_revision = 3; } +// This comment is left unintentionally blank. message GetRawChangesResponse { + // This comment is left unintentionally blank. message RawChange { + // This comment is left unintentionally blank. enum Operation { - UNKNOWN = 0; - ADDED = 1; - COPIED = 2; - DELETED = 3; - MODIFIED = 4; - RENAMED = 5; - TYPE_CHANGED = 6; + // This comment is left unintentionally blank. + UNKNOWN = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ADDED = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + COPIED = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + DELETED = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + MODIFIED = 4; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + RENAMED = 5; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TYPE_CHANGED = 6; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX } + // This comment is left unintentionally blank. string blob_id = 1; + // This comment is left unintentionally blank. int64 size= 2; // This used to be a string that is now represented by the field 9 as byte array. @@ -666,22 +890,32 @@ message GetRawChangesResponse { reserved 4; reserved "old_path"; + // This comment is left unintentionally blank. Operation operation= 5; + // This comment is left unintentionally blank. string raw_operation = 6; + // This comment is left unintentionally blank. int32 old_mode = 7; + // This comment is left unintentionally blank. int32 new_mode = 8; // the following fields, 9 and 10, will eventually replace 3 and 4 bytes new_path_bytes = 9; + // This comment is left unintentionally blank. bytes old_path_bytes = 10; } + // This comment is left unintentionally blank. repeated RawChange raw_changes = 1; } +// This comment is left unintentionally blank. message SearchFilesByNameRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string query = 2; + // This comment is left unintentionally blank. bytes ref = 3; // If `filter` is specified and non-empty, it will be parsed as a regular // expression and used to filter the result set before it is transmitted. It is @@ -691,20 +925,31 @@ message SearchFilesByNameRequest { string filter = 4; } +// This comment is left unintentionally blank. message SearchFilesByNameResponse { + // This comment is left unintentionally blank. repeated bytes files = 1; } +// This comment is left unintentionally blank. message SearchFilesByContentRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string query = 2; + // This comment is left unintentionally blank. bytes ref = 3; + // This comment is left unintentionally blank. bool chunked_response = 4; } +// This comment is left unintentionally blank. message SearchFilesByContentResponse { + // This comment is left unintentionally blank. repeated bytes matches = 1; + // This comment is left unintentionally blank. bytes match_data = 2; + // This comment is left unintentionally blank. bool end_of_match = 3; } @@ -742,45 +987,66 @@ message Remote { reserved "name"; } +// This comment is left unintentionally blank. message GetObjectDirectorySizeRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message GetObjectDirectorySizeResponse { // Object directory size in kilobytes int64 size = 1; } +// This comment is left unintentionally blank. message RemoveRepositoryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } +// This comment is left unintentionally blank. message RemoveRepositoryResponse { } + +// This comment is left unintentionally blank. message RenameRepositoryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. string relative_path = 2; } +// This comment is left unintentionally blank. message RenameRepositoryResponse{ } +// This comment is left unintentionally blank. message ReplicateRepositoryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. Repository source = 2; } -message ReplicateRepositoryResponse{} +// This comment is left unintentionally blank. +message ReplicateRepositoryResponse{ +} +// This comment is left unintentionally blank. message OptimizeRepositoryRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } -message OptimizeRepositoryResponse{} +// This comment is left unintentionally blank. +message OptimizeRepositoryResponse{ +} // PruneUnreachableObjectsRequest is a request for the PruneUnreachableObjects // RPC call. message PruneUnreachableObjectsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; } @@ -798,4 +1064,17 @@ message SetFullPathRequest { } // SetFullPathResponse is a response fqor the SetFullPath RPC. -message SetFullPathResponse {} +message SetFullPathResponse { +} + +// FullPathRequest is a request for the FullPath RPC. +message FullPathRequest { + // Repository is the repository whose gitconfig should be read. + Repository repository = 1 [(target_repository)=true]; +} + +// SetFullPathResponse is a response for the SetFullPath RPC. +message FullPathResponse { + // Path read from the "gitlab.fullpath" config key. + string path = 1; +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/server.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/server.proto new file mode 100644 index 0000000000..23d1ea7272 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/server.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; + +package gitaly; + +import "google/protobuf/duration.proto"; +import "lint.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// ServerService is a service that provides information about a Gitaly server. +service ServerService { + option (intercepted) = true; + + // This comment is left unintentionally blank. + rpc ServerInfo(ServerInfoRequest) returns (ServerInfoResponse); + + // This comment is left unintentionally blank. + rpc DiskStatistics(DiskStatisticsRequest) returns (DiskStatisticsResponse); + + // ClockSynced checks if machine clock is synced + // (the offset is less that the one passed in the request). + rpc ClockSynced(ClockSyncedRequest) returns (ClockSyncedResponse); + + // ReadinessCheck runs the set of the checks to make sure service is in operational state. + rpc ReadinessCheck(ReadinessCheckRequest) returns (ReadinessCheckResponse); +} + +// This comment is left unintentionally blank. +message ServerInfoRequest { +} + +// This comment is left unintentionally blank. +message ServerInfoResponse { + // This comment is left unintentionally blank. + message StorageStatus { + // This comment is left unintentionally blank. + string storage_name = 1; + // This comment is left unintentionally blank. + bool readable = 2; + // This comment is left unintentionally blank. + bool writeable = 3; + // This comment is left unintentionally blank. + string fs_type = 4; + // This comment is left unintentionally blank. + string filesystem_id = 5; + // This comment is left unintentionally blank. + uint32 replication_factor = 6; + } + + // This comment is left unintentionally blank. + string server_version = 1; + // This comment is left unintentionally blank. + string git_version = 2; + // This comment is left unintentionally blank. + repeated StorageStatus storage_statuses = 3; +} + +// This comment is left unintentionally blank. +message DiskStatisticsRequest { +} + +// This comment is left unintentionally blank. +message DiskStatisticsResponse { + // This comment is left unintentionally blank. + message StorageStatus { + // When both available and used fields are equal 0 that means that + // Gitaly was unable to determine storage stats. + string storage_name = 1; + // This comment is left unintentionally blank. + int64 available = 2; + // This comment is left unintentionally blank. + int64 used = 3; + } + + // This comment is left unintentionally blank. + repeated StorageStatus storage_statuses = 1; +} + +// ClockSyncedRequest contains settings to be used for the system clock synchronisation check. +message ClockSyncedRequest { + // NtpHost is a URL to the external NTP service that should be used for clock sync check. + // Default is "ntp.pool.org" + string ntp_host = 1; + reserved "drift_threshold_millis"; + reserved 2; + // DriftThreshold is an allowed drift from the NTP service. + google.protobuf.Duration drift_threshold = 3; +} + +// ClockSyncedRequest represents result of the system clock synchronisation check. +message ClockSyncedResponse { + // Synced is set to true if system clock has an affordable drift compared to NTP service. + bool synced = 1; +} + +// ReadinessCheckRequest is used to verify if the service is in operational state. +message ReadinessCheckRequest { + // Timeout is an amount of milliseconds for the check to run before give up and mark as failed. + google.protobuf.Duration timeout = 1; +} + +// ReadinessCheckResponse is just a stub now and contains no information. +// If the service is not in the operational state the error will be returned instead. +message ReadinessCheckResponse { + // Ok represents response if none checks failed. + message Ok { + } + // Failure represents response if at least one check failed. + message Failure { + // Response contains information about failed check. + message Response { + // Name is a name of the check that was performed. + string name = 1; + // ErrorMessage is a cause of the check failure. + string error_message = 2; + } + // FailedChecks is a list of failed checks. + repeated Response failed_checks = 1; + } + + oneof Result { + // OkResponse is set when all checks pass. + Ok ok_response = 1; + // FailureResponse is set if at least one check failed. + Failure failure_response = 2; + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/shared.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/shared.proto new file mode 100644 index 0000000000..9b7fcebbf7 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/shared.proto @@ -0,0 +1,222 @@ +syntax = "proto3"; + +package gitaly; + +import "google/protobuf/timestamp.proto"; +import "lint.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// This comment is left unintentionally blank. +enum ObjectType { + // This comment is left unintentionally blank. + UNKNOWN = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + COMMIT = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + BLOB = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TREE = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + TAG = 4; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX +} + +// This comment is left unintentionally blank. +enum SignatureType { + // This comment is left unintentionally blank. + NONE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + PGP = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + X509 = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + SSH = 3; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // maybe add X509+TSA or other combinations at a later step +} + +// This comment is left unintentionally blank. +message Repository { + // DEPRECATED: https://gitlab.com/gitlab-org/gitaly/issues/151 + reserved 1; + reserved "path"; + + // This comment is left unintentionally blank. + string storage_name = 2; + // This comment is left unintentionally blank. + string relative_path = 3; + // Sets the GIT_OBJECT_DIRECTORY envvar on git commands to the value of this field. + // It influences the object storage directory the SHA1 directories are created underneath. + string git_object_directory = 4; + // Sets the GIT_ALTERNATE_OBJECT_DIRECTORIES envvar on git commands to the values of this field. + // It influences the list of Git object directories which can be used to search for Git objects. + repeated string git_alternate_object_directories = 5; + // Used in callbacks to GitLab so that it knows what repository the event is + // associated with. May be left empty on RPC's that do not perform callbacks. + // During project creation, `gl_repository` may not be known. + string gl_repository = 6; + reserved 7; + // The human-readable GitLab project path (e.g. gitlab-org/gitlab-ce). + // When hashed storage is use, this associates a project path with its + // path on disk. The name can change over time (e.g. when a project is + // renamed). This is primarily used for logging/debugging at the + // moment. + string gl_project_path = 8; +} + +// A single Git trailer (https://git-scm.com/docs/git-interpret-trailers) +// key-value pair. +message CommitTrailer { + // The key of the trailer, such as `Signed-off-by`. + bytes key = 1; + // The value of the trailer, such as `Alice `. + bytes value = 2; +} + +// CommitStatInfo includes the number of changed lines and files in the commit. +message CommitStatInfo { + // additions is the number of line additions in the commit. + int32 additions = 1; + // deletions is the number of lines deleted in the commit. + int32 deletions = 2; + // changed_files is the number of files changed in the commit. + int32 changed_files = 3; +} + +// Corresponds to Gitlab::Git::Commit +message GitCommit { + // This comment is left unintentionally blank. + string id = 1; + // This comment is left unintentionally blank. + bytes subject = 2; + // This comment is left unintentionally blank. + bytes body = 3; + // This comment is left unintentionally blank. + CommitAuthor author = 4; + // This comment is left unintentionally blank. + CommitAuthor committer = 5; + // This comment is left unintentionally blank. + repeated string parent_ids = 6; + // If body exceeds a certain threshold, it will be nullified, + // but its size will be set in body_size so we can know if + // a commit had a body in the first place. + int64 body_size = 7; + // This comment is left unintentionally blank. + SignatureType signature_type = 8; + // The tree ID will always be filled, even if the tree is empty. In that case + // the value will be `4b825dc642cb6eb9a060e54bf8d69288fbee4904`. + // That value is equivalent to `git hash-object -t tree /dev/null` + string tree_id = 9; + // The list of Git trailers (https://git-scm.com/docs/git-interpret-trailers) + // found in this commit's message. The number of trailers and their key/value + // sizes are limited. If a trailer exceeds these size limits, it and any + // trailers that follow it are not included. + repeated CommitTrailer trailers = 10; + // The stats include additions, deletions and changed_files, + // they are only set when `include_shortstat == true`. + CommitStatInfo short_stats = 11; +} + +// This comment is left unintentionally blank. +message CommitAuthor { + // This comment is left unintentionally blank. + bytes name = 1; + // This comment is left unintentionally blank. + bytes email = 2; + // This comment is left unintentionally blank. + google.protobuf.Timestamp date = 3; + // This comment is left unintentionally blank. + bytes timezone = 4; +} + +// This comment is left unintentionally blank. +message ExitStatus { + // This comment is left unintentionally blank. + int32 value = 1; +} + +// Corresponds to Gitlab::Git::Branch +message Branch { + // This comment is left unintentionally blank. + bytes name = 1; + // This comment is left unintentionally blank. + GitCommit target_commit = 2; +} + +// This comment is left unintentionally blank. +message Tag { + // This comment is left unintentionally blank. + bytes name = 1; + // This comment is left unintentionally blank. + string id = 2; + // This comment is left unintentionally blank. + GitCommit target_commit = 3; + // If message exceeds a certain threshold, it will be nullified, + // but its size will be set in message_size so we can know if + // a tag had a message in the first place. + bytes message = 4; + // This comment is left unintentionally blank. + int64 message_size = 5; + // This comment is left unintentionally blank. + CommitAuthor tagger = 6; + // This comment is left unintentionally blank. + SignatureType signature_type = 7; +} + +// This comment is left unintentionally blank. +message User { + // This comment is left unintentionally blank. + string gl_id = 1; + // This comment is left unintentionally blank. + bytes name = 2; + // This comment is left unintentionally blank. + bytes email = 3; + // This comment is left unintentionally blank. + string gl_username = 4; + // Timezone is the timezone as configured by the user in the web interface. This + // timezone may be used when new commits are created via RPC calls. + string timezone = 5; +} + +// This comment is left unintentionally blank. +message ObjectPool { + // This comment is left unintentionally blank. + Repository repository = 1 [(gitaly.repository)=true]; +} + +// This comment is left unintentionally blank. +message PaginationParameter { + // Instructs pagination to start sending results after the provided page + // token appears. A page token allows for a generic pattern to uniquely + // identify a result or 'page'. Each paginated RPC may interpret a page + // token differently. + string page_token = 1; + // When fully consuming the response the client will receive _at most_ + // `limit` number of resulting objects. Note that the number of response + // messages might be much lower, as some response messages already send + // multiple objects per message. + // When the limit is smaller than 0, it will be normalized to 2147483647 + // on the server side. When limit is not set, it defaults to 0, and no + // results are send in the response. + int32 limit = 2; +} + +// This comment is left unintentionally blank. +message PaginationCursor { + // To the caller, this is an opaque token to indicate what the caller + // should present as a page_token to get subsequent results. + string next_cursor = 1; +} + +// https://git-scm.com/docs/git/#_options +message GlobalOptions { + // Treat pathspecs literally (i.e. no globbing, no pathspec magic) + bool literal_pathspecs = 1; +} + +// SortDirection defines the sort direction. +enum SortDirection { + // ASCENDING sorts by the sort key in ascending order. + ASCENDING = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // DESCENDING sorts by the sort key in descending order. + DESCENDING = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/smarthttp.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/smarthttp.proto similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/smarthttp.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/smarthttp.proto index f9e3977d6d..a0e6aaad58 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/smarthttp.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/smarthttp.proto @@ -2,11 +2,13 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// SmartHTTPService is a service that provides RPCs required for HTTP-based Git +// clones via the smart HTTP protocol. service SmartHTTPService { // The response body for GET /info/refs?service=git-upload-pack // Will be invoked when the user executes a `git fetch`, meaning the server @@ -48,7 +50,9 @@ service SmartHTTPService { } } +// This comment is left unintentionally blank. message InfoRefsRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Parameters to use with git -c (key=value pairs) repeated string git_config_options = 2; @@ -57,10 +61,13 @@ message InfoRefsRequest { string git_protocol = 3; } +// This comment is left unintentionally blank. message InfoRefsResponse { + // This comment is left unintentionally blank. bytes data = 1; } +// This comment is left unintentionally blank. message PostUploadPackRequest { // repository should only be present in the first message of the stream Repository repository = 1 [(target_repository)=true]; @@ -73,11 +80,13 @@ message PostUploadPackRequest { string git_protocol = 4; } +// This comment is left unintentionally blank. message PostUploadPackResponse { // Raw data from stdout of 'git upload-pack' bytes data = 1; } +// This comment is left unintentionally blank. message PostUploadPackWithSidechannelRequest { // repository should only be present in the first message of the stream Repository repository = 1 [(target_repository)=true]; @@ -87,8 +96,11 @@ message PostUploadPackWithSidechannelRequest { string git_protocol = 3; } -message PostUploadPackWithSidechannelResponse { } +// This comment is left unintentionally blank. +message PostUploadPackWithSidechannelResponse { +} +// This comment is left unintentionally blank. message PostReceivePackRequest { // repository should only be present in the first message of the stream Repository repository = 1 [(target_repository)=true]; @@ -97,7 +109,9 @@ message PostReceivePackRequest { // gl_id, gl_repository, and gl_username become env variables, used by the Git {pre,post}-receive // hooks. They should only be present in the first message of the stream. string gl_id = 3; + // This comment is left unintentionally blank. string gl_repository = 4; + // This comment is left unintentionally blank. string gl_username = 5; // Git protocol version string git_protocol = 6; @@ -106,6 +120,7 @@ message PostReceivePackRequest { repeated string git_config_options = 7; } +// This comment is left unintentionally blank. message PostReceivePackResponse { // Raw data from stdout of 'git receive-pack' bytes data = 1; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ssh.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ssh.proto similarity index 84% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ssh.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ssh.proto index 732d26a2c3..9964828eda 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/ssh.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/ssh.proto @@ -2,11 +2,12 @@ syntax = "proto3"; package gitaly; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// SSHService is a service that provides RPCs required for SSH-based Git clones. service SSHService { // To forward 'git upload-pack' to Gitaly for SSH sessions rpc SSHUploadPack(stream SSHUploadPackRequest) returns (stream SSHUploadPackResponse) { @@ -37,6 +38,7 @@ service SSHService { } } +// This comment is left unintentionally blank. message SSHUploadPackRequest { // 'repository' must be present in the first message. Repository repository = 1 [(target_repository)=true]; @@ -52,6 +54,7 @@ message SSHUploadPackRequest { string git_protocol = 5; } +// This comment is left unintentionally blank. message SSHUploadPackResponse { // A chunk of raw data from 'git upload-pack' standard output bytes stdout = 1; @@ -62,6 +65,7 @@ message SSHUploadPackResponse { ExitStatus exit_status = 3; } +// This comment is left unintentionally blank. message SSHUploadPackWithSidechannelRequest { // 'repository' must be present in the first message. Repository repository = 1 [(target_repository)=true]; @@ -72,8 +76,11 @@ message SSHUploadPackWithSidechannelRequest { string git_protocol = 3; } -message SSHUploadPackWithSidechannelResponse {} +// This comment is left unintentionally blank. +message SSHUploadPackWithSidechannelResponse { +} +// This comment is left unintentionally blank. message SSHReceivePackRequest { // 'repository' must be present in the first message. Repository repository = 1 [(target_repository)=true]; @@ -82,16 +89,17 @@ message SSHReceivePackRequest { // Contents of GL_ID, GL_REPOSITORY, and GL_USERNAME environment variables // for 'git receive-pack' string gl_id = 3; + // This comment is left unintentionally blank. string gl_repository = 4; + // This comment is left unintentionally blank. string gl_username = 5; - // Git protocol version string git_protocol = 6; - // Parameters to use with git -c (key=value pairs) repeated string git_config_options = 7; } +// This comment is left unintentionally blank. message SSHReceivePackResponse { // A chunk of raw data from 'git receive-pack' standard output bytes stdout = 1; @@ -102,6 +110,7 @@ message SSHReceivePackResponse { ExitStatus exit_status = 3; } +// This comment is left unintentionally blank. message SSHUploadArchiveRequest { // 'repository' must be present in the first message. Repository repository = 1 [(target_repository)=true]; @@ -109,6 +118,7 @@ message SSHUploadArchiveRequest { bytes stdin = 2; } +// This comment is left unintentionally blank. message SSHUploadArchiveResponse { // A chunk of raw data from 'git upload-archive' standard output bytes stdout = 1; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/transaction.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/transaction.proto new file mode 100644 index 0000000000..448705f9ae --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/transaction.proto @@ -0,0 +1,101 @@ +syntax = "proto3"; + +package gitaly; + +import "lint.proto"; +import "shared.proto"; + +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; + +// RefTransaction is a service which provides RPCs to interact with reference +// transactions. Reference transactions are used in the context of Gitaly +// Cluster to ensure that all nodes part of a single transaction perform the +// same change: given a set of changes, the changes are hashed and the hash is +// then voted on. +service RefTransaction { + option (intercepted) = true; + + // VoteTransaction casts a vote on a transaction to establish whether the + // node is doing the same change as all the other nodes part of the + // transaction. This RPC blocks until quorum has been reached, which may be + // _before_ all nodes have cast a vote. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. + rpc VoteTransaction (VoteTransactionRequest) returns (VoteTransactionResponse); + + // StopTransaction gracefully stops a transaction. This RPC can be used if + // only a subset of nodes executes specific code which may cause the + // transaction to fail. One such example is Git hooks, which only execute on + // the primary Gitaly noded. Other nodes which vote on this transaction will + // get a response with the `STOP` state being set. + // + // This RPC may return one of the following error codes: + // + // - `NotFound` in case the transaction could not be found. + // - `Canceled` in case the transaction has been canceled before quorum was + // reached. + rpc StopTransaction (StopTransactionRequest) returns (StopTransactionResponse); + +} + +// This comment is left unintentionally blank. +message VoteTransactionRequest { + // This comment is left unintentionally blank. + enum Phase { + // UNKNOWN_PHASE is the unknown voting phase. This value has been the + // default because phases have been introduced. Eventually, using this + // phase will become unsupported. + UNKNOWN_PHASE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // PREPARED_PHASE is the prepratory phase. The data that is about to change + // is locked for concurrent modification, but changes have not yet been + // written to disk. + PREPARED_PHASE = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // COMMITTED_PHASE is the committing phase. Data has been committed to disk + // and will be visible in all subsequent requests. + COMMITTED_PHASE = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + }; + + // This comment is left unintentionally blank. + Repository repository = 1[(target_repository)=true]; + // ID of the transaction we're processing + uint64 transaction_id = 2; + // Name of the Gitaly node that's voting on a transaction. + string node = 3; + // SHA1 of the references that are to be updated + bytes reference_updates_hash = 4; + // Phase is the voting phase. + Phase phase = 5; +} + +// This comment is left unintentionally blank. +message VoteTransactionResponse { + // The outcome of the given transaction telling the client whether the + // transaction should be committed or rolled back. + enum TransactionState { + // This comment is left unintentionally blank. + COMMIT = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + ABORT = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + // This comment is left unintentionally blank. + STOP = 2; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. + TransactionState state = 1; +} + +// This comment is left unintentionally blank. +message StopTransactionRequest { + // This comment is left unintentionally blank. + Repository repository = 1[(target_repository)=true]; + // ID of the transaction we're processing + uint64 transaction_id = 2; +} + +// This comment is left unintentionally blank. +message StopTransactionResponse { +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/wiki.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/wiki.proto similarity index 51% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/wiki.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/wiki.proto index dd41bc257f..d50c262a4e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/wiki.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/proto/wiki.proto @@ -1,66 +1,92 @@ syntax = "proto3"; +package gitaly; + import "lint.proto"; import "shared.proto"; -package gitaly; - -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; +// WikiService is a service that provides Wiki-related functionality. This +// service is deprecated and should not be used anymore. Instead, all +// functionality to implement Wikis should use Git-based RPCS. service WikiService { + + // This comment is left unintentionally blank. rpc WikiWritePage(stream WikiWritePageRequest) returns (WikiWritePageResponse) { option (op_type) = { op: MUTATOR }; } + + // This comment is left unintentionally blank. rpc WikiUpdatePage(stream WikiUpdatePageRequest) returns (WikiUpdatePageResponse) { option (op_type) = { op: MUTATOR }; } + // WikiFindPage returns a stream because the page's raw_data field may be arbitrarily large. rpc WikiFindPage(WikiFindPageRequest) returns (stream WikiFindPageResponse) { option (op_type) = { op: ACCESSOR }; } + + // This comment is left unintentionally blank. rpc WikiGetAllPages(WikiGetAllPagesRequest) returns (stream WikiGetAllPagesResponse) { option (op_type) = { op: ACCESSOR }; - } + + // This comment is left unintentionally blank. rpc WikiListPages(WikiListPagesRequest) returns (stream WikiListPagesResponse) { option (op_type) = { op: ACCESSOR }; - } + } +// This comment is left unintentionally blank. message WikiCommitDetails { + // This comment is left unintentionally blank. bytes name = 1; + // This comment is left unintentionally blank. bytes email = 2; + // This comment is left unintentionally blank. bytes message = 3; + // This comment is left unintentionally blank. int32 user_id = 4; + // This comment is left unintentionally blank. bytes user_name = 5; } +// This comment is left unintentionally blank. message WikiPageVersion { + // This comment is left unintentionally blank. GitCommit commit = 1; + // This comment is left unintentionally blank. string format = 2; } +// This comment is left unintentionally blank. message WikiPage { // These fields are only present in the first message of a WikiPage stream WikiPageVersion version = 1; + // This comment is left unintentionally blank. string format = 2; + // This comment is left unintentionally blank. bytes title = 3; + // This comment is left unintentionally blank. string url_path = 4; + // This comment is left unintentionally blank. bytes path = 5; + // This comment is left unintentionally blank. bytes name = 6; + // This comment is left unintentionally blank. bool historical = 7; - // This field is present in all messages of a WikiPage stream bytes raw_data = 8; } @@ -69,37 +95,53 @@ message WikiPage { message WikiWritePageRequest { // These following fields are only present in the first message. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes name = 2; + // This comment is left unintentionally blank. string format = 3; + // This comment is left unintentionally blank. WikiCommitDetails commit_details = 4; // This field is present in all messages. bytes content = 5; } +// This comment is left unintentionally blank. message WikiWritePageResponse { + // This comment is left unintentionally blank. bytes duplicate_error = 1; } +// This comment is left unintentionally blank. message WikiUpdatePageRequest { // There fields are only present in the first message of the stream Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes page_path = 2; + // This comment is left unintentionally blank. bytes title = 3; + // This comment is left unintentionally blank. string format = 4; + // This comment is left unintentionally blank. WikiCommitDetails commit_details = 5; - // This field is present in all messages bytes content = 6; } +// This comment is left unintentionally blank. message WikiUpdatePageResponse { + // This comment is left unintentionally blank. bytes error = 1; } +// This comment is left unintentionally blank. message WikiFindPageRequest { + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; + // This comment is left unintentionally blank. bytes title = 2; + // This comment is left unintentionally blank. bytes revision = 3; + // This comment is left unintentionally blank. bytes directory = 4; // prevents the content from being sent over the response bool skip_content = 5; @@ -108,45 +150,62 @@ message WikiFindPageRequest { // WikiFindPageResponse is a stream because we need multiple WikiPage // messages to send the raw_data field. message WikiFindPageResponse { + // This comment is left unintentionally blank. WikiPage page = 1; } +// This comment is left unintentionally blank. message WikiGetAllPagesRequest { + // This comment is left unintentionally blank. + enum SortBy { + // This comment is left unintentionally blank. + TITLE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + CREATED_AT = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Passing 0 means no limit is applied uint32 limit = 2; + // This comment is left unintentionally blank. bool direction_desc = 3; - - enum SortBy { - TITLE = 0; - CREATED_AT = 1; - } + // This comment is left unintentionally blank. SortBy sort = 4; } // The WikiGetAllPagesResponse stream is a concatenation of WikiPage streams message WikiGetAllPagesResponse { + // This comment is left unintentionally blank. WikiPage page = 1; // When end_of_page is true it signals a change of page for the next Response message (if any) bool end_of_page = 2; } +// This comment is left unintentionally blank. message WikiListPagesRequest { + // This comment is left unintentionally blank. + enum SortBy { + // This comment is left unintentionally blank. + TITLE = 0; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH + // This comment is left unintentionally blank. + CREATED_AT = 1; // protolint:disable:this ENUM_FIELD_NAMES_PREFIX + } + + // This comment is left unintentionally blank. Repository repository = 1 [(target_repository)=true]; // Passing 0 means no limit is applied uint32 limit = 2; + // This comment is left unintentionally blank. bool direction_desc = 3; - - enum SortBy { - TITLE = 0; - CREATED_AT = 1; - } + // This comment is left unintentionally blank. SortBy sort = 4; - + // This comment is left unintentionally blank. uint32 offset = 5; } // The WikiListPagesResponse stream is a concatenation of WikiPage streams without content message WikiListPagesResponse { + // This comment is left unintentionally blank. WikiPage page = 1; } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/.rubocop.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/.rubocop.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/.rubocop.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/.rubocop.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/.rubocop_todo.yml b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/.rubocop_todo.yml similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/.rubocop_todo.yml rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/.rubocop_todo.yml diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile index 787e705f94..7fa9b5b307 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile @@ -1,9 +1,9 @@ source 'https://rubygems.org' gem 'rugged', '~> 1.2' -gem 'github-linguist', '~> 7.12', require: 'linguist' +gem 'github-linguist', '~> 7.20.0', require: 'linguist' gem 'gitlab-markup', '~> 1.7.1' -gem 'activesupport', '~> 6.1.4.7' +gem 'activesupport', '~> 6.1.6.1' gem 'rdoc', '~> 6.0' gem 'gitlab-gollum-lib', '~> 4.2.7.10.gitlab.2', require: false gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4.4.gitlab.1', require: false @@ -13,13 +13,13 @@ gem 'faraday', '~> 1.0' gem 'rbtrace', require: false # Labkit provides observability functionality -gem 'gitlab-labkit', '~> 0.21.1' +gem 'gitlab-labkit', '~> 0.24' # Detects the open source license the repository includes # This version needs to be in sync with GitLab CE/EE -gem 'licensee', '~> 9.14.1' +gem 'licensee', '~> 9.15' -gem 'google-protobuf', '~> 3.19.0' +gem 'google-protobuf', '~> 3.21.0' group :development, :test do gem 'rubocop', '~> 0.69', require: false diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile.lock b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile.lock similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile.lock rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile.lock index cc37adacce..616dabbe08 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/Gemfile.lock +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/Gemfile.lock @@ -2,20 +2,20 @@ GEM remote: https://rubygems.org/ specs: abstract_type (0.0.7) - actionpack (6.1.4.7) - actionview (= 6.1.4.7) - activesupport (= 6.1.4.7) + actionpack (6.1.6.1) + actionview (= 6.1.6.1) + activesupport (= 6.1.6.1) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actionview (6.1.4.7) - activesupport (= 6.1.4.7) + actionview (6.1.6.1) + activesupport (= 6.1.6.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activesupport (6.1.4.7) + activesupport (6.1.6.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -24,7 +24,7 @@ GEM adamantium (0.2.0) ice_nine (~> 0.11.0) memoizable (~> 0.4.0) - addressable (2.7.0) + addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.2) binding_ninja (0.2.3) @@ -39,20 +39,20 @@ GEM diff-lcs (1.3) dotenv (2.7.6) equalizer (0.0.11) - erubi (1.10.0) - escape_utils (1.2.1) + erubi (1.11.0) + escape_utils (1.2.2) factory_bot (5.0.2) activesupport (>= 4.2.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) - ffi (1.15.3) + ffi (1.15.5) gemojione (3.3.0) json - github-linguist (7.12.1) + github-linguist (7.20.0) charlock_holmes (~> 0.7.7) escape_utils (~> 1.2.0) mini_mime (~> 1.0) - rugged (>= 0.25.1) + rugged (~> 1.0) github-markup (1.7.0) gitlab-gollum-lib (4.2.7.10.gitlab.2) gemojione (~> 3.2) @@ -65,11 +65,11 @@ GEM gitlab-gollum-rugged_adapter (0.4.4.4.gitlab.1) mime-types (>= 1.15) rugged (~> 1.0) - gitlab-labkit (0.21.2) - actionpack (>= 5.0.0, < 7.0.0) - activesupport (>= 5.0.0, < 7.0.0) - grpc (~> 1.30) - jaeger-client (~> 1.1) + gitlab-labkit (0.24.0) + actionpack (>= 5.0.0, < 8.0.0) + activesupport (>= 5.0.0, < 8.0.0) + grpc (>= 1.37) + jaeger-client (~> 1.1.0) opentracing (~> 0.4) pg_query (~> 2.1) redis (> 3.0.0, < 5.0.0) @@ -81,27 +81,27 @@ GEM with_env (= 1.1.0) xml-simple (~> 1.1.5) gitlab-markup (1.7.1) - google-protobuf (3.19.1) - googleapis-common-protos-types (1.3.0) + google-protobuf (3.21.5) + googleapis-common-protos-types (1.4.0) google-protobuf (~> 3.14) grpc (1.42.0) google-protobuf (~> 3.18) googleapis-common-protos-types (~> 1.0) grpc-tools (1.42.0) - i18n (1.10.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) ice_nine (0.11.2) jaeger-client (1.1.0) opentracing (~> 0.3) thrift - json (2.6.1) - licensee (9.14.1) + json (2.5.1) + licensee (9.15.2) dotenv (~> 2.0) - octokit (~> 4.17) + octokit (~> 4.20) reverse_markdown (~> 1.0) rugged (>= 0.24, < 2.0) thor (>= 0.19, < 2.0) - loofah (2.16.0) + loofah (2.18.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) memoizable (0.4.2) @@ -110,12 +110,12 @@ GEM mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2020.1104) - mini_mime (1.0.2) + mini_mime (1.1.2) mini_portile2 (2.8.0) - minitest (5.15.0) + minitest (5.16.3) msgpack (1.3.3) multipart-post (2.1.1) - nokogiri (1.13.3) + nokogiri (1.13.8) mini_portile2 (~> 2.8.0) racc (~> 1.4) octokit (4.20.0) @@ -126,8 +126,8 @@ GEM parallel (1.19.2) parser (3.0.3.2) ast (~> 2.4.1) - pg_query (2.1.1) - google-protobuf (>= 3.17.1) + pg_query (2.1.3) + google-protobuf (>= 3.19.2) proc_to_ast (0.1.0) coderay parser @@ -136,15 +136,15 @@ GEM pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) - public_suffix (4.0.6) + public_suffix (4.0.7) racc (1.6.0) - rack (2.2.3) - rack-test (1.1.0) - rack (>= 1.0, < 3) + rack (2.2.4) + rack-test (2.0.2) + rack (>= 1.3) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) + rails-html-sanitizer (1.4.3) loofah (~> 2.3) rainbow (3.0.0) rbtrace (0.4.14) @@ -152,12 +152,12 @@ GEM msgpack (>= 0.4.3) optimist (>= 3.0.0) rdoc (6.3.2) - redis (4.4.0) + redis (4.8.0) regexp_parser (1.8.1) reverse_markdown (1.4.0) nokogiri rexml (3.2.5) - rouge (3.27.0) + rouge (3.30.0) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -202,10 +202,10 @@ GEM stringex (2.8.5) thor (1.1.0) thread_safe (0.3.6) - thrift (0.15.0) + thrift (0.16.0) timecop (0.9.1) tomlrb (2.0.1) - tzinfo (2.0.4) + tzinfo (2.0.5) concurrent-ruby (~> 1.0) unicode-display_width (1.7.0) unparser (0.4.7) @@ -219,25 +219,25 @@ GEM with_env (1.1.0) xml-simple (1.1.9) rexml - zeitwerk (2.5.4) + zeitwerk (2.6.0) PLATFORMS ruby DEPENDENCIES - activesupport (~> 6.1.4.7) + activesupport (~> 6.1.6.1) factory_bot faraday (~> 1.0) - github-linguist (~> 7.12) + github-linguist (~> 7.20.0) gitlab-gollum-lib (~> 4.2.7.10.gitlab.2) gitlab-gollum-rugged_adapter (~> 0.4.4.4.gitlab.1) - gitlab-labkit (~> 0.21.1) + gitlab-labkit (~> 0.24) gitlab-license_finder gitlab-markup (~> 1.7.1) - google-protobuf (~> 3.19.0) + google-protobuf (~> 3.21.0) grpc (~> 1.42.0) grpc-tools (~> 1.42.0) - licensee (~> 9.14.1) + licensee (~> 9.15) pry (~> 0.12.2) rbtrace rdoc (~> 6.0) @@ -249,4 +249,4 @@ DEPENDENCIES timecop BUNDLED WITH - 2.1.4 + 2.3.15 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-linguist b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-linguist new file mode 100755 index 0000000000..f06e29b354 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-linguist @@ -0,0 +1,86 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'json' +require 'linguist' +require 'optparse' +require 'rugged' +require 'tempfile' +require 'zlib' + +LANGUAGE_STATS_CACHE = 'language-stats.cache' +LANGUAGE_STATS_CACHE_VERSION = "v3:#{Linguist::VERSION}" + +def gitaly_linguist(args) + repository_path = nil + commit = nil + + parser = OptionParser.new do |opts| + opts.on("-rREPOSITORY", "--repository=REPOSITORY", "Repository to scan") { |r| repository_path = r } + opts.on("-cCOMMIT", "--commit=COMMIT", "Commit to scan") { |c| commit = c } + opts.on("-h", "--help", "Prints this help") do + puts opts + exit + end + end + + parser.parse!(args) + + raise OptionParser::MissingArgument, 'repository' if repository_path.nil? + raise OptionParser::MissingArgument, 'commit' if commit.nil? + + Rugged::Settings['search_path_system'] = '/dev/null' + Rugged::Settings['search_path_global'] = '/dev/null' + Rugged::Settings['search_path_xdg'] = '/dev/null' + + repository = Rugged::Repository.bare(repository_path) + project = Linguist::Repository.new(repository, commit) + + if (cache = load_cache(repository_path)) + old_commit_oid, old_stats = cache + + project.load_existing_stats(old_commit_oid, old_stats) + end + + puts JSON.dump(project.languages) + + write_cache(repository_path, commit, project.cache) +end + +def cache_file(repo_path) + File.join(repo_path, LANGUAGE_STATS_CACHE) +end + +def load_cache(repo_path) + cached_data = File.open(cache_file(repo_path), "rb") do |f| + Zlib::Inflate.inflate(f.read) + end + + # rubocop:disable Security/MarshalLoad + # + # While this is ugly, it's the same as we previously did in git-linguist. So + # for backwards-compatibility reasons we can't change this. + version, commit, stats = Marshal.load(cached_data) + # rubocop:enable Security/MarshalLoad + + if version == LANGUAGE_STATS_CACHE_VERSION && commit && stats + [commit, stats] + end +rescue SystemCallError, ::Zlib::DataError, ::Zlib::BufError, TypeError + nil +end + +def write_cache(repo_path, commit, stats) + cache = [LANGUAGE_STATS_CACHE_VERSION, commit, stats] + + Tempfile.open('cache_file', repo_path) do |f| + marshal = Marshal.dump(cache) + f.write(Zlib::Deflate.deflate(marshal)) + f.close + File.rename(f.path, cache_file(repo_path)) + end + + FileUtils.chmod 0o644, cache_file(repo_path) +end + +gitaly_linguist(ARGV) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/bin/gitaly-ruby b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-ruby similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/bin/gitaly-ruby rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-ruby index d373529453..7ec1136747 100755 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/bin/gitaly-ruby +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/gitaly-ruby @@ -31,6 +31,8 @@ def main FileUtils.mkdir_p(socket_dir) File.chmod(0700, socket_dir) + Labkit::FIPS.enable_fips_mode! if Labkit::FIPS.enabled? + set_rugged_search_path load_distributed_tracing @@ -73,6 +75,8 @@ def set_rugged_search_path return unless search_path Rugged::Settings['search_path_system'] = search_path + Rugged::Settings['search_path_global'] = '/dev/null' + Rugged::Settings['search_path_xdg'] = '/dev/null' end def load_distributed_tracing diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/bin/ruby-cd b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/ruby-cd similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/bin/ruby-cd rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/bin/ruby-cd diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/client.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/client.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/client.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/client.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/exception_sanitizer_interceptor.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/exception_sanitizer_interceptor.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/exception_sanitizer_interceptor.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/exception_sanitizer_interceptor.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/feature_flags.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/feature_flags.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/feature_flags.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/feature_flags.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/health_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/health_service.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/health_service.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/health_service.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/repository_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/repository_service.rb new file mode 100644 index 0000000000..514e80723b --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/repository_service.rb @@ -0,0 +1,28 @@ +require 'licensee' + +module GitalyServer + class RepositoryService < Gitaly::RepositoryService::Service + include Utils + + def find_license(request, call) + repo = Gitlab::Git::Repository.from_gitaly(request.repository, call) + + begin + project = ::Licensee.project(repo.path) + return Gitaly::FindLicenseResponse.new(license_short_name: "") unless project&.license + + license = project.license + return Gitaly::FindLicenseResponse.new( + license_short_name: license.key || "", + license_name: license.name || "", + license_url: license.url || "", + license_path: project.matched_file&.filename, + license_nickname: license.nickname || "" + ) + rescue Rugged::Error + end + + Gitaly::FindLicenseResponse.new(license_short_name: "") + end + end +end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/rugged_interceptor.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/rugged_interceptor.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/rugged_interceptor.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/rugged_interceptor.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/sentry.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/sentry.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/sentry.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/sentry.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/sentry_interceptor.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/sentry_interceptor.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/sentry_interceptor.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/sentry_interceptor.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/utils.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/utils.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/utils.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/utils.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/wiki_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/wiki_service.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitaly_server/wiki_service.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitaly_server/wiki_service.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/config.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/config.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/config.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/config.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/encoding_helper.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/encoding_helper.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/encoding_helper.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/encoding_helper.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git.rb similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git.rb index ec2c97e3ef..3e8c75da35 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git.rb @@ -2,6 +2,7 @@ require 'rugged' require 'linguist/blob_helper' require 'securerandom' +require 'gitlab-labkit' # Ruby on Rails mix-ins that GitLab::Git code relies on require 'active_support/core_ext/object/blank' @@ -21,7 +22,6 @@ dir = __dir__ # Some later requires are order-sensitive. Manually require whatever we need. require_relative "#{dir}/encoding_helper.rb" require_relative "#{dir}/utils/strong_memoize.rb" -require_relative "#{dir}/git/remote_repository.rb" require_relative "#{dir}/git/popen.rb" # Require all .rb files we can find in the gitlab lib directory diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/branch.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/branch.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/branch.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/branch.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/commit.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/commit.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/commit.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/commit.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/committer_with_hooks.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/committer_with_hooks.rb similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/committer_with_hooks.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/committer_with_hooks.rb index 90e98e729d..57ca4ac5be 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/committer_with_hooks.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/committer_with_hooks.rb @@ -10,8 +10,7 @@ module Gitlab def commit result = Gitlab::Git::OperationService.new(git_user, gl_wiki.repository).with_branch( - @wiki.ref, - start_branch_name: @wiki.ref + @wiki.ref ) do |_start_commit| super(false) end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/hook.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/hook.rb similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/hook.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/hook.rb index 58c99503ca..8084cd74c8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/hook.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/hook.rb @@ -116,7 +116,7 @@ module Gitlab git_path: Gitlab.config.git.bin_path, internal_socket: Gitlab.config.gitaly.internal_socket, internal_socket_token: ENV['GITALY_TOKEN'], - receive_hooks_payload: { + user_details: { userid: gl_id, username: gl_username, protocol: GL_PROTOCOL diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/hooks_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/hooks_service.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/hooks_service.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/hooks_service.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/operation_service.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/operation_service.rb similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/operation_service.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/operation_service.rb index 0ab3116943..902a707ada 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/operation_service.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/operation_service.rb @@ -25,43 +25,22 @@ module Gitlab @repository = new_repository end - # Whenever `start_branch_name` or `start_sha` is passed, if `branch_name` - # doesn't exist, it will be created from the commit pointed to by - # `start_branch_name` or `start_sha`. - # - # If `start_repository` is passed, and the branch doesn't exist, - # it would try to find the commits from it instead of current repository. - def with_branch(branch_name, - start_branch_name: nil, - start_sha: nil, - start_repository: repository, - force: false, - &block) - start_repository = RemoteRepository.new(start_repository) unless start_repository.is_a?(RemoteRepository) - - start_branch_name = nil if start_repository.empty? - - if start_branch_name.present? && !start_repository.branch_exists?(start_branch_name) - raise ArgumentError, "Cannot find branch '#{start_branch_name}'" - elsif start_sha.present? && !start_repository.commit_id(start_sha) - raise ArgumentError, "Cannot find commit '#{start_sha}'" + # Execute the block with the tip commit referenced by the given branch. + # The branch must exist before calling this function. + def with_branch(branch_name, &block) + if !repository.empty? && !repository.branch_exists?(branch_name) + raise ArgumentError, "Cannot find branch '#{branch_name}'" end - update_branch_with_hooks(branch_name, force) do - repository.with_repo_branch_commit( - start_repository, - start_sha.presence || start_branch_name.presence || branch_name, - &block - ) + update_branch_with_hooks(branch_name) do + repository.with_repo_branch_commit(branch_name, &block) end end private # Returns [newrev, should_run_after_create, should_run_after_create_branch] - def update_branch_with_hooks(branch_name, force) - update_autocrlf_option - + def update_branch_with_hooks(branch_name) was_empty = repository.empty? # Make commit @@ -70,7 +49,7 @@ module Gitlab raise Gitlab::Git::CommitError.new('Failed to create commit') unless newrev branch = repository.find_branch(branch_name) - oldrev = find_oldrev_from_branch(newrev, branch, force) + oldrev = find_oldrev_from_branch(newrev, branch) ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name update_ref_in_hooks(ref, newrev, oldrev) @@ -78,13 +57,11 @@ module Gitlab BranchUpdate.new(newrev, was_empty, was_empty || Gitlab::Git.blank_ref?(oldrev)) end - def find_oldrev_from_branch(newrev, branch, force) + def find_oldrev_from_branch(newrev, branch) return Gitlab::Git::BLANK_SHA unless branch oldrev = branch.target - return oldrev if force - merge_base = repository.merge_base(newrev, branch.target) raise Gitlab::Git::Repository::InvalidRef unless merge_base @@ -139,10 +116,6 @@ module Gitlab ) end end - - def update_autocrlf_option - repository.autocrlf = :input if repository.autocrlf != :input - end end end end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/popen.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/popen.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/popen.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/popen.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/push_options.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/push_options.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/push_options.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/push_options.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/ref.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/ref.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/ref.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/ref.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/repository.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/repository.rb similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/repository.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/repository.rb index 92107b9c65..cbe5bde195 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/repository.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/repository.rb @@ -9,7 +9,6 @@ module Gitlab include Gitlab::Utils::StrongMemoize GITALY_INTERNAL_URL = 'ssh://gitaly/internal.git'.freeze - AUTOCRLF_VALUES = { 'true' => true, 'false' => false, 'input' => :input }.freeze RUGGED_KEY = :rugged_list GIT_ALLOW_SHA_UPLOAD = 'uploadpack.allowAnySHA1InWant=true'.freeze @@ -177,26 +176,12 @@ module Gitlab end end - def with_repo_branch_commit(start_repository, start_ref) - start_repository = RemoteRepository.new(start_repository) unless start_repository.is_a?(RemoteRepository) - - if start_repository.empty? - return yield nil - elsif start_repository.same_repository?(self) - # Directly return the commit from this repository - return yield commit(start_ref) - end - - # Find the commit from the remote repository (this triggers an RPC) - commit_id = start_repository.commit_id(start_ref) - return yield nil unless commit_id - - if existing_commit = commit(commit_id) - # Commit is already present (e.g. in a fork, or through a previous fetch) - yield existing_commit + def with_repo_branch_commit(start_ref) + if empty? + yield nil else - fetch_sha(start_repository, commit_id) - yield commit(commit_id) + # Directly return the commit from this repository + yield commit(start_ref) end end @@ -237,19 +222,6 @@ module Gitlab nil end - # Fetch a commit from the given source repository - def fetch_sha(source_repository, sha) - source_repository = RemoteRepository.new(source_repository) unless source_repository.is_a?(RemoteRepository) - - env = source_repository.fetch_env(git_config_options: [GIT_ALLOW_SHA_UPLOAD]) - - args = %W[fetch --no-tags #{GITALY_INTERNAL_URL} #{sha}] - message, status = run_git(args, env: env, include_stderr: true) - raise Gitlab::Git::CommandError, message unless status.zero? - - sha - end - # Lookup for rugged object by oid or ref name def lookup(oid_or_ref_name) rugged.rev_parse(oid_or_ref_name) @@ -271,14 +243,6 @@ module Gitlab !has_visible_content? end - def autocrlf - AUTOCRLF_VALUES[rugged.config['core.autocrlf']] - end - - def autocrlf=(value) - rugged.config['core.autocrlf'] = AUTOCRLF_VALUES.invert[value] - end - def cleanup # Opening a repository may be expensive, and we only need to close it # if it's been open. @@ -286,25 +250,15 @@ module Gitlab end def head_symbolic_ref - message, status = run_git(%w[symbolic-ref HEAD]) + head = rugged.ref('HEAD') - return 'main' if status.nonzero? + return 'main' if head.type != :symbolic - Ref.extract_branch_name(message.squish) + Ref.extract_branch_name(head.target_id) end private - def run_git(args, chdir: path, env: {}, nice: false, include_stderr: false, lazy_block: nil, &block) - cmd = [Gitlab.config.git.bin_path, *args] - cmd.unshift("nice") if nice - - object_directories = alternate_object_directories - env['GIT_ALTERNATE_OBJECT_DIRECTORIES'] = object_directories.join(File::PATH_SEPARATOR) if object_directories.any? - - popen(cmd, chdir, env, include_stderr: include_stderr, lazy_block: lazy_block, &block) - end - def branches_filter(filter: nil, sort_by: nil) branches = rugged.branches.each(filter).map do |rugged_ref| begin diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/tag.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/tag.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/tag.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/tag.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/user.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/user.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/user.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/user.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki_page.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki_page.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki_page.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki_page.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki_page_version.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki_page_version.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git/wiki_page_version.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git/wiki_page_version.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git_logger.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git_logger.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/git_logger.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/git_logger.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/gollum.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/gollum.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/gollum.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/gollum.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/rails_logger.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/rails_logger.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/rails_logger.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/rails_logger.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/utils/strong_memoize.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/utils/strong_memoize.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/lib/gitlab/utils/strong_memoize.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/lib/gitlab/utils/strong_memoize.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/README.md b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/README.md similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/README.md rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/README.md diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly.rb similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly.rb index 9c80cea63b..5ea7a9d046 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly.rb @@ -29,7 +29,7 @@ require 'gitaly/ref_services_pb' require 'gitaly/remote_services_pb' -require 'gitaly/repository-service_services_pb' +require 'gitaly/repository_services_pb' require 'gitaly/server_services_pb' diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/blob_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/blob_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/blob_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/blob_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/blob_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/blob_services_pb.rb similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/blob_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/blob_services_pb.rb index 5eb951f5ee..aaea1d0efe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/blob_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/blob_services_pb.rb @@ -6,6 +6,8 @@ require 'blob_pb' module Gitaly module BlobService + # BlobService is a service which provides RPCs to retrieve Git blobs from a + # specific repository. class Service include ::GRPC::GenericService @@ -18,6 +20,7 @@ module Gitaly # ID. We use a stream to return a chunked arbitrarily large binary # response rpc :GetBlob, ::Gitaly::GetBlobRequest, stream(::Gitaly::GetBlobResponse) + # This comment is left unintentionally blank. rpc :GetBlobs, ::Gitaly::GetBlobsRequest, stream(::Gitaly::GetBlobsResponse) # ListBlobs will list all blobs reachable from a given set of revisions by # doing a graph walk. It is not valid to pass revisions which do not resolve diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/cleanup_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/cleanup_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/cleanup_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/cleanup_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/cleanup_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/cleanup_services_pb.rb similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/cleanup_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/cleanup_services_pb.rb index 643b2ea707..54a0d9fa52 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/cleanup_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/cleanup_services_pb.rb @@ -6,6 +6,7 @@ require 'cleanup_pb' module Gitaly module CleanupService + # CleanupService provides RPCs to clean up a repository's contents. class Service include ::GRPC::GenericService @@ -14,6 +15,7 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.CleanupService' + # This comment is left unintentionally blank. rpc :ApplyBfgObjectMapStream, stream(::Gitaly::ApplyBfgObjectMapStreamRequest), stream(::Gitaly::ApplyBfgObjectMapStreamResponse) end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_pb.rb similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_pb.rb index 1e331cd1f8..4c798267a2 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_pb.rb @@ -1,9 +1,9 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: commit.proto +require 'google/protobuf/timestamp_pb' require 'lint_pb' require 'shared_pb' -require 'google/protobuf/timestamp_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do @@ -20,6 +20,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :after, :message, 8, "google.protobuf.Timestamp" optional :before, :message, 9, "google.protobuf.Timestamp" optional :author, :bytes, 10 + optional :ignore_case, :bool, 12 + repeated :commit_message_patterns, :bytes, 13 end add_enum "gitaly.ListCommitsRequest.Order" do value :NONE, 0 @@ -118,6 +120,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :recursive, :bool, 4 optional :sort, :enum, 5, "gitaly.GetTreeEntriesRequest.SortBy" optional :pagination_params, :message, 6, "gitaly.PaginationParameter" + optional :skip_flat_paths, :bool, 7 end add_enum "gitaly.GetTreeEntriesRequest.SortBy" do value :DEFAULT, 0 @@ -192,6 +195,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :order, :enum, 14, "gitaly.FindCommitsRequest.Order" optional :global_options, :message, 15, "gitaly.GlobalOptions" optional :trailers, :bool, 16 + optional :include_shortstat, :bool, 17 end add_enum "gitaly.FindCommitsRequest.Order" do value :NONE, 0 diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_services_pb.rb similarity index 74% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_services_pb.rb index 131f841228..c99e663fb8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/commit_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/commit_services_pb.rb @@ -6,6 +6,8 @@ require 'commit_pb' module Gitaly module CommitService + # CommitService is a service which provides RPCs that interact with Git + # commits. class Service include ::GRPC::GenericService @@ -21,26 +23,46 @@ module Gitaly # ListAllCommits lists all commits present in the repository, including # those not reachable by any reference. rpc :ListAllCommits, ::Gitaly::ListAllCommitsRequest, stream(::Gitaly::ListAllCommitsResponse) + # This comment is left unintentionally blank. rpc :CommitIsAncestor, ::Gitaly::CommitIsAncestorRequest, ::Gitaly::CommitIsAncestorResponse + # This comment is left unintentionally blank. rpc :TreeEntry, ::Gitaly::TreeEntryRequest, stream(::Gitaly::TreeEntryResponse) + # This comment is left unintentionally blank. rpc :CountCommits, ::Gitaly::CountCommitsRequest, ::Gitaly::CountCommitsResponse + # This comment is left unintentionally blank. rpc :CountDivergingCommits, ::Gitaly::CountDivergingCommitsRequest, ::Gitaly::CountDivergingCommitsResponse + # This comment is left unintentionally blank. rpc :GetTreeEntries, ::Gitaly::GetTreeEntriesRequest, stream(::Gitaly::GetTreeEntriesResponse) + # This comment is left unintentionally blank. rpc :ListFiles, ::Gitaly::ListFilesRequest, stream(::Gitaly::ListFilesResponse) + # This comment is left unintentionally blank. rpc :FindCommit, ::Gitaly::FindCommitRequest, ::Gitaly::FindCommitResponse + # This comment is left unintentionally blank. rpc :CommitStats, ::Gitaly::CommitStatsRequest, ::Gitaly::CommitStatsResponse # Use a stream to paginate the result set rpc :FindAllCommits, ::Gitaly::FindAllCommitsRequest, stream(::Gitaly::FindAllCommitsResponse) + # This comment is left unintentionally blank. rpc :FindCommits, ::Gitaly::FindCommitsRequest, stream(::Gitaly::FindCommitsResponse) + # CommitLanguages detects the source code languages of the whole tree for a + # given commit. Returns an error in case no languages could be detected. rpc :CommitLanguages, ::Gitaly::CommitLanguagesRequest, ::Gitaly::CommitLanguagesResponse + # This comment is left unintentionally blank. rpc :RawBlame, ::Gitaly::RawBlameRequest, stream(::Gitaly::RawBlameResponse) + # This comment is left unintentionally blank. rpc :LastCommitForPath, ::Gitaly::LastCommitForPathRequest, ::Gitaly::LastCommitForPathResponse + # This comment is left unintentionally blank. rpc :ListLastCommitsForTree, ::Gitaly::ListLastCommitsForTreeRequest, stream(::Gitaly::ListLastCommitsForTreeResponse) + # This comment is left unintentionally blank. rpc :CommitsByMessage, ::Gitaly::CommitsByMessageRequest, stream(::Gitaly::CommitsByMessageResponse) + # This comment is left unintentionally blank. rpc :ListCommitsByOid, ::Gitaly::ListCommitsByOidRequest, stream(::Gitaly::ListCommitsByOidResponse) + # This comment is left unintentionally blank. rpc :ListCommitsByRefName, ::Gitaly::ListCommitsByRefNameRequest, stream(::Gitaly::ListCommitsByRefNameResponse) + # This comment is left unintentionally blank. rpc :FilterShasWithSignatures, stream(::Gitaly::FilterShasWithSignaturesRequest), stream(::Gitaly::FilterShasWithSignaturesResponse) + # This comment is left unintentionally blank. rpc :GetCommitSignatures, ::Gitaly::GetCommitSignaturesRequest, stream(::Gitaly::GetCommitSignaturesResponse) + # This comment is left unintentionally blank. rpc :GetCommitMessages, ::Gitaly::GetCommitMessagesRequest, stream(::Gitaly::GetCommitMessagesResponse) # CheckObjectsExist will check for the existence of revisions against a # repository. It returns two sets of data. An array containing the revisions diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_pb.rb index 1338cf2d5e..1dcc1cdbe6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_pb.rb @@ -1,9 +1,9 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: conflicts.proto +require 'google/protobuf/timestamp_pb' require 'lint_pb' require 'shared_pb' -require 'google/protobuf/timestamp_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_services_pb.rb similarity index 78% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_services_pb.rb index 0332407f89..245cdd2eb4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/conflicts_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/conflicts_services_pb.rb @@ -6,6 +6,8 @@ require 'conflicts_pb' module Gitaly module ConflictsService + # ConflictsService is a service which provides RPCs to interact with conflicts + # resulting from a merge. class Service include ::GRPC::GenericService @@ -14,6 +16,8 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.ConflictsService' + # ListConflictFiles returns all conflicting files which result from a merge + # of two specified commit objects. rpc :ListConflictFiles, ::Gitaly::ListConflictFilesRequest, stream(::Gitaly::ListConflictFilesResponse) # ResolveConflicts tries to resolve a conflicting merge with a set of # user-provided merge resolutions. If resolving the conflict succeeds, the diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_pb.rb similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_pb.rb index 5a805b0380..5018218b57 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_pb.rb @@ -92,6 +92,21 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.FindChangedPathsRequest" do optional :repository, :message, 1, "gitaly.Repository" repeated :commits, :string, 2 + repeated :requests, :message, 3, "gitaly.FindChangedPathsRequest.Request" + end + add_message "gitaly.FindChangedPathsRequest.Request" do + oneof :type do + optional :tree_request, :message, 1, "gitaly.FindChangedPathsRequest.Request.TreeRequest" + optional :commit_request, :message, 2, "gitaly.FindChangedPathsRequest.Request.CommitRequest" + end + end + add_message "gitaly.FindChangedPathsRequest.Request.TreeRequest" do + optional :left_tree_revision, :string, 1 + optional :right_tree_revision, :string, 2 + end + add_message "gitaly.FindChangedPathsRequest.Request.CommitRequest" do + optional :commit_revision, :string, 1 + repeated :parent_commit_revisions, :string, 2 end add_message "gitaly.FindChangedPathsResponse" do repeated :paths, :message, 1, "gitaly.ChangedPaths" @@ -99,6 +114,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.ChangedPaths" do optional :path, :bytes, 1 optional :status, :enum, 2, "gitaly.ChangedPaths.Status" + optional :old_mode, :int32, 3 + optional :new_mode, :int32, 4 end add_enum "gitaly.ChangedPaths.Status" do value :ADDED, 0 @@ -125,6 +142,9 @@ module Gitaly DiffStats = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DiffStats").msgclass DiffStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DiffStatsResponse").msgclass FindChangedPathsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindChangedPathsRequest").msgclass + FindChangedPathsRequest::Request = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindChangedPathsRequest.Request").msgclass + FindChangedPathsRequest::Request::TreeRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindChangedPathsRequest.Request.TreeRequest").msgclass + FindChangedPathsRequest::Request::CommitRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindChangedPathsRequest.Request.CommitRequest").msgclass FindChangedPathsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindChangedPathsResponse").msgclass ChangedPaths = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ChangedPaths").msgclass ChangedPaths::Status = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ChangedPaths.Status").enummodule diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_services_pb.rb similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_services_pb.rb index 55807f77a3..c325ed65eb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/diff_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/diff_services_pb.rb @@ -6,6 +6,8 @@ require 'diff_pb' module Gitaly module DiffService + # DiffService is a service which provides RPCs to inspect differences + # introduced between a set of commits. class Service include ::GRPC::GenericService @@ -18,8 +20,11 @@ module Gitaly rpc :CommitDiff, ::Gitaly::CommitDiffRequest, stream(::Gitaly::CommitDiffResponse) # Return a stream so we can divide the response in chunks of deltas rpc :CommitDelta, ::Gitaly::CommitDeltaRequest, stream(::Gitaly::CommitDeltaResponse) + # This comment is left unintentionally blank. rpc :RawDiff, ::Gitaly::RawDiffRequest, stream(::Gitaly::RawDiffResponse) + # This comment is left unintentionally blank. rpc :RawPatch, ::Gitaly::RawPatchRequest, stream(::Gitaly::RawPatchResponse) + # This comment is left unintentionally blank. rpc :DiffStats, ::Gitaly::DiffStatsRequest, stream(::Gitaly::DiffStatsResponse) # Return a list of files changed along with the status of each file rpc :FindChangedPaths, ::Gitaly::FindChangedPathsRequest, stream(::Gitaly::FindChangedPathsResponse) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/errors_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/errors_pb.rb new file mode 100644 index 0000000000..1691cc7606 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/errors_pb.rb @@ -0,0 +1,78 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: errors.proto + +require 'google/protobuf/duration_pb' +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("errors.proto", :syntax => :proto3) do + add_message "gitaly.AccessCheckError" do + optional :error_message, :string, 1 + optional :protocol, :string, 2 + optional :user_id, :string, 3 + optional :changes, :bytes, 4 + end + add_message "gitaly.InvalidRefFormatError" do + repeated :refs, :bytes, 2 + end + add_message "gitaly.NotAncestorError" do + optional :parent_revision, :bytes, 1 + optional :child_revision, :bytes, 2 + end + add_message "gitaly.ChangesAlreadyAppliedError" do + end + add_message "gitaly.MergeConflictError" do + repeated :conflicting_files, :bytes, 1 + repeated :conflicting_commit_ids, :string, 2 + end + add_message "gitaly.ReferencesLockedError" do + repeated :refs, :bytes, 1 + end + add_message "gitaly.ReferenceExistsError" do + optional :reference_name, :bytes, 1 + optional :oid, :string, 2 + end + add_message "gitaly.ReferenceNotFoundError" do + optional :reference_name, :bytes, 1 + end + add_message "gitaly.ReferenceUpdateError" do + optional :reference_name, :bytes, 1 + optional :old_oid, :string, 2 + optional :new_oid, :string, 3 + end + add_message "gitaly.ResolveRevisionError" do + optional :revision, :bytes, 1 + end + add_message "gitaly.LimitError" do + optional :error_message, :string, 1 + optional :retry_after, :message, 2, "google.protobuf.Duration" + end + add_message "gitaly.CustomHookError" do + optional :stdout, :bytes, 1 + optional :stderr, :bytes, 2 + optional :hook_type, :enum, 3, "gitaly.CustomHookError.HookType" + end + add_enum "gitaly.CustomHookError.HookType" do + value :HOOK_TYPE_UNSPECIFIED, 0 + value :HOOK_TYPE_PRERECEIVE, 1 + value :HOOK_TYPE_UPDATE, 2 + value :HOOK_TYPE_POSTRECEIVE, 3 + end + end +end + +module Gitaly + AccessCheckError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.AccessCheckError").msgclass + InvalidRefFormatError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.InvalidRefFormatError").msgclass + NotAncestorError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.NotAncestorError").msgclass + ChangesAlreadyAppliedError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ChangesAlreadyAppliedError").msgclass + MergeConflictError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.MergeConflictError").msgclass + ReferencesLockedError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferencesLockedError").msgclass + ReferenceExistsError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceExistsError").msgclass + ReferenceNotFoundError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceNotFoundError").msgclass + ReferenceUpdateError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceUpdateError").msgclass + ResolveRevisionError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ResolveRevisionError").msgclass + LimitError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.LimitError").msgclass + CustomHookError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.CustomHookError").msgclass + CustomHookError::HookType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.CustomHookError.HookType").enummodule +end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_pb.rb similarity index 87% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_pb.rb index ac5f7ed84b..811749589e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_pb.rb @@ -57,18 +57,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :stderr, :bytes, 2 optional :exit_status, :message, 3, "gitaly.ExitStatus" end - add_message "gitaly.PackObjectsHookRequest" do - optional :repository, :message, 1, "gitaly.Repository" - repeated :args, :string, 2 - optional :stdin, :bytes, 3 - end - add_message "gitaly.PackObjectsHookResponse" do - optional :stdout, :bytes, 1 - optional :stderr, :bytes, 2 - end add_message "gitaly.PackObjectsHookWithSidechannelRequest" do optional :repository, :message, 1, "gitaly.Repository" repeated :args, :string, 2 + optional :gl_id, :string, 3 + optional :gl_username, :string, 5 + optional :git_protocol, :string, 6 end add_message "gitaly.PackObjectsHookWithSidechannelResponse" do end @@ -85,8 +79,6 @@ module Gitaly ReferenceTransactionHookRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceTransactionHookRequest").msgclass ReferenceTransactionHookRequest::State = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceTransactionHookRequest.State").enummodule ReferenceTransactionHookResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReferenceTransactionHookResponse").msgclass - PackObjectsHookRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PackObjectsHookRequest").msgclass - PackObjectsHookResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PackObjectsHookResponse").msgclass PackObjectsHookWithSidechannelRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PackObjectsHookWithSidechannelRequest").msgclass PackObjectsHookWithSidechannelResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PackObjectsHookWithSidechannelResponse").msgclass end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_services_pb.rb similarity index 71% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_services_pb.rb index ad8a46f6fb..0854e819a6 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/hook_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/hook_services_pb.rb @@ -6,6 +6,9 @@ require 'hook_pb' module Gitaly module HookService + # HookService is a service which provides the implementation of a subset of + # Git hooks. These are typically invoked via the `gitaly-hooks` binary to + # ensure that the actual hook logic is executed in the context of the server. class Service include ::GRPC::GenericService @@ -14,12 +17,14 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.HookService' + # This comment is left unintentionally blank. rpc :PreReceiveHook, stream(::Gitaly::PreReceiveHookRequest), stream(::Gitaly::PreReceiveHookResponse) + # This comment is left unintentionally blank. rpc :PostReceiveHook, stream(::Gitaly::PostReceiveHookRequest), stream(::Gitaly::PostReceiveHookResponse) + # This comment is left unintentionally blank. rpc :UpdateHook, ::Gitaly::UpdateHookRequest, stream(::Gitaly::UpdateHookResponse) + # This comment is left unintentionally blank. rpc :ReferenceTransactionHook, stream(::Gitaly::ReferenceTransactionHookRequest), stream(::Gitaly::ReferenceTransactionHookResponse) - # PackObjectsHook has been replaced by PackObjectsHookWithSidechannel. Remove in 15.0. - rpc :PackObjectsHook, stream(::Gitaly::PackObjectsHookRequest), stream(::Gitaly::PackObjectsHookResponse) # PackObjectsHookWithSidechannel is an optimized version of PackObjectsHook that uses # a unix socket side channel. rpc :PackObjectsHookWithSidechannel, ::Gitaly::PackObjectsHookWithSidechannelRequest, ::Gitaly::PackObjectsHookWithSidechannelResponse diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/internal_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/internal_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/internal_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/internal_pb.rb index ecf1659b4a..6c6902907d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/internal_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/internal_pb.rb @@ -1,8 +1,8 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: internal.proto -require 'lint_pb' require 'google/protobuf/timestamp_pb' +require 'lint_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/internal_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/internal_services_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/internal_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/internal_services_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/lint_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/lint_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/lint_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/lint_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/namespace_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/namespace_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/namespace_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/namespace_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/namespace_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/namespace_services_pb.rb similarity index 65% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/namespace_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/namespace_services_pb.rb index 1d9fa61021..ce0a0c2a8e 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/namespace_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/namespace_services_pb.rb @@ -6,6 +6,9 @@ require 'namespace_pb' module Gitaly module NamespaceService + # NamespaceService is a service which provides RPCs to manage namespaces of a + # storage. Namespaces had been used before Gitaly migrated to hashed storages + # and shouldn't be used nowadays anymore. class Service include ::GRPC::GenericService @@ -14,9 +17,13 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.NamespaceService' + # This comment is left unintentionally blank. rpc :AddNamespace, ::Gitaly::AddNamespaceRequest, ::Gitaly::AddNamespaceResponse + # This comment is left unintentionally blank. rpc :RemoveNamespace, ::Gitaly::RemoveNamespaceRequest, ::Gitaly::RemoveNamespaceResponse + # This comment is left unintentionally blank. rpc :RenameNamespace, ::Gitaly::RenameNamespaceRequest, ::Gitaly::RenameNamespaceResponse + # This comment is left unintentionally blank. rpc :NamespaceExists, ::Gitaly::NamespaceExistsRequest, ::Gitaly::NamespaceExistsResponse end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_pb.rb similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_pb.rb index ebbe7fa8f6..f022a19d6d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_pb.rb @@ -37,7 +37,6 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.FetchIntoObjectPoolRequest" do optional :origin, :message, 1, "gitaly.Repository" optional :object_pool, :message, 2, "gitaly.ObjectPool" - optional :repack, :bool, 3 end add_message "gitaly.FetchIntoObjectPoolResponse" do end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_services_pb.rb similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_services_pb.rb index 4f0f1c01ca..fe12b6ab22 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/objectpool_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/objectpool_services_pb.rb @@ -6,6 +6,10 @@ require 'objectpool_pb' module Gitaly module ObjectPoolService + # ObjectPoolService is a service containing RPCs to manipulate object pools. + # An object pool is a separate repository that can be linked to from multiple + # satellite repositories in order to deduplicate common objects between them. + # This is mostly used in the contexet of repository forks. class Service include ::GRPC::GenericService @@ -14,13 +18,22 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.ObjectPoolService' + # This comment is left unintentionally blank. rpc :CreateObjectPool, ::Gitaly::CreateObjectPoolRequest, ::Gitaly::CreateObjectPoolResponse + # This comment is left unintentionally blank. rpc :DeleteObjectPool, ::Gitaly::DeleteObjectPoolRequest, ::Gitaly::DeleteObjectPoolResponse # Repositories are assumed to be stored on the same disk rpc :LinkRepositoryToObjectPool, ::Gitaly::LinkRepositoryToObjectPoolRequest, ::Gitaly::LinkRepositoryToObjectPoolResponse + # This comment is left unintentionally blank. rpc :ReduplicateRepository, ::Gitaly::ReduplicateRepositoryRequest, ::Gitaly::ReduplicateRepositoryResponse + # This comment is left unintentionally blank. rpc :DisconnectGitAlternates, ::Gitaly::DisconnectGitAlternatesRequest, ::Gitaly::DisconnectGitAlternatesResponse + # FetchIntoObjectPool fetches all references from a pool member into an object pool so that + # objects shared between this repository and other pool members can be deduplicated. This RPC + # will perform housekeeping tasks after the object pool has been updated to ensure that the pool + # is in an optimal state. rpc :FetchIntoObjectPool, ::Gitaly::FetchIntoObjectPoolRequest, ::Gitaly::FetchIntoObjectPoolResponse + # This comment is left unintentionally blank. rpc :GetObjectPool, ::Gitaly::GetObjectPoolRequest, ::Gitaly::GetObjectPoolResponse end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_pb.rb similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_pb.rb index 783c34a62c..99e6503975 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_pb.rb @@ -1,10 +1,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: operations.proto -require 'lint_pb' -require 'shared_pb' require 'errors_pb' require 'google/protobuf/timestamp_pb' +require 'lint_pb' +require 'shared_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do @@ -19,6 +19,11 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :branch, :message, 1, "gitaly.Branch" optional :pre_receive_error, :string, 2 end + add_message "gitaly.UserCreateBranchError" do + oneof :error do + optional :custom_hook, :message, 1, "gitaly.CustomHookError" + end + end add_message "gitaly.UserUpdateBranchRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :branch_name, :bytes, 2 @@ -37,6 +42,13 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.UserDeleteBranchResponse" do optional :pre_receive_error, :string, 1 end + add_message "gitaly.UserDeleteBranchError" do + oneof :error do + optional :access_check, :message, 1, "gitaly.AccessCheckError" + optional :reference_update, :message, 2, "gitaly.ReferenceUpdateError" + optional :custom_hook, :message, 3, "gitaly.CustomHookError" + end + end add_message "gitaly.UserDeleteTagRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :tag_name, :bytes, 2 @@ -58,6 +70,14 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :exists, :bool, 2 optional :pre_receive_error, :string, 3 end + add_message "gitaly.UserCreateTagError" do + oneof :error do + optional :access_check, :message, 1, "gitaly.AccessCheckError" + optional :reference_update, :message, 2, "gitaly.ReferenceUpdateError" + optional :custom_hook, :message, 3, "gitaly.CustomHookError" + optional :reference_exists, :message, 4, "gitaly.ReferenceExistsError" + end + end add_message "gitaly.UserMergeBranchRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :user, :message, 2, "gitaly.User" @@ -70,12 +90,13 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.UserMergeBranchResponse" do optional :commit_id, :string, 1 optional :branch_update, :message, 3, "gitaly.OperationBranchUpdate" - optional :pre_receive_error, :string, 4 end add_message "gitaly.UserMergeBranchError" do oneof :error do optional :access_check, :message, 1, "gitaly.AccessCheckError" optional :reference_update, :message, 2, "gitaly.ReferenceUpdateError" + optional :custom_hook, :message, 3, "gitaly.CustomHookError" + optional :merge_conflict, :message, 4, "gitaly.MergeConflictError" end end add_message "gitaly.UserMergeToRefRequest" do @@ -91,7 +112,6 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.UserMergeToRefResponse" do optional :commit_id, :string, 1 - optional :pre_receive_error, :string, 2 end add_message "gitaly.OperationBranchUpdate" do optional :commit_id, :string, 1 @@ -131,6 +151,14 @@ Google::Protobuf::DescriptorPool.generated_pool.build do value :EMPTY, 1 value :CONFLICT, 2 end + add_message "gitaly.UserCherryPickError" do + oneof :error do + optional :cherry_pick_conflict, :message, 1, "gitaly.MergeConflictError" + optional :target_branch_diverged, :message, 2, "gitaly.NotAncestorError" + optional :changes_already_applied, :message, 3, "gitaly.ChangesAlreadyAppliedError" + optional :access_check, :message, 4, "gitaly.AccessCheckError" + end + end add_message "gitaly.UserRevertRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :user, :message, 2, "gitaly.User" @@ -236,7 +264,6 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.UserSquashResponse" do optional :squash_sha, :string, 1 - optional :git_error, :string, 3 end add_message "gitaly.UserRebaseConfirmableError" do oneof :error do @@ -285,14 +312,17 @@ end module Gitaly UserCreateBranchRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateBranchRequest").msgclass UserCreateBranchResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateBranchResponse").msgclass + UserCreateBranchError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateBranchError").msgclass UserUpdateBranchRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserUpdateBranchRequest").msgclass UserUpdateBranchResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserUpdateBranchResponse").msgclass UserDeleteBranchRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserDeleteBranchRequest").msgclass UserDeleteBranchResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserDeleteBranchResponse").msgclass + UserDeleteBranchError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserDeleteBranchError").msgclass UserDeleteTagRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserDeleteTagRequest").msgclass UserDeleteTagResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserDeleteTagResponse").msgclass UserCreateTagRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateTagRequest").msgclass UserCreateTagResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateTagResponse").msgclass + UserCreateTagError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCreateTagError").msgclass UserMergeBranchRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserMergeBranchRequest").msgclass UserMergeBranchResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserMergeBranchResponse").msgclass UserMergeBranchError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserMergeBranchError").msgclass @@ -304,6 +334,7 @@ module Gitaly UserCherryPickRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCherryPickRequest").msgclass UserCherryPickResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCherryPickResponse").msgclass UserCherryPickResponse::CreateTreeError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCherryPickResponse.CreateTreeError").enummodule + UserCherryPickError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserCherryPickError").msgclass UserRevertRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserRevertRequest").msgclass UserRevertResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserRevertResponse").msgclass UserRevertResponse::CreateTreeError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UserRevertResponse.CreateTreeError").enummodule diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_services_pb.rb similarity index 77% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_services_pb.rb index 13a98c011e..f2a427687d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/operations_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/operations_services_pb.rb @@ -18,11 +18,29 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.OperationService' + # This comment is left unintentionally blank. rpc :UserCreateBranch, ::Gitaly::UserCreateBranchRequest, ::Gitaly::UserCreateBranchResponse + # This comment is left unintentionally blank. rpc :UserUpdateBranch, ::Gitaly::UserUpdateBranchRequest, ::Gitaly::UserUpdateBranchResponse + # UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes + # hooks and contacts Rails to verify that the user is indeed allowed to delete that branch. The + # following known error conditions may happen: + # + # - Returns `InvalidArgument` in case either the branch name or user are not set. + # - Returns `FailedPrecondition` in case the branch does not exist. + # - Returns `OK` with a `PreReceiveError` in case custom hooks refused the update. If the + # `gitaly_user_delete_branch_structured_errors` feature flag is enabled this error case will + # instead return `PermissionDenied` with either a `CustomHook` or AccessCheck` structured + # error. + # - Returns `FailedPrecondition` in case updating the reference fails because + # of a concurrent write to the same reference. If the + # `gitaly_user_delete_branch_structured_errors` feature flag is set this error case will + # instead return `FailedPrecondition` with a `ReferenceUpdate` structured error. rpc :UserDeleteBranch, ::Gitaly::UserDeleteBranchRequest, ::Gitaly::UserDeleteBranchResponse - # UserCreateTag creates a new tag. + # UserCreateTag creates a new tag. This RPC knows to create both lightweight and annotated tags + # depending on whether a message is set. rpc :UserCreateTag, ::Gitaly::UserCreateTagRequest, ::Gitaly::UserCreateTagResponse + # This comment is left unintentionally blank. rpc :UserDeleteTag, ::Gitaly::UserDeleteTagRequest, ::Gitaly::UserDeleteTagResponse # UserMergeRef creates a merge commit and updates target_ref to point to that # new commit. The first parent of the merge commit (the main line) is taken diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_pb.rb index 143db977d1..7031b6043a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_pb.rb @@ -1,9 +1,9 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: praefect.proto +require 'google/protobuf/timestamp_pb' require 'lint_pb' require 'shared_pb' -require 'google/protobuf/timestamp_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_services_pb.rb similarity index 94% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_services_pb.rb index 319feaaee6..9ead16a482 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/praefect_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/praefect_services_pb.rb @@ -6,6 +6,8 @@ require 'praefect_pb' module Gitaly module PraefectInfoService + # PraefectInfoService is a service which provides RPCs to query and modify + # Praefect-specific parameters. class Service include ::GRPC::GenericService @@ -14,6 +16,7 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.PraefectInfoService' + # This comment is left unintentionally blank. rpc :RepositoryReplicas, ::Gitaly::RepositoryReplicasRequest, ::Gitaly::RepositoryReplicasResponse # DatalossCheck checks for unavailable repositories. rpc :DatalossCheck, ::Gitaly::DatalossCheckRequest, ::Gitaly::DatalossCheckResponse diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_pb.rb similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_pb.rb index 4424cf61b7..4159a6982a 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_pb.rb @@ -1,9 +1,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ref.proto +require 'errors_pb' +require 'google/protobuf/timestamp_pb' require 'lint_pb' require 'shared_pb' -require 'google/protobuf/timestamp_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do @@ -38,6 +39,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.FindLocalBranchesResponse" do repeated :branches, :message, 1, "gitaly.FindLocalBranchResponse" + repeated :local_branches, :message, 2, "gitaly.Branch" end add_message "gitaly.FindLocalBranchResponse" do optional :name, :bytes, 1 @@ -72,6 +74,11 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.FindTagResponse" do optional :tag, :message, 1, "gitaly.Tag" end + add_message "gitaly.FindTagError" do + oneof :error do + optional :tag_not_found, :message, 1, "gitaly.ReferenceNotFoundError" + end + end add_message "gitaly.FindAllTagsRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :sort_by, :message, 2, "gitaly.FindAllTagsRequest.SortBy" @@ -84,6 +91,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_enum "gitaly.FindAllTagsRequest.SortBy.Key" do value :REFNAME, 0 value :CREATORDATE, 1 + value :VERSION_REFNAME, 2 end add_message "gitaly.FindAllTagsResponse" do repeated :tags, :message, 1, "gitaly.Tag" @@ -131,6 +139,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do add_message "gitaly.DeleteRefsResponse" do optional :git_error, :string, 1 end + add_message "gitaly.DeleteRefsError" do + oneof :error do + optional :invalid_format, :message, 1, "gitaly.InvalidRefFormatError" + optional :references_locked, :message, 2, "gitaly.ReferencesLockedError" + end + end add_message "gitaly.ListBranchNamesContainingCommitRequest" do optional :repository, :message, 1, "gitaly.Repository" optional :commit_id, :string, 2 @@ -232,6 +246,7 @@ module Gitaly FindAllBranchesResponse::Branch = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindAllBranchesResponse.Branch").msgclass FindTagRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindTagRequest").msgclass FindTagResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindTagResponse").msgclass + FindTagError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindTagError").msgclass FindAllTagsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindAllTagsRequest").msgclass FindAllTagsRequest::SortBy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindAllTagsRequest.SortBy").msgclass FindAllTagsRequest::SortBy::Key = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindAllTagsRequest.SortBy.Key").enummodule @@ -247,6 +262,7 @@ module Gitaly FindBranchResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FindBranchResponse").msgclass DeleteRefsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DeleteRefsRequest").msgclass DeleteRefsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DeleteRefsResponse").msgclass + DeleteRefsError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DeleteRefsError").msgclass ListBranchNamesContainingCommitRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ListBranchNamesContainingCommitRequest").msgclass ListBranchNamesContainingCommitResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ListBranchNamesContainingCommitResponse").msgclass ListTagNamesContainingCommitRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ListTagNamesContainingCommitRequest").msgclass diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_services_pb.rb similarity index 80% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_services_pb.rb index feab3e680a..ac905cd7bb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ref_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ref_services_pb.rb @@ -6,6 +6,7 @@ require 'ref_pb' module Gitaly module RefService + # RefService is a service that provides RPCs to list and modify Git references. class Service include ::GRPC::GenericService @@ -14,28 +15,41 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.RefService' + # This comment is left unintentionally blank. rpc :FindDefaultBranchName, ::Gitaly::FindDefaultBranchNameRequest, ::Gitaly::FindDefaultBranchNameResponse + # This comment is left unintentionally blank. rpc :FindAllBranchNames, ::Gitaly::FindAllBranchNamesRequest, stream(::Gitaly::FindAllBranchNamesResponse) + # This comment is left unintentionally blank. rpc :FindAllTagNames, ::Gitaly::FindAllTagNamesRequest, stream(::Gitaly::FindAllTagNamesResponse) # Return a stream so we can divide the response in chunks of branches rpc :FindLocalBranches, ::Gitaly::FindLocalBranchesRequest, stream(::Gitaly::FindLocalBranchesResponse) + # This comment is left unintentionally blank. rpc :FindAllBranches, ::Gitaly::FindAllBranchesRequest, stream(::Gitaly::FindAllBranchesResponse) # Returns a stream of tags repository has. rpc :FindAllTags, ::Gitaly::FindAllTagsRequest, stream(::Gitaly::FindAllTagsResponse) + # FindTag looks up a tag by its name and returns it to the caller if it exists. This RPC supports + # both lightweight and annotated tags. Note: this RPC returns an `Internal` error if the tag was + # not found. rpc :FindTag, ::Gitaly::FindTagRequest, ::Gitaly::FindTagResponse + # This comment is left unintentionally blank. rpc :FindAllRemoteBranches, ::Gitaly::FindAllRemoteBranchesRequest, stream(::Gitaly::FindAllRemoteBranchesResponse) + # This comment is left unintentionally blank. rpc :RefExists, ::Gitaly::RefExistsRequest, ::Gitaly::RefExistsResponse # FindBranch finds a branch by its unqualified name (like "master") and # returns the commit it currently points to. rpc :FindBranch, ::Gitaly::FindBranchRequest, ::Gitaly::FindBranchResponse + # This comment is left unintentionally blank. rpc :DeleteRefs, ::Gitaly::DeleteRefsRequest, ::Gitaly::DeleteRefsResponse + # This comment is left unintentionally blank. rpc :ListBranchNamesContainingCommit, ::Gitaly::ListBranchNamesContainingCommitRequest, stream(::Gitaly::ListBranchNamesContainingCommitResponse) + # This comment is left unintentionally blank. rpc :ListTagNamesContainingCommit, ::Gitaly::ListTagNamesContainingCommitRequest, stream(::Gitaly::ListTagNamesContainingCommitResponse) # GetTagSignatures returns signatures for annotated tags resolved from a set of revisions. Revisions # which don't resolve to an annotated tag are silently discarded. Revisions which cannot be resolved # result in an error. Tags which are annotated but not signed will return a TagSignature response # which has no signature, but its unsigned contents will still be returned. rpc :GetTagSignatures, ::Gitaly::GetTagSignaturesRequest, stream(::Gitaly::GetTagSignaturesResponse) + # This comment is left unintentionally blank. rpc :GetTagMessages, ::Gitaly::GetTagMessagesRequest, stream(::Gitaly::GetTagMessagesResponse) # PackRefs is deprecated in favor of OptimizeRepository. rpc :PackRefs, ::Gitaly::PackRefsRequest, ::Gitaly::PackRefsResponse diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/remote_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/remote_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/remote_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/remote_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/remote_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/remote_services_pb.rb similarity index 89% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/remote_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/remote_services_pb.rb index 856f21ceeb..08f7ed80d1 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/remote_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/remote_services_pb.rb @@ -6,6 +6,8 @@ require 'remote_pb' module Gitaly module RemoteService + # RemoteService is a service providing RPCs to interact with a remote + # repository that is hosted on another Git server. class Service include ::GRPC::GenericService @@ -20,6 +22,7 @@ module Gitaly # deleted from the mirror. UpdateRemoteMirror updates all tags. Branches are updated if they match # the patterns specified in the requests. rpc :UpdateRemoteMirror, stream(::Gitaly::UpdateRemoteMirrorRequest), ::Gitaly::UpdateRemoteMirrorResponse + # This comment is left unintentionally blank. rpc :FindRemoteRepository, ::Gitaly::FindRemoteRepositoryRequest, ::Gitaly::FindRemoteRepositoryResponse # FindRemoteRootRef tries to find the root reference of a remote # repository. The root reference is the default branch as pointed to by diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_pb.rb similarity index 97% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_pb.rb index 4082efbd9d..81df3add04 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_pb.rb @@ -1,12 +1,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# source: repository-service.proto +# source: repository.proto require 'lint_pb' require 'shared_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("repository-service.proto", :syntax => :proto3) do + add_file("repository.proto", :syntax => :proto3) do add_message "gitaly.RepositoryExistsRequest" do optional :repository, :message, 1, "gitaly.Repository" end @@ -202,6 +202,10 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.FindLicenseResponse" do optional :license_short_name, :string, 1 + optional :license_name, :string, 2 + optional :license_url, :string, 3 + optional :license_path, :string, 4 + optional :license_nickname, :string, 5 end add_message "gitaly.GetInfoAttributesRequest" do optional :repository, :message, 1, "gitaly.Repository" @@ -321,6 +325,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.SetFullPathResponse" do end + add_message "gitaly.FullPathRequest" do + optional :repository, :message, 1, "gitaly.Repository" + end + add_message "gitaly.FullPathResponse" do + optional :path, :string, 1 + end end end @@ -412,4 +422,6 @@ module Gitaly PruneUnreachableObjectsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PruneUnreachableObjectsResponse").msgclass SetFullPathRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.SetFullPathRequest").msgclass SetFullPathResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.SetFullPathResponse").msgclass + FullPathRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FullPathRequest").msgclass + FullPathResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.FullPathResponse").msgclass end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_services_pb.rb similarity index 81% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_services_pb.rb index 5dd354365f..57cc9199a8 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/repository-service_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/repository_services_pb.rb @@ -1,11 +1,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: repository-service.proto for package 'gitaly' +# Source: repository.proto for package 'gitaly' require 'grpc' -require 'repository-service_pb' +require 'repository_pb' module Gitaly module RepositoryService + # RepositoryService is a service providing RPCs accessing repositories as a whole. class Service include ::GRPC::GenericService @@ -14,6 +15,7 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.RepositoryService' + # This comment is left unintentionally blank. rpc :RepositoryExists, ::Gitaly::RepositoryExistsRequest, ::Gitaly::RepositoryExistsResponse # RepackIncremental is deprecated in favor of OptimizeRepository. rpc :RepackIncremental, ::Gitaly::RepackIncrementalRequest, ::Gitaly::RepackIncrementalResponse @@ -25,21 +27,31 @@ module Gitaly rpc :GarbageCollect, ::Gitaly::GarbageCollectRequest, ::Gitaly::GarbageCollectResponse # WriteCommitGraph is deprecated in favor of OptimizeRepository. rpc :WriteCommitGraph, ::Gitaly::WriteCommitGraphRequest, ::Gitaly::WriteCommitGraphResponse + # This comment is left unintentionally blank. rpc :RepositorySize, ::Gitaly::RepositorySizeRequest, ::Gitaly::RepositorySizeResponse + # This comment is left unintentionally blank. rpc :ApplyGitattributes, ::Gitaly::ApplyGitattributesRequest, ::Gitaly::ApplyGitattributesResponse # FetchRemote fetches references from a remote repository into the local # repository. rpc :FetchRemote, ::Gitaly::FetchRemoteRequest, ::Gitaly::FetchRemoteResponse + # This comment is left unintentionally blank. rpc :CreateRepository, ::Gitaly::CreateRepositoryRequest, ::Gitaly::CreateRepositoryResponse + # This comment is left unintentionally blank. rpc :GetArchive, ::Gitaly::GetArchiveRequest, stream(::Gitaly::GetArchiveResponse) + # This comment is left unintentionally blank. rpc :HasLocalBranches, ::Gitaly::HasLocalBranchesRequest, ::Gitaly::HasLocalBranchesResponse # FetchSourceBranch fetches a branch from a second (potentially remote) # repository into the given repository. rpc :FetchSourceBranch, ::Gitaly::FetchSourceBranchRequest, ::Gitaly::FetchSourceBranchResponse + # This comment is left unintentionally blank. rpc :Fsck, ::Gitaly::FsckRequest, ::Gitaly::FsckResponse + # This comment is left unintentionally blank. rpc :WriteRef, ::Gitaly::WriteRefRequest, ::Gitaly::WriteRefResponse + # This comment is left unintentionally blank. rpc :FindMergeBase, ::Gitaly::FindMergeBaseRequest, ::Gitaly::FindMergeBaseResponse + # This comment is left unintentionally blank. rpc :CreateFork, ::Gitaly::CreateForkRequest, ::Gitaly::CreateForkResponse + # This comment is left unintentionally blank. rpc :CreateRepositoryFromURL, ::Gitaly::CreateRepositoryFromURLRequest, ::Gitaly::CreateRepositoryFromURLResponse # CreateBundle creates a bundle from all refs rpc :CreateBundle, ::Gitaly::CreateBundleRequest, stream(::Gitaly::CreateBundleResponse) @@ -50,28 +62,42 @@ module Gitaly # Refs will be mirrored to the target repository with the refspec # "+refs/*:refs/*" and refs that do not exist in the bundle will be removed. rpc :FetchBundle, stream(::Gitaly::FetchBundleRequest), ::Gitaly::FetchBundleResponse + # This comment is left unintentionally blank. rpc :CreateRepositoryFromBundle, stream(::Gitaly::CreateRepositoryFromBundleRequest), ::Gitaly::CreateRepositoryFromBundleResponse # GetConfig reads the target repository's gitconfig and streams its contents # back. Returns a NotFound error in case no gitconfig was found. rpc :GetConfig, ::Gitaly::GetConfigRequest, stream(::Gitaly::GetConfigResponse) + # This comment is left unintentionally blank. rpc :FindLicense, ::Gitaly::FindLicenseRequest, ::Gitaly::FindLicenseResponse + # This comment is left unintentionally blank. rpc :GetInfoAttributes, ::Gitaly::GetInfoAttributesRequest, stream(::Gitaly::GetInfoAttributesResponse) + # This comment is left unintentionally blank. rpc :CalculateChecksum, ::Gitaly::CalculateChecksumRequest, ::Gitaly::CalculateChecksumResponse # Cleanup is deprecated in favor of OptimizeRepository. rpc :Cleanup, ::Gitaly::CleanupRequest, ::Gitaly::CleanupResponse + # This comment is left unintentionally blank. rpc :GetSnapshot, ::Gitaly::GetSnapshotRequest, stream(::Gitaly::GetSnapshotResponse) + # This comment is left unintentionally blank. rpc :CreateRepositoryFromSnapshot, ::Gitaly::CreateRepositoryFromSnapshotRequest, ::Gitaly::CreateRepositoryFromSnapshotResponse + # This comment is left unintentionally blank. rpc :GetRawChanges, ::Gitaly::GetRawChangesRequest, stream(::Gitaly::GetRawChangesResponse) + # This comment is left unintentionally blank. rpc :SearchFilesByContent, ::Gitaly::SearchFilesByContentRequest, stream(::Gitaly::SearchFilesByContentResponse) + # This comment is left unintentionally blank. rpc :SearchFilesByName, ::Gitaly::SearchFilesByNameRequest, stream(::Gitaly::SearchFilesByNameResponse) + # This comment is left unintentionally blank. rpc :RestoreCustomHooks, stream(::Gitaly::RestoreCustomHooksRequest), ::Gitaly::RestoreCustomHooksResponse + # This comment is left unintentionally blank. rpc :BackupCustomHooks, ::Gitaly::BackupCustomHooksRequest, stream(::Gitaly::BackupCustomHooksResponse) + # This comment is left unintentionally blank. rpc :GetObjectDirectorySize, ::Gitaly::GetObjectDirectorySizeRequest, ::Gitaly::GetObjectDirectorySizeResponse # RemoveRepository will move the repository to `+gitaly/tmp/_removed` and # eventually remove it. This ensures that even on networked filesystems the # data is actually removed even if there's someone still handling the data. rpc :RemoveRepository, ::Gitaly::RemoveRepositoryRequest, ::Gitaly::RemoveRepositoryResponse + # This comment is left unintentionally blank. rpc :RenameRepository, ::Gitaly::RenameRepositoryRequest, ::Gitaly::RenameRepositoryResponse + # This comment is left unintentionally blank. rpc :ReplicateRepository, ::Gitaly::ReplicateRepositoryRequest, ::Gitaly::ReplicateRepositoryResponse # OptimizeRepository performs all maintenance tasks in a repository to keep # it in an efficient state. It cleans up stale data, repacks objects, @@ -97,6 +123,9 @@ module Gitaly # an admin inspects the repository's gitconfig such that he can easily see # what the repository name is. rpc :SetFullPath, ::Gitaly::SetFullPathRequest, ::Gitaly::SetFullPathResponse + # FullPath reads the "gitlab.fullpath" configuration from the repository's + # gitconfig. Returns an error in case the full path has not been configured. + rpc :FullPath, ::Gitaly::FullPathRequest, ::Gitaly::FullPathResponse end Stub = Service.rpc_stub_class diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_pb.rb similarity index 61% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_pb.rb index 8e41430d41..06f5eec967 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_pb.rb @@ -1,6 +1,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: server.proto +require 'google/protobuf/duration_pb' require 'lint_pb' require 'google/protobuf' @@ -33,11 +34,29 @@ Google::Protobuf::DescriptorPool.generated_pool.build do end add_message "gitaly.ClockSyncedRequest" do optional :ntp_host, :string, 1 - optional :drift_threshold_millis, :int64, 2 + optional :drift_threshold, :message, 3, "google.protobuf.Duration" end add_message "gitaly.ClockSyncedResponse" do optional :synced, :bool, 1 end + add_message "gitaly.ReadinessCheckRequest" do + optional :timeout, :message, 1, "google.protobuf.Duration" + end + add_message "gitaly.ReadinessCheckResponse" do + oneof :Result do + optional :ok_response, :message, 1, "gitaly.ReadinessCheckResponse.Ok" + optional :failure_response, :message, 2, "gitaly.ReadinessCheckResponse.Failure" + end + end + add_message "gitaly.ReadinessCheckResponse.Ok" do + end + add_message "gitaly.ReadinessCheckResponse.Failure" do + repeated :failed_checks, :message, 1, "gitaly.ReadinessCheckResponse.Failure.Response" + end + add_message "gitaly.ReadinessCheckResponse.Failure.Response" do + optional :name, :string, 1 + optional :error_message, :string, 2 + end end end @@ -50,4 +69,9 @@ module Gitaly DiskStatisticsResponse::StorageStatus = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.DiskStatisticsResponse.StorageStatus").msgclass ClockSyncedRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ClockSyncedRequest").msgclass ClockSyncedResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ClockSyncedResponse").msgclass + ReadinessCheckRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReadinessCheckRequest").msgclass + ReadinessCheckResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReadinessCheckResponse").msgclass + ReadinessCheckResponse::Ok = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReadinessCheckResponse.Ok").msgclass + ReadinessCheckResponse::Failure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReadinessCheckResponse.Failure").msgclass + ReadinessCheckResponse::Failure::Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ReadinessCheckResponse.Failure.Response").msgclass end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_services_pb.rb similarity index 68% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_services_pb.rb index 6c1711b2c0..2e7ba45f20 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/server_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/server_services_pb.rb @@ -6,6 +6,7 @@ require 'server_pb' module Gitaly module ServerService + # ServerService is a service that provides information about a Gitaly server. class Service include ::GRPC::GenericService @@ -14,11 +15,15 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.ServerService' + # This comment is left unintentionally blank. rpc :ServerInfo, ::Gitaly::ServerInfoRequest, ::Gitaly::ServerInfoResponse + # This comment is left unintentionally blank. rpc :DiskStatistics, ::Gitaly::DiskStatisticsRequest, ::Gitaly::DiskStatisticsResponse # ClockSynced checks if machine clock is synced # (the offset is less that the one passed in the request). rpc :ClockSynced, ::Gitaly::ClockSyncedRequest, ::Gitaly::ClockSyncedResponse + # ReadinessCheck runs the set of the checks to make sure service is in operational state. + rpc :ReadinessCheck, ::Gitaly::ReadinessCheckRequest, ::Gitaly::ReadinessCheckResponse end Stub = Service.rpc_stub_class diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/shared_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/shared_pb.rb similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/shared_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/shared_pb.rb index 80fb0bed81..4481fca605 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/shared_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/shared_pb.rb @@ -19,6 +19,11 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :key, :bytes, 1 optional :value, :bytes, 2 end + add_message "gitaly.CommitStatInfo" do + optional :additions, :int32, 1 + optional :deletions, :int32, 2 + optional :changed_files, :int32, 3 + end add_message "gitaly.GitCommit" do optional :id, :string, 1 optional :subject, :bytes, 2 @@ -30,6 +35,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :signature_type, :enum, 8, "gitaly.SignatureType" optional :tree_id, :string, 9 repeated :trailers, :message, 10, "gitaly.CommitTrailer" + optional :short_stats, :message, 11, "gitaly.CommitStatInfo" end add_message "gitaly.CommitAuthor" do optional :name, :bytes, 1 @@ -96,6 +102,7 @@ end module Gitaly Repository = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.Repository").msgclass CommitTrailer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.CommitTrailer").msgclass + CommitStatInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.CommitStatInfo").msgclass GitCommit = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.GitCommit").msgclass CommitAuthor = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.CommitAuthor").msgclass ExitStatus = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.ExitStatus").msgclass diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/smarthttp_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/smarthttp_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/smarthttp_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/smarthttp_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/smarthttp_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/smarthttp_services_pb.rb similarity index 92% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/smarthttp_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/smarthttp_services_pb.rb index 256293a228..688d4e00fc 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/smarthttp_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/smarthttp_services_pb.rb @@ -6,6 +6,8 @@ require 'smarthttp_pb' module Gitaly module SmartHTTPService + # SmartHTTPService is a service that provides RPCs required for HTTP-based Git + # clones via the smart HTTP protocol. class Service include ::GRPC::GenericService diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ssh_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ssh_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ssh_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ssh_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ssh_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ssh_services_pb.rb similarity index 93% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ssh_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ssh_services_pb.rb index a50b0fa5a0..d630bcb810 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/ssh_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/ssh_services_pb.rb @@ -6,6 +6,7 @@ require 'ssh_pb' module Gitaly module SSHService + # SSHService is a service that provides RPCs required for SSH-based Git clones. class Service include ::GRPC::GenericService diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/transaction_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/transaction_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/transaction_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/transaction_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/transaction_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/transaction_services_pb.rb new file mode 100644 index 0000000000..639d465bc9 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/transaction_services_pb.rb @@ -0,0 +1,49 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: transaction.proto for package 'gitaly' + +require 'grpc' +require 'transaction_pb' + +module Gitaly + module RefTransaction + # RefTransaction is a service which provides RPCs to interact with reference + # transactions. Reference transactions are used in the context of Gitaly + # Cluster to ensure that all nodes part of a single transaction perform the + # same change: given a set of changes, the changes are hashed and the hash is + # then voted on. + class Service + + include ::GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'gitaly.RefTransaction' + + # VoteTransaction casts a vote on a transaction to establish whether the + # node is doing the same change as all the other nodes part of the + # transaction. This RPC blocks until quorum has been reached, which may be + # _before_ all nodes have cast a vote. + # + # This RPC may return one of the following error codes: + # + # - `NotFound` in case the transaction could not be found. + # - `Canceled` in case the transaction has been canceled before quorum was + # reached. + rpc :VoteTransaction, ::Gitaly::VoteTransactionRequest, ::Gitaly::VoteTransactionResponse + # StopTransaction gracefully stops a transaction. This RPC can be used if + # only a subset of nodes executes specific code which may cause the + # transaction to fail. One such example is Git hooks, which only execute on + # the primary Gitaly noded. Other nodes which vote on this transaction will + # get a response with the `STOP` state being set. + # + # This RPC may return one of the following error codes: + # + # - `NotFound` in case the transaction could not be found. + # - `Canceled` in case the transaction has been canceled before quorum was + # reached. + rpc :StopTransaction, ::Gitaly::StopTransactionRequest, ::Gitaly::StopTransactionResponse + end + + Stub = Service.rpc_stub_class + end +end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/version.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/version.rb similarity index 86% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/version.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/version.rb index 24117953ae..1298fa3697 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/version.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/version.rb @@ -2,5 +2,5 @@ # (https://gitlab.com/gitlab-org/release-tools/), and should not be # modified. module Gitaly - VERSION = '15.0.0-rc1' + VERSION = '15.4.2' end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/wiki_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/wiki_pb.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/wiki_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/wiki_pb.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/wiki_services_pb.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/wiki_services_pb.rb similarity index 70% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/wiki_services_pb.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/wiki_services_pb.rb index 6e18e6893b..16ccdd1cb0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/proto/gitaly/wiki_services_pb.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/proto/gitaly/wiki_services_pb.rb @@ -6,6 +6,9 @@ require 'wiki_pb' module Gitaly module WikiService + # WikiService is a service that provides Wiki-related functionality. This + # service is deprecated and should not be used anymore. Instead, all + # functionality to implement Wikis should use Git-based RPCS. class Service include ::GRPC::GenericService @@ -14,11 +17,15 @@ module Gitaly self.unmarshal_class_method = :decode self.service_name = 'gitaly.WikiService' + # This comment is left unintentionally blank. rpc :WikiWritePage, stream(::Gitaly::WikiWritePageRequest), ::Gitaly::WikiWritePageResponse + # This comment is left unintentionally blank. rpc :WikiUpdatePage, stream(::Gitaly::WikiUpdatePageRequest), ::Gitaly::WikiUpdatePageResponse # WikiFindPage returns a stream because the page's raw_data field may be arbitrarily large. rpc :WikiFindPage, ::Gitaly::WikiFindPageRequest, stream(::Gitaly::WikiFindPageResponse) + # This comment is left unintentionally blank. rpc :WikiGetAllPages, ::Gitaly::WikiGetAllPagesRequest, stream(::Gitaly::WikiGetAllPagesResponse) + # This comment is left unintentionally blank. rpc :WikiListPages, ::Gitaly::WikiListPagesRequest, stream(::Gitaly::WikiListPagesResponse) end diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/gitaly/commit.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/gitaly/commit.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/gitaly/commit.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/gitaly/commit.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/gitaly/commit_author.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/gitaly/commit_author.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/gitaly/commit_author.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/gitaly/commit_author.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/sequences.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/sequences.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/factories/sequences.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/factories/sequences.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/gitaly/repository_service_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/gitaly/repository_service_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/gitaly/repository_service_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/gitaly/repository_service_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/exception_sanitizer_interceptor_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/exception_sanitizer_interceptor_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/exception_sanitizer_interceptor_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/exception_sanitizer_interceptor_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/feature_flags_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/feature_flags_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/feature_flags_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/feature_flags_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/rugged_interceptor_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/rugged_interceptor_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/rugged_interceptor_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/rugged_interceptor_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/sentry/url_sanitizer_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/sentry/url_sanitizer_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/sentry/url_sanitizer_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/sentry/url_sanitizer_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/sentry_interceptor_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/sentry_interceptor_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/sentry_interceptor_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/sentry_interceptor_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/utils_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/utils_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitaly_server/utils_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitaly_server/utils_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/branch_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/branch_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/branch_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/branch_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/commit_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/commit_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/commit_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/commit_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/hook_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/hook_spec.rb similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/hook_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/hook_spec.rb index 4839407e0a..1d54547282 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/hook_spec.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/hook_spec.rb @@ -44,7 +44,7 @@ describe Gitlab::Git::Hook do git_path: Gitlab.config.git.bin_path, internal_socket: Gitlab.config.gitaly.internal_socket, internal_socket_token: nil, - receive_hooks_payload: { + user_details: { userid: 'user-123', username: 'janedoe', protocol: 'web' diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/popen_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/popen_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/popen_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/popen_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/push_options_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/push_options_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/push_options_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/push_options_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/repository_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/repository_spec.rb similarity index 66% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/repository_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/repository_spec.rb index b6e140cb17..573058b25d 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/repository_spec.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/repository_spec.rb @@ -149,118 +149,31 @@ describe Gitlab::Git::Repository do # rubocop:disable Metrics/BlockLength end describe '#with_repo_branch_commit' do - let(:start_repository) { Gitlab::Git::RemoteRepository.new(source_repository) } - let(:start_commit) { source_repository.commit } - - context 'when start_repository is empty' do - let(:source_repository) { gitlab_git_from_gitaly(new_empty_test_repo) } - - before do - expect(start_repository).not_to receive(:commit_id) - expect(repository).not_to receive(:fetch_sha) - end + context 'when repository is empty' do + let(:repository) { gitlab_git_from_gitaly(new_empty_test_repo) } it 'yields nil' do expect do |block| - repository.with_repo_branch_commit(start_repository, 'master', &block) + repository.with_repo_branch_commit('master', &block) end.to yield_with_args(nil) end end - context 'when start_repository is the same repository' do - let(:source_repository) { repository } - - before do - expect(start_repository).not_to receive(:commit_id) - expect(repository).not_to receive(:fetch_sha) - end + context 'when repository is not empty' do + let(:start_commit) { repository.commit } it 'yields the commit for the SHA' do expect do |block| - repository.with_repo_branch_commit(start_repository, start_commit.sha, &block) + repository.with_repo_branch_commit(start_commit.sha, &block) end.to yield_with_args(start_commit) end it 'yields the commit for the branch' do expect do |block| - repository.with_repo_branch_commit(start_repository, 'master', &block) + repository.with_repo_branch_commit('master', &block) end.to yield_with_args(start_commit) end end - - context 'when start_repository is different' do - let(:source_repository) { gitlab_git_from_gitaly(test_repo_read_only) } - - context 'when start commit already exists' do - let(:start_commit) { repository.commit } - - before do - expect(start_repository).to receive(:commit_id).and_return(start_commit.sha) - expect(repository).not_to receive(:fetch_sha) - end - - it 'yields the commit for the SHA' do - expect do |block| - repository.with_repo_branch_commit(start_repository, start_commit.sha, &block) - end.to yield_with_args(start_commit) - end - - it 'yields the commit for the branch' do - expect do |block| - repository.with_repo_branch_commit(start_repository, 'master', &block) - end.to yield_with_args(start_commit) - end - end - - context 'when start commit does not exist' do - before do - expect(start_repository).to receive(:commit_id).and_return(start_commit.sha) - expect(repository).to receive(:fetch_sha).with(start_repository, start_commit.sha) - end - - it 'yields the fetched commit for the SHA' do - expect do |block| - repository.with_repo_branch_commit(start_repository, start_commit.sha, &block) - end.to yield_with_args(nil) # since fetch_sha is mocked - end - - it 'yields the fetched commit for the branch' do - expect do |block| - repository.with_repo_branch_commit(start_repository, 'master', &block) - end.to yield_with_args(nil) # since fetch_sha is mocked - end - end - end - end - - describe '#fetch_sha' do - let(:source_repository) { Gitlab::Git::RemoteRepository.new(repository) } - let(:sha) { 'b971194ee2d047f24cb897b6fb0d7ae99c8dd0ca' } - let(:git_args) { %W[fetch --no-tags ssh://gitaly/internal.git #{sha}] } - - before do - expect(source_repository).to receive(:fetch_env) - .with(git_config_options: ['uploadpack.allowAnySHA1InWant=true']) - .and_return({}) - end - - it 'fetches the commit from the source repository' do - expect(repository).to receive(:run_git) - .with(git_args, env: {}, include_stderr: true) - .and_return(['success', 0]) - - expect(repository.fetch_sha(source_repository, sha)).to eq(sha) - end - - it 'raises an error if the commit does not exist in the source repository' do - expect(repository).to receive(:run_git) - .with(git_args, env: {}, include_stderr: true) - .and_return(['error', 1]) - - expect do - repository.fetch_sha(source_repository, sha) - end.to raise_error(Gitlab::Git::CommandError, 'error') - end end describe '#cleanup' do diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert2.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert2.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert2.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert2.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert3.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert3.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert3.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycert3.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycertdup.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycertdup.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/certs/gitalycertdup.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/certs/gitalycertdup.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/gitalycert.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/gitalycert.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/testdata/gitalycert.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/testdata/gitalycert.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/user_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/user_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/user_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/user_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/wiki_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/wiki_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/git/wiki_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/git/wiki_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/gollum_spec.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/gollum_spec.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/lib/gitlab/gollum_spec.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/lib/gitlab/gollum_spec.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/spec_helper.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/spec_helper.rb similarity index 76% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/spec_helper.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/spec_helper.rb index 52296007e0..dcd20550e0 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/spec_helper.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/spec_helper.rb @@ -13,6 +13,12 @@ GITLAB_SHELL_DIR = File.join(TMP_DIR, 'gitlab-shell').freeze # overwrite HOME env variable so user global .gitconfig doesn't influence tests ENV["HOME"] = File.join(File.dirname(__FILE__), "/support/helpers/testdata/home") +# Furthermore, overwrite the Rugged search path so that it doesn't pick up any +# gitconfig, either. +Rugged::Settings['search_path_system'] = '/dev/null' +Rugged::Settings['search_path_global'] = '/dev/null' +Rugged::Settings['search_path_xdg'] = '/dev/null' + require 'test_repo_helper' Dir[File.join(__dir__, 'support/helpers/*.rb')].each { |f| require f } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/generate-seed-repo-rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/generate-seed-repo-rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/generate-seed-repo-rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/generate-seed-repo-rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/certs/gitalycert.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/certs/gitalycert.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/certs/gitalycert.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/certs/gitalycert.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/certs/gitalykey.pem b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/certs/gitalykey.pem similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/certs/gitalykey.pem rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/certs/gitalykey.pem diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/integration_helper.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/integration_helper.rb similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/integration_helper.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/integration_helper.rb index 5d3a1ef7cb..c4462e7507 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/integration_helper.rb +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/integration_helper.rb @@ -48,18 +48,6 @@ module IntegrationClient def gitaly_repo(storage, relative_path) Gitaly::Repository.new(storage_name: storage, relative_path: relative_path) end - - def get_client(addr) - servers = Base64.strict_encode64({ - default: { - address: addr, - token: 'the-secret-token' - } - }.to_json) - - call = double(metadata: { 'gitaly-servers' => servers }) - Gitlab::Git::GitalyRemoteRepository.new(repository.gitaly_repository, call) - end end def start_gitaly diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/seed_repo.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/seed_repo.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/seed_repo.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/seed_repo.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/testdata/home/.gitconfig b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/testdata/home/.gitconfig similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/helpers/testdata/home/.gitconfig rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/helpers/testdata/home/.gitconfig diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/sentry.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/sentry.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/support/sentry.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/support/sentry.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/test_repo_helper.rb b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/test_repo_helper.rb similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/ruby/spec/test_repo_helper.rb rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/ruby/spec/test_repo_helper.rb diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/scripts/security-harness b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/scripts/security-harness similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/scripts/security-harness rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/scripts/security-harness diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/streamio/stream.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/streamio/stream.go similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/streamio/stream.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/streamio/stream.go diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/streamio/stream_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/streamio/stream_test.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/streamio/stream_test.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/streamio/stream_test.go index 8f7c841fdf..296039142c 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/streamio/stream_test.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/streamio/stream_test.go @@ -1,3 +1,5 @@ +//go:build !gitaly_test_sha256 + package streamio import ( diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/module-updater/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/module-updater/main.go similarity index 90% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/module-updater/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/module-updater/main.go index c58aad5354..d8cfbda1ee 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/module-updater/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/module-updater/main.go @@ -18,18 +18,18 @@ import ( ) var skipDirs = map[string]bool{ - ".git": true, - ".gitlab": true, - "_build": true, - "_support": true, - "changelogs": true, - "danger": true, - "doc": true, - "proto/go/gitalypb": true, - "proto/go/internal/linter/testdata": true, - "ruby": true, - "scripts": true, - "unreleased": true, + ".git": true, + ".gitlab": true, + "_build": true, + "_support": true, + "changelogs": true, + "danger": true, + "doc": true, + "proto/go/gitalypb": true, + "ruby": true, + "scripts": true, + "tools/protoc-gen-gitaly-lint/testdata": true, + "unreleased": true, } func main() { @@ -119,7 +119,7 @@ func getModule(modDir string) (string, error) { return "", fmt.Errorf("command %q: %w", strings.Join(cmd.Args, " "), err) } - var modInfo = struct{ Module struct{ Path string } }{} + modInfo := struct{ Module struct{ Path string } }{} if err := json.Unmarshal(data, &modInfo); err != nil { return "", err } @@ -259,8 +259,8 @@ func verifyModulePath(moduleRootPath string) error { // rewriteProto re-write proto files by changing the go_package option declaration: // 1. option go_package = "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"; -// 2. option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; -// 4. option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; +// 2. option go_package = "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"; +// 4. option go_package = "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"; func rewriteProto(moduleAbsRootPath, prev, next string) error { protoDirPath := filepath.Join(moduleAbsRootPath, "proto") if err := filepath.Walk(protoDirPath, func(path string, info fs.FileInfo, err error) error { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/noticegen/notice.template b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/noticegen/notice.template similarity index 100% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/noticegen/notice.template rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/noticegen/notice.template diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/noticegen/noticegen.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/noticegen/noticegen.go similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/noticegen/noticegen.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/noticegen/noticegen.go index 0d54f221a5..9d2a9f21bd 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/_support/noticegen/noticegen.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/noticegen/noticegen.go @@ -39,7 +39,7 @@ func main() { if err != nil { log.Fatal(err) } - var modInfo = struct { + modInfo := struct { Module struct { Path string } @@ -62,7 +62,7 @@ func main() { } if p == modInfo.Module.Path { - return nil + return filepath.SkipDir } t, err := os.ReadFile(path) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint.go similarity index 95% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint.go index 48eb0f252a..8bb4c9e709 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/lint.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint.go @@ -1,11 +1,11 @@ -package linter +package main import ( "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v14/internal/protoutil" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/protoutil" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/pluginpb" diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint_test.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint_test.go new file mode 100644 index 0000000000..8ab86c3f53 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/lint_test.go @@ -0,0 +1,81 @@ +//go:build !gitaly_test_sha256 + +package main + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + _ "gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata" + "google.golang.org/protobuf/reflect/protodesc" + protoreg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/pluginpb" +) + +func TestLintFile(t *testing.T) { + for _, tt := range []struct { + protoPath string + errs []error + }{ + { + protoPath: "protoc-gen-gitaly-lint/testdata/valid.proto", + errs: nil, + }, + { + protoPath: "protoc-gen-gitaly-lint/testdata/invalid.proto", + errs: []error{ + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InterceptedWithOperationType", "InvalidMethod", errors.New("operation type defined on an intercepted method")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod0", errors.New("missing op_type extension")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod1", errors.New("op set to UNKNOWN")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod2", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod4", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod5", errors.New("wrong type of field RequestWithWrongTypeRepository.header.repository, expected .gitaly.Repository, got .test.InvalidMethodResponse")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod6", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod7", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod8", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod9", errors.New("unexpected count of target_repository fields 1, expected 0, found target_repository label at: [InvalidMethodRequestWithRepo.destination]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod10", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithStorageAndRepo.storage_name]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod11", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithNestedStorageAndRepo.inner_message.storage_name]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod13", errors.New("unexpected count of storage field 0, expected 1, found storage label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod14", errors.New("unexpected count of storage field 2, expected 1, found storage label at: [RequestWithMultipleNestedStorage.inner_message.storage_name RequestWithMultipleNestedStorage.storage_name]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "InvalidMethod15", errors.New("operation type defined on an intercepted method")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithMissingRepository", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithUnflaggedRepository", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithWrongNestedRepositoryType", errors.New("wrong type of field RequestWithWrongTypeRepository.header.repository, expected .gitaly.Repository, got .test.InvalidMethodResponse")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithInvalidTargetType", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithInvalidNestedRequest", errors.New("unexpected count of target_repository fields 0, expected 1, found target_repository label at: []")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithStorageAndRepository", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithStorageAndRepo.storage_name]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithNestedStorageAndRepository", errors.New("unexpected count of storage field 1, expected 0, found storage label at: [RequestWithNestedStorageAndRepo.inner_message.storage_name]")), + formatError("protoc-gen-gitaly-lint/testdata/invalid.proto", "InvalidService", "MaintenanceWithStorageScope", errors.New("unknown operation scope level 2")), + }, + }, + } { + t.Run(tt.protoPath, func(t *testing.T) { + fd, err := protoreg.GlobalFiles.FindFileByPath(tt.protoPath) + require.NoError(t, err) + + fdToCheck := protodesc.ToFileDescriptorProto(fd) + req := &pluginpb.CodeGeneratorRequest{ + ProtoFile: []*descriptorpb.FileDescriptorProto{fdToCheck}, + } + + for _, protoPath := range []string{ + // as we have no input stream we can use to create CodeGeneratorRequest + // we must create it by hands with all required dependencies loaded + "google/protobuf/descriptor.proto", + "google/protobuf/timestamp.proto", + "lint.proto", + "shared.proto", + } { + fd, err := protoreg.GlobalFiles.FindFileByPath(protoPath) + require.NoError(t, err) + req.ProtoFile = append(req.ProtoFile, protodesc.ToFileDescriptorProto(fd)) + } + + errs := LintFile(fdToCheck, req) + require.Equal(t, tt.errs, errs) + }) + } +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/main.go new file mode 100644 index 0000000000..be7de808bc --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/main.go @@ -0,0 +1,107 @@ +// Command protoc-gen-gitaly-lint is designed to be used as a protobuf compiler +// plugin to verify Gitaly processes are being followed when writing RPC's. +// +// Usage +// +// The protoc-gen-gitaly linter can be chained into any protoc workflow that +// requires verification that Gitaly RPC guidelines are followed. Typically +// this can be done by adding the following argument to an existing protoc +// command: +// +// --gitaly_lint_out=. +// +// For example, you may add the linter as an argument to the command responsible +// for generating Go code: +// +// protoc --go_out=. --gitaly_lint_out=. *.proto +// +// Or, you can run the Gitaly linter by itself. To try out, run the following +// command while in the project root: +// +// protoc --gitaly_lint_out=. ./go/internal/cmd/protoc-gen-gitaly-lint/testdata/incomplete.proto +// +// You should see some errors printed to screen for improperly written +// RPC's in the incomplete.proto file. +// +// Prerequisites +// +// The protobuf compiler (protoc) can be obtained from the GitHub page: +// https://github.com/protocolbuffers/protobuf/releases +// +// Background +// +// The protobuf compiler accepts plugins to analyze protobuf files and generate +// language specific code. +// +// These plugins require the following executable naming convention: +// +// protoc-gen-$NAME +// +// Where $NAME is the plugin name of the compiler desired. The protobuf compiler +// will search the PATH until an executable with that name is found for a +// desired plugin. For example, the following protoc command: +// +// protoc --gitaly_lint_out=. *.proto +// +// The above will search the PATH for an executable named protoc-gen-gitaly-lint +// +// The plugin accepts a protobuf message in STDIN that describes the parsed +// protobuf files. A response is sent back on STDOUT that contains any errors. +package main + +import ( + "fmt" + "io" + "log" + "os" + "strings" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/pluginpb" +) + +func main() { + data, err := io.ReadAll(os.Stdin) + if err != nil { + log.Fatalf("reading input: %s", err) + } + + req := &pluginpb.CodeGeneratorRequest{} + + if err := proto.Unmarshal(data, req); err != nil { + log.Fatalf("parsing input proto: %s", err) + } + + if err := lintProtos(req); err != nil { + log.Fatal(err) + } +} + +func lintProtos(req *pluginpb.CodeGeneratorRequest) error { + var errMsgs []string + for _, pf := range req.GetProtoFile() { + errs := LintFile(pf, req) + for _, err := range errs { + errMsgs = append(errMsgs, err.Error()) + } + } + + resp := &pluginpb.CodeGeneratorResponse{} + + if len(errMsgs) > 0 { + errMsg := strings.Join(errMsgs, "\n\t") + resp.Error = &errMsg + } + + // Send back the results. + data, err := proto.Marshal(resp) + if err != nil { + return fmt.Errorf("failed to marshal output proto: %s", err) + } + + _, err = os.Stdout.Write(data) + if err != nil { + return fmt.Errorf("failed to write output proto: %s", err) + } + return nil +} diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/method.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/method.go similarity index 98% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/method.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/method.go index b336f7f4fb..39329b5219 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/method.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/method.go @@ -1,12 +1,12 @@ -package linter +package main import ( "errors" "fmt" "strings" - "gitlab.com/gitlab-org/gitaly/v14/internal/protoutil" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/internal/protoutil" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/pluginpb" ) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.pb.go similarity index 59% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.pb.go index 1252ad32f6..409245f4e4 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.pb.go @@ -1,13 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: go/internal/linter/testdata/invalid.proto +// protoc-gen-go v1.28.0 +// protoc v3.21.1 +// source: protoc-gen-gitaly-lint/testdata/invalid.proto package testdata import ( - gitalypb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalypb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -30,7 +30,7 @@ type InvalidMethodRequest struct { func (x *InvalidMethodRequest) Reset() { *x = InvalidMethodRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[0] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -43,7 +43,7 @@ func (x *InvalidMethodRequest) String() string { func (*InvalidMethodRequest) ProtoMessage() {} func (x *InvalidMethodRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[0] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -56,7 +56,7 @@ func (x *InvalidMethodRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidMethodRequest.ProtoReflect.Descriptor instead. func (*InvalidMethodRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{0} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{0} } type InvalidMethodRequestWithRepo struct { @@ -70,7 +70,7 @@ type InvalidMethodRequestWithRepo struct { func (x *InvalidMethodRequestWithRepo) Reset() { *x = InvalidMethodRequestWithRepo{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[1] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -83,7 +83,7 @@ func (x *InvalidMethodRequestWithRepo) String() string { func (*InvalidMethodRequestWithRepo) ProtoMessage() {} func (x *InvalidMethodRequestWithRepo) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[1] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -96,7 +96,7 @@ func (x *InvalidMethodRequestWithRepo) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidMethodRequestWithRepo.ProtoReflect.Descriptor instead. func (*InvalidMethodRequestWithRepo) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{1} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{1} } func (x *InvalidMethodRequestWithRepo) GetDestination() *gitalypb.Repository { @@ -117,7 +117,7 @@ type InvalidTargetType struct { func (x *InvalidTargetType) Reset() { *x = InvalidTargetType{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[2] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -130,7 +130,7 @@ func (x *InvalidTargetType) String() string { func (*InvalidTargetType) ProtoMessage() {} func (x *InvalidTargetType) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[2] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -143,7 +143,7 @@ func (x *InvalidTargetType) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidTargetType.ProtoReflect.Descriptor instead. func (*InvalidTargetType) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{2} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{2} } func (x *InvalidTargetType) GetWrongType() int32 { @@ -162,7 +162,7 @@ type InvalidMethodResponse struct { func (x *InvalidMethodResponse) Reset() { *x = InvalidMethodResponse{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[3] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -175,7 +175,7 @@ func (x *InvalidMethodResponse) String() string { func (*InvalidMethodResponse) ProtoMessage() {} func (x *InvalidMethodResponse) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[3] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -188,7 +188,7 @@ func (x *InvalidMethodResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidMethodResponse.ProtoReflect.Descriptor instead. func (*InvalidMethodResponse) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{3} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{3} } type InvalidNestedRequest struct { @@ -202,7 +202,7 @@ type InvalidNestedRequest struct { func (x *InvalidNestedRequest) Reset() { *x = InvalidNestedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[4] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -215,7 +215,7 @@ func (x *InvalidNestedRequest) String() string { func (*InvalidNestedRequest) ProtoMessage() {} func (x *InvalidNestedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[4] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -228,7 +228,7 @@ func (x *InvalidNestedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InvalidNestedRequest.ProtoReflect.Descriptor instead. func (*InvalidNestedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{4} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{4} } func (x *InvalidNestedRequest) GetInnerMessage() *InvalidTargetType { @@ -250,7 +250,7 @@ type RequestWithStorage struct { func (x *RequestWithStorage) Reset() { *x = RequestWithStorage{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[5] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -263,7 +263,7 @@ func (x *RequestWithStorage) String() string { func (*RequestWithStorage) ProtoMessage() {} func (x *RequestWithStorage) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[5] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -276,7 +276,7 @@ func (x *RequestWithStorage) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithStorage.ProtoReflect.Descriptor instead. func (*RequestWithStorage) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{5} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{5} } func (x *RequestWithStorage) GetStorageName() string { @@ -305,7 +305,7 @@ type RequestWithStorageAndRepo struct { func (x *RequestWithStorageAndRepo) Reset() { *x = RequestWithStorageAndRepo{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[6] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -318,7 +318,7 @@ func (x *RequestWithStorageAndRepo) String() string { func (*RequestWithStorageAndRepo) ProtoMessage() {} func (x *RequestWithStorageAndRepo) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[6] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -331,7 +331,7 @@ func (x *RequestWithStorageAndRepo) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithStorageAndRepo.ProtoReflect.Descriptor instead. func (*RequestWithStorageAndRepo) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{6} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{6} } func (x *RequestWithStorageAndRepo) GetStorageName() string { @@ -359,7 +359,7 @@ type RequestWithNestedStorageAndRepo struct { func (x *RequestWithNestedStorageAndRepo) Reset() { *x = RequestWithNestedStorageAndRepo{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[7] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -372,7 +372,7 @@ func (x *RequestWithNestedStorageAndRepo) String() string { func (*RequestWithNestedStorageAndRepo) ProtoMessage() {} func (x *RequestWithNestedStorageAndRepo) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[7] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -385,7 +385,7 @@ func (x *RequestWithNestedStorageAndRepo) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithNestedStorageAndRepo.ProtoReflect.Descriptor instead. func (*RequestWithNestedStorageAndRepo) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{7} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{7} } func (x *RequestWithNestedStorageAndRepo) GetInnerMessage() *RequestWithStorageAndRepo { @@ -407,7 +407,7 @@ type RequestWithMultipleNestedStorage struct { func (x *RequestWithMultipleNestedStorage) Reset() { *x = RequestWithMultipleNestedStorage{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[8] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -420,7 +420,7 @@ func (x *RequestWithMultipleNestedStorage) String() string { func (*RequestWithMultipleNestedStorage) ProtoMessage() {} func (x *RequestWithMultipleNestedStorage) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[8] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -433,7 +433,7 @@ func (x *RequestWithMultipleNestedStorage) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithMultipleNestedStorage.ProtoReflect.Descriptor instead. func (*RequestWithMultipleNestedStorage) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{8} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{8} } func (x *RequestWithMultipleNestedStorage) GetInnerMessage() *RequestWithStorage { @@ -461,7 +461,7 @@ type RequestWithInnerNestedStorage struct { func (x *RequestWithInnerNestedStorage) Reset() { *x = RequestWithInnerNestedStorage{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[9] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -474,7 +474,7 @@ func (x *RequestWithInnerNestedStorage) String() string { func (*RequestWithInnerNestedStorage) ProtoMessage() {} func (x *RequestWithInnerNestedStorage) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[9] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -487,7 +487,7 @@ func (x *RequestWithInnerNestedStorage) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithInnerNestedStorage.ProtoReflect.Descriptor instead. func (*RequestWithInnerNestedStorage) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{9} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{9} } func (x *RequestWithInnerNestedStorage) GetHeader() *RequestWithInnerNestedStorage_Header { @@ -508,7 +508,7 @@ type RequestWithWrongTypeRepository struct { func (x *RequestWithWrongTypeRepository) Reset() { *x = RequestWithWrongTypeRepository{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[10] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -521,7 +521,7 @@ func (x *RequestWithWrongTypeRepository) String() string { func (*RequestWithWrongTypeRepository) ProtoMessage() {} func (x *RequestWithWrongTypeRepository) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[10] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -534,7 +534,7 @@ func (x *RequestWithWrongTypeRepository) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithWrongTypeRepository.ProtoReflect.Descriptor instead. func (*RequestWithWrongTypeRepository) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{10} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{10} } func (x *RequestWithWrongTypeRepository) GetHeader() *RequestWithWrongTypeRepository_Header { @@ -555,7 +555,7 @@ type RequestWithNestedRepoNotFlagged struct { func (x *RequestWithNestedRepoNotFlagged) Reset() { *x = RequestWithNestedRepoNotFlagged{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[11] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -568,7 +568,7 @@ func (x *RequestWithNestedRepoNotFlagged) String() string { func (*RequestWithNestedRepoNotFlagged) ProtoMessage() {} func (x *RequestWithNestedRepoNotFlagged) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[11] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -581,7 +581,7 @@ func (x *RequestWithNestedRepoNotFlagged) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestWithNestedRepoNotFlagged.ProtoReflect.Descriptor instead. func (*RequestWithNestedRepoNotFlagged) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{11} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{11} } func (x *RequestWithNestedRepoNotFlagged) GetHeader() *RequestWithNestedRepoNotFlagged_Header { @@ -602,7 +602,7 @@ type RequestWithInnerNestedStorage_Header struct { func (x *RequestWithInnerNestedStorage_Header) Reset() { *x = RequestWithInnerNestedStorage_Header{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[12] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -615,7 +615,7 @@ func (x *RequestWithInnerNestedStorage_Header) String() string { func (*RequestWithInnerNestedStorage_Header) ProtoMessage() {} func (x *RequestWithInnerNestedStorage_Header) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[12] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -628,7 +628,7 @@ func (x *RequestWithInnerNestedStorage_Header) ProtoReflect() protoreflect.Messa // Deprecated: Use RequestWithInnerNestedStorage_Header.ProtoReflect.Descriptor instead. func (*RequestWithInnerNestedStorage_Header) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{9, 0} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{9, 0} } func (x *RequestWithInnerNestedStorage_Header) GetStorageName() string { @@ -649,7 +649,7 @@ type RequestWithWrongTypeRepository_Header struct { func (x *RequestWithWrongTypeRepository_Header) Reset() { *x = RequestWithWrongTypeRepository_Header{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[13] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -662,7 +662,7 @@ func (x *RequestWithWrongTypeRepository_Header) String() string { func (*RequestWithWrongTypeRepository_Header) ProtoMessage() {} func (x *RequestWithWrongTypeRepository_Header) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[13] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -675,7 +675,7 @@ func (x *RequestWithWrongTypeRepository_Header) ProtoReflect() protoreflect.Mess // Deprecated: Use RequestWithWrongTypeRepository_Header.ProtoReflect.Descriptor instead. func (*RequestWithWrongTypeRepository_Header) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{10, 0} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{10, 0} } func (x *RequestWithWrongTypeRepository_Header) GetRepository() *InvalidMethodResponse { @@ -696,7 +696,7 @@ type RequestWithNestedRepoNotFlagged_Header struct { func (x *RequestWithNestedRepoNotFlagged_Header) Reset() { *x = RequestWithNestedRepoNotFlagged_Header{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[14] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -709,7 +709,7 @@ func (x *RequestWithNestedRepoNotFlagged_Header) String() string { func (*RequestWithNestedRepoNotFlagged_Header) ProtoMessage() {} func (x *RequestWithNestedRepoNotFlagged_Header) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_invalid_proto_msgTypes[14] + mi := &file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -722,7 +722,7 @@ func (x *RequestWithNestedRepoNotFlagged_Header) ProtoReflect() protoreflect.Mes // Deprecated: Use RequestWithNestedRepoNotFlagged_Header.ProtoReflect.Descriptor instead. func (*RequestWithNestedRepoNotFlagged_Header) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_invalid_proto_rawDescGZIP(), []int{11, 0} + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP(), []int{11, 0} } func (x *RequestWithNestedRepoNotFlagged_Header) GetRepository() *gitalypb.Repository { @@ -732,256 +732,256 @@ func (x *RequestWithNestedRepoNotFlagged_Header) GetRepository() *gitalypb.Repos return nil } -var File_go_internal_linter_testdata_invalid_proto protoreflect.FileDescriptor +var File_protoc_gen_gitaly_lint_testdata_invalid_proto protoreflect.FileDescriptor -var file_go_internal_linter_testdata_invalid_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x67, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x69, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x74, 0x65, 0x73, - 0x74, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x16, 0x0a, 0x14, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x1c, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x52, - 0x65, 0x70, 0x6f, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, - 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x38, 0x0a, 0x11, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0a, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x09, - 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0d, 0x69, 0x6e, - 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x6e, 0x65, - 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x73, 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x27, - 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, +var file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2d, 0x6c, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, + 0x61, 0x2f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x04, 0x74, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x16, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x1c, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, + 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x80, 0x01, - 0x0a, 0x19, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x27, 0x0a, 0x0c, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, - 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x67, 0x0a, 0x1f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, - 0x65, 0x70, 0x6f, 0x12, 0x44, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x0c, 0x69, 0x6e, 0x6e, - 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x8a, 0x01, 0x0a, 0x20, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, - 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x3d, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x38, 0x0a, 0x11, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0a, 0x77, 0x72, 0x6f, 0x6e, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x04, 0x98, 0xc6, + 0x2c, 0x01, 0x52, 0x09, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x22, 0x17, 0x0a, + 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, - 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, - 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x1d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x42, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x65, 0x72, - 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x31, 0x0a, 0x06, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, - 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, - 0xb8, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, - 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x49, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, - 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x4b, 0x0a, - 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x04, 0x90, 0xc6, 0x2c, 0x01, 0x52, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xab, 0x01, 0x0a, 0x1f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, 0x65, 0x64, 0x12, 0x4a, - 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x73, 0x0a, 0x12, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, + 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, + 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x67, 0x0a, 0x1f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, + 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x44, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, - 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, - 0x61, 0x67, 0x67, 0x65, 0x64, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x04, 0x98, 0xc6, - 0x2c, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x3c, 0x0a, 0x06, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x32, 0x76, 0x0a, 0x1c, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x52, + 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x8a, 0x01, + 0x0a, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x75, 0x6c, + 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x1d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x42, 0x0a, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, + 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x1a, 0x31, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, + 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x1a, 0x4b, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x04, 0x90, 0xc6, + 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xab, + 0x01, 0x0a, 0x1f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, + 0x65, 0x64, 0x12, 0x4a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, + 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, 0x65, 0x64, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x3c, + 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x32, 0x76, 0x0a, 0x1c, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0d, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x1a, 0x04, + 0xf0, 0x97, 0x28, 0x01, 0x32, 0xc1, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x30, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, - 0x32, 0xc1, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x30, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x31, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x32, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x34, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5b, 0x0a, 0x0e, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x35, 0x12, 0x24, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, - 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5c, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x36, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, 0x65, 0x64, 0x1a, - 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x01, 0x12, 0x4e, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x37, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, - 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x01, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x38, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5b, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x39, 0x12, 0x22, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x00, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x32, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x12, 0x57, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x30, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x5d, 0x0a, - 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x31, - 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, - 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x51, 0x0a, 0x0f, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x33, 0x12, - 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, - 0x60, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x31, 0x34, 0x12, 0x26, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x12, 0x59, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x31, 0x35, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, - 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x08, 0x80, 0x98, 0x28, 0x01, 0xfa, 0x97, 0x28, 0x00, 0x12, 0x63, 0x0a, 0x20, - 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x34, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x03, 0x12, 0x70, 0x0a, 0x22, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, - 0x57, 0x69, 0x74, 0x68, 0x55, 0x6e, 0x66, 0x6c, 0x61, 0x67, 0x67, 0x65, 0x64, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, 0x65, 0x64, 0x1a, 0x1b, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x03, 0x12, 0x75, 0x0a, 0x28, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x4e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5b, 0x0a, + 0x0e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x35, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x60, 0x0a, 0x20, 0x4d, 0x61, - 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x66, 0x0a, 0x23, - 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, - 0x28, 0x02, 0x08, 0x03, 0x12, 0x6b, 0x0a, 0x23, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, - 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x74, 0x65, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5c, 0x0a, 0x0e, 0x49, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x36, 0x12, 0x25, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, + 0x67, 0x65, 0x64, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x4e, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x37, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x51, 0x0a, 0x0e, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x38, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x5b, 0x0a, 0x0e, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x39, 0x12, 0x22, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, + 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, + 0xfa, 0x97, 0x28, 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, 0x57, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x30, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x03, 0x12, 0x77, 0x0a, 0x29, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, - 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, - 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, - 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x68, 0x0a, 0x1b, 0x4d, 0x61, - 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x22, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x02, 0x12, 0x5d, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x31, 0x31, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, + 0x12, 0x51, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x31, 0x33, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1b, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x12, 0x60, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x31, 0x34, 0x12, 0x26, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x1b, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, 0x59, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x35, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0x80, 0x98, 0x28, 0x01, 0xfa, 0x97, 0x28, 0x00, + 0x12, 0x63, 0x0a, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, + 0x69, 0x74, 0x68, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x70, 0x0a, 0x22, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x55, 0x6e, 0x66, 0x6c, 0x61, 0x67, 0x67, 0x65, + 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x67, + 0x65, 0x64, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x75, 0x0a, 0x28, 0x4d, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x60, + 0x0a, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, + 0x68, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x1b, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, + 0x12, 0x66, 0x0a, 0x23, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, + 0x69, 0x74, 0x68, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x6b, 0x0a, 0x23, 0x4d, 0x61, 0x69, 0x6e, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, + 0x74, 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, + 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x77, 0x0a, 0x29, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x68, + 0x0a, 0x1b, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, + 0x68, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x22, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, - 0x08, 0x03, 0x10, 0x02, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, - 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, + 0x6f, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, + 0xfa, 0x97, 0x28, 0x04, 0x08, 0x03, 0x10, 0x02, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x6c, + 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, + 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2d, 0x6c, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_go_internal_linter_testdata_invalid_proto_rawDescOnce sync.Once - file_go_internal_linter_testdata_invalid_proto_rawDescData = file_go_internal_linter_testdata_invalid_proto_rawDesc + file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescOnce sync.Once + file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescData = file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDesc ) -func file_go_internal_linter_testdata_invalid_proto_rawDescGZIP() []byte { - file_go_internal_linter_testdata_invalid_proto_rawDescOnce.Do(func() { - file_go_internal_linter_testdata_invalid_proto_rawDescData = protoimpl.X.CompressGZIP(file_go_internal_linter_testdata_invalid_proto_rawDescData) +func file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescGZIP() []byte { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescOnce.Do(func() { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescData = protoimpl.X.CompressGZIP(file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescData) }) - return file_go_internal_linter_testdata_invalid_proto_rawDescData + return file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDescData } -var file_go_internal_linter_testdata_invalid_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_go_internal_linter_testdata_invalid_proto_goTypes = []interface{}{ +var file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_protoc_gen_gitaly_lint_testdata_invalid_proto_goTypes = []interface{}{ (*InvalidMethodRequest)(nil), // 0: test.InvalidMethodRequest (*InvalidMethodRequestWithRepo)(nil), // 1: test.InvalidMethodRequestWithRepo (*InvalidTargetType)(nil), // 2: test.InvalidTargetType @@ -999,7 +999,7 @@ var file_go_internal_linter_testdata_invalid_proto_goTypes = []interface{}{ (*RequestWithNestedRepoNotFlagged_Header)(nil), // 14: test.RequestWithNestedRepoNotFlagged.Header (*gitalypb.Repository)(nil), // 15: gitaly.Repository } -var file_go_internal_linter_testdata_invalid_proto_depIdxs = []int32{ +var file_protoc_gen_gitaly_lint_testdata_invalid_proto_depIdxs = []int32{ 15, // 0: test.InvalidMethodRequestWithRepo.destination:type_name -> gitaly.Repository 2, // 1: test.InvalidNestedRequest.inner_message:type_name -> test.InvalidTargetType 15, // 2: test.RequestWithStorage.destination:type_name -> gitaly.Repository @@ -1064,13 +1064,13 @@ var file_go_internal_linter_testdata_invalid_proto_depIdxs = []int32{ 0, // [0:11] is the sub-list for field type_name } -func init() { file_go_internal_linter_testdata_invalid_proto_init() } -func file_go_internal_linter_testdata_invalid_proto_init() { - if File_go_internal_linter_testdata_invalid_proto != nil { +func init() { file_protoc_gen_gitaly_lint_testdata_invalid_proto_init() } +func file_protoc_gen_gitaly_lint_testdata_invalid_proto_init() { + if File_protoc_gen_gitaly_lint_testdata_invalid_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_go_internal_linter_testdata_invalid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InvalidMethodRequest); i { case 0: return &v.state @@ -1082,7 +1082,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InvalidMethodRequestWithRepo); i { case 0: return &v.state @@ -1094,7 +1094,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InvalidTargetType); i { case 0: return &v.state @@ -1106,7 +1106,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InvalidMethodResponse); i { case 0: return &v.state @@ -1118,7 +1118,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InvalidNestedRequest); i { case 0: return &v.state @@ -1130,7 +1130,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithStorage); i { case 0: return &v.state @@ -1142,7 +1142,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithStorageAndRepo); i { case 0: return &v.state @@ -1154,7 +1154,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithNestedStorageAndRepo); i { case 0: return &v.state @@ -1166,7 +1166,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithMultipleNestedStorage); i { case 0: return &v.state @@ -1178,7 +1178,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithInnerNestedStorage); i { case 0: return &v.state @@ -1190,7 +1190,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithWrongTypeRepository); i { case 0: return &v.state @@ -1202,7 +1202,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithNestedRepoNotFlagged); i { case 0: return &v.state @@ -1214,7 +1214,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithInnerNestedStorage_Header); i { case 0: return &v.state @@ -1226,7 +1226,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithWrongTypeRepository_Header); i { case 0: return &v.state @@ -1238,7 +1238,7 @@ func file_go_internal_linter_testdata_invalid_proto_init() { return nil } } - file_go_internal_linter_testdata_invalid_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RequestWithNestedRepoNotFlagged_Header); i { case 0: return &v.state @@ -1255,18 +1255,18 @@ func file_go_internal_linter_testdata_invalid_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_go_internal_linter_testdata_invalid_proto_rawDesc, + RawDescriptor: file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDesc, NumEnums: 0, NumMessages: 15, NumExtensions: 0, NumServices: 2, }, - GoTypes: file_go_internal_linter_testdata_invalid_proto_goTypes, - DependencyIndexes: file_go_internal_linter_testdata_invalid_proto_depIdxs, - MessageInfos: file_go_internal_linter_testdata_invalid_proto_msgTypes, + GoTypes: file_protoc_gen_gitaly_lint_testdata_invalid_proto_goTypes, + DependencyIndexes: file_protoc_gen_gitaly_lint_testdata_invalid_proto_depIdxs, + MessageInfos: file_protoc_gen_gitaly_lint_testdata_invalid_proto_msgTypes, }.Build() - File_go_internal_linter_testdata_invalid_proto = out.File - file_go_internal_linter_testdata_invalid_proto_rawDesc = nil - file_go_internal_linter_testdata_invalid_proto_goTypes = nil - file_go_internal_linter_testdata_invalid_proto_depIdxs = nil + File_protoc_gen_gitaly_lint_testdata_invalid_proto = out.File + file_protoc_gen_gitaly_lint_testdata_invalid_proto_rawDesc = nil + file_protoc_gen_gitaly_lint_testdata_invalid_proto_goTypes = nil + file_protoc_gen_gitaly_lint_testdata_invalid_proto_depIdxs = nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.proto similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.proto index badafa4da9..562700d404 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid.proto @@ -2,12 +2,13 @@ syntax = "proto3"; package test; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata"; - import "lint.proto"; import "shared.proto"; -message InvalidMethodRequest {} +option go_package = "gitlab.com/gitlab-org/gitaly/tools/protoc-gen-gitaly-lint/testdata"; + +message InvalidMethodRequest { +} message InvalidMethodRequestWithRepo { gitaly.Repository destination = 1 [(gitaly.target_repository)=true]; @@ -17,7 +18,8 @@ message InvalidTargetType { int32 wrong_type = 1 [(gitaly.target_repository)=true]; } -message InvalidMethodResponse{} +message InvalidMethodResponse{ +} message InvalidNestedRequest{ InvalidTargetType inner_message = 1; @@ -159,8 +161,8 @@ service InvalidService { // Intercepted methods must not have operation type annotations. rpc InvalidMethod15(RequestWithStorageAndRepo) returns (InvalidMethodResponse) { - option (gitaly.intercepted_method) = true; - option (gitaly.op_type) = {}; + option (gitaly.intercepted_method) = true; + option (gitaly.op_type) = {}; }; rpc MaintenanceWithMissingRepository(InvalidMethodRequest) returns (InvalidMethodResponse) { diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid_grpc.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid_grpc.pb.go index 02211b2f99..d289b39a70 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/invalid_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/invalid_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: protoc-gen-gitaly-lint/testdata/invalid.proto package testdata @@ -100,7 +104,7 @@ var InterceptedWithOperationType_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "go/internal/linter/testdata/invalid.proto", + Metadata: "protoc-gen-gitaly-lint/testdata/invalid.proto", } // InvalidServiceClient is the client API for InvalidService service. @@ -970,5 +974,5 @@ var InvalidService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "go/internal/linter/testdata/invalid.proto", + Metadata: "protoc-gen-gitaly-lint/testdata/invalid.proto", } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.pb.go similarity index 58% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.pb.go index 2885e84302..79d0ad025b 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.pb.go @@ -1,13 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: go/internal/linter/testdata/valid.proto +// protoc-gen-go v1.28.0 +// protoc v3.21.1 +// source: protoc-gen-gitaly-lint/testdata/valid.proto package testdata import ( - gitalypb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalypb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -32,7 +32,7 @@ type ValidRequest struct { func (x *ValidRequest) Reset() { *x = ValidRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[0] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -45,7 +45,7 @@ func (x *ValidRequest) String() string { func (*ValidRequest) ProtoMessage() {} func (x *ValidRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[0] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -58,7 +58,7 @@ func (x *ValidRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidRequest.ProtoReflect.Descriptor instead. func (*ValidRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{0} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{0} } func (x *ValidRequest) GetDestination() *gitalypb.Repository { @@ -77,7 +77,7 @@ type ValidRequestWithoutRepo struct { func (x *ValidRequestWithoutRepo) Reset() { *x = ValidRequestWithoutRepo{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[1] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -90,7 +90,7 @@ func (x *ValidRequestWithoutRepo) String() string { func (*ValidRequestWithoutRepo) ProtoMessage() {} func (x *ValidRequestWithoutRepo) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[1] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -103,7 +103,7 @@ func (x *ValidRequestWithoutRepo) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidRequestWithoutRepo.ProtoReflect.Descriptor instead. func (*ValidRequestWithoutRepo) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{1} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{1} } type ValidStorageRequest struct { @@ -117,7 +117,7 @@ type ValidStorageRequest struct { func (x *ValidStorageRequest) Reset() { *x = ValidStorageRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[2] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -130,7 +130,7 @@ func (x *ValidStorageRequest) String() string { func (*ValidStorageRequest) ProtoMessage() {} func (x *ValidStorageRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[2] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -143,7 +143,7 @@ func (x *ValidStorageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidStorageRequest.ProtoReflect.Descriptor instead. func (*ValidStorageRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{2} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{2} } func (x *ValidStorageRequest) GetStorageName() string { @@ -162,7 +162,7 @@ type ValidResponse struct { func (x *ValidResponse) Reset() { *x = ValidResponse{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[3] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -175,7 +175,7 @@ func (x *ValidResponse) String() string { func (*ValidResponse) ProtoMessage() {} func (x *ValidResponse) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[3] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -188,7 +188,7 @@ func (x *ValidResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidResponse.ProtoReflect.Descriptor instead. func (*ValidResponse) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{3} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{3} } type ValidNestedRequest struct { @@ -202,7 +202,7 @@ type ValidNestedRequest struct { func (x *ValidNestedRequest) Reset() { *x = ValidNestedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[4] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -215,7 +215,7 @@ func (x *ValidNestedRequest) String() string { func (*ValidNestedRequest) ProtoMessage() {} func (x *ValidNestedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[4] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -228,7 +228,7 @@ func (x *ValidNestedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidNestedRequest.ProtoReflect.Descriptor instead. func (*ValidNestedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{4} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{4} } func (x *ValidNestedRequest) GetInnerMessage() *ValidRequest { @@ -249,7 +249,7 @@ type ValidStorageNestedRequest struct { func (x *ValidStorageNestedRequest) Reset() { *x = ValidStorageNestedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[5] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -262,7 +262,7 @@ func (x *ValidStorageNestedRequest) String() string { func (*ValidStorageNestedRequest) ProtoMessage() {} func (x *ValidStorageNestedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[5] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -275,7 +275,7 @@ func (x *ValidStorageNestedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidStorageNestedRequest.ProtoReflect.Descriptor instead. func (*ValidStorageNestedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{5} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{5} } func (x *ValidStorageNestedRequest) GetInnerMessage() *ValidStorageRequest { @@ -296,7 +296,7 @@ type ValidNestedSharedRequest struct { func (x *ValidNestedSharedRequest) Reset() { *x = ValidNestedSharedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[6] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -309,7 +309,7 @@ func (x *ValidNestedSharedRequest) String() string { func (*ValidNestedSharedRequest) ProtoMessage() {} func (x *ValidNestedSharedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[6] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -322,7 +322,7 @@ func (x *ValidNestedSharedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidNestedSharedRequest.ProtoReflect.Descriptor instead. func (*ValidNestedSharedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{6} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{6} } func (x *ValidNestedSharedRequest) GetNestedTargetRepo() *gitalypb.ObjectPool { @@ -343,7 +343,7 @@ type ValidInnerNestedRequest struct { func (x *ValidInnerNestedRequest) Reset() { *x = ValidInnerNestedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[7] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -356,7 +356,7 @@ func (x *ValidInnerNestedRequest) String() string { func (*ValidInnerNestedRequest) ProtoMessage() {} func (x *ValidInnerNestedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[7] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -369,7 +369,7 @@ func (x *ValidInnerNestedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidInnerNestedRequest.ProtoReflect.Descriptor instead. func (*ValidInnerNestedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{7} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{7} } func (x *ValidInnerNestedRequest) GetHeader() *ValidInnerNestedRequest_Header { @@ -390,7 +390,7 @@ type ValidStorageInnerNestedRequest struct { func (x *ValidStorageInnerNestedRequest) Reset() { *x = ValidStorageInnerNestedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[8] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -403,7 +403,7 @@ func (x *ValidStorageInnerNestedRequest) String() string { func (*ValidStorageInnerNestedRequest) ProtoMessage() {} func (x *ValidStorageInnerNestedRequest) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[8] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -416,7 +416,7 @@ func (x *ValidStorageInnerNestedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidStorageInnerNestedRequest.ProtoReflect.Descriptor instead. func (*ValidStorageInnerNestedRequest) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{8} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{8} } func (x *ValidStorageInnerNestedRequest) GetHeader() *ValidStorageInnerNestedRequest_Header { @@ -437,7 +437,7 @@ type ValidInnerNestedRequest_Header struct { func (x *ValidInnerNestedRequest_Header) Reset() { *x = ValidInnerNestedRequest_Header{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[9] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -450,7 +450,7 @@ func (x *ValidInnerNestedRequest_Header) String() string { func (*ValidInnerNestedRequest_Header) ProtoMessage() {} func (x *ValidInnerNestedRequest_Header) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[9] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -463,7 +463,7 @@ func (x *ValidInnerNestedRequest_Header) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidInnerNestedRequest_Header.ProtoReflect.Descriptor instead. func (*ValidInnerNestedRequest_Header) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{7, 0} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{7, 0} } func (x *ValidInnerNestedRequest_Header) GetDestination() *gitalypb.Repository { @@ -484,7 +484,7 @@ type ValidStorageInnerNestedRequest_Header struct { func (x *ValidStorageInnerNestedRequest_Header) Reset() { *x = ValidStorageInnerNestedRequest_Header{} if protoimpl.UnsafeEnabled { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[10] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -497,7 +497,7 @@ func (x *ValidStorageInnerNestedRequest_Header) String() string { func (*ValidStorageInnerNestedRequest_Header) ProtoMessage() {} func (x *ValidStorageInnerNestedRequest_Header) ProtoReflect() protoreflect.Message { - mi := &file_go_internal_linter_testdata_valid_proto_msgTypes[10] + mi := &file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -510,7 +510,7 @@ func (x *ValidStorageInnerNestedRequest_Header) ProtoReflect() protoreflect.Mess // Deprecated: Use ValidStorageInnerNestedRequest_Header.ProtoReflect.Descriptor instead. func (*ValidStorageInnerNestedRequest_Header) Descriptor() ([]byte, []int) { - return file_go_internal_linter_testdata_valid_proto_rawDescGZIP(), []int{8, 0} + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP(), []int{8, 0} } func (x *ValidStorageInnerNestedRequest_Header) GetStorageName() string { @@ -520,157 +520,157 @@ func (x *ValidStorageInnerNestedRequest_Header) GetStorageName() string { return "" } -var File_go_internal_linter_testdata_valid_proto protoreflect.FileDescriptor +var File_protoc_gen_gitaly_lint_testdata_valid_proto protoreflect.FileDescriptor -var file_go_internal_linter_testdata_valid_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x67, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x74, 0x65, 0x73, 0x74, 0x1a, - 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, 0x0c, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, +var file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDesc = []byte{ + 0x0a, 0x2b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2d, 0x6c, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, + 0x61, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x74, + 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, + 0x0c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x22, 0x3e, 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0d, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x5b, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x62, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, + 0x12, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x42, 0x04, 0x98, + 0xc6, 0x2c, 0x01, 0x52, 0x10, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x22, 0x9d, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, + 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, + 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, + 0x44, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x22, 0x3e, 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x98, 0x01, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x6e, 0x65, + 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x31, 0x0a, + 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x0f, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x5b, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, - 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, - 0x0c, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x62, 0x0a, - 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x68, 0x61, 0x72, - 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x12, 0x6e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, - 0x10, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x22, 0x9d, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, 0x6e, 0x65, 0x72, - 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x44, 0x0a, 0x06, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, - 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x98, 0x01, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x31, 0x0a, 0x06, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x88, 0xc6, 0x2c, 0x01, 0x52, - 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0x51, 0x0a, 0x12, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x32, - 0xc4, 0x08, 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x3d, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x12, - 0x3e, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x32, 0x12, 0x12, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, - 0x3e, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x33, 0x12, 0x12, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, - 0x44, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x35, 0x12, 0x18, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, + 0x32, 0x51, 0x0a, 0x12, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x4a, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x36, 0x12, 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x01, 0x12, 0x49, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x37, - 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, 0x6e, - 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x47, 0x0a, 0x0b, - 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x38, 0x12, 0x19, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, 0x4d, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x39, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xfa, 0x97, 0x28, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x12, 0x44, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x31, 0x30, 0x12, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x80, 0x98, 0x28, 0x01, 0x12, 0x42, 0x0a, 0x0f, 0x54, 0x65, - 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x53, - 0x0a, 0x20, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, - 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x53, 0x63, 0x6f, - 0x70, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, + 0x97, 0x28, 0x01, 0x32, 0xc4, 0x08, 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, - 0x02, 0x08, 0x03, 0x12, 0x59, 0x0a, 0x20, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, - 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x65, - 0x0a, 0x26, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, - 0x65, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x68, 0x61, 0x72, 0x65, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x02, 0x08, 0x02, 0x12, 0x3e, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x32, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x01, 0x12, 0x3e, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x33, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, + 0x02, 0x08, 0x01, 0x12, 0x44, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x35, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x4a, 0x0a, 0x0b, 0x54, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x36, 0x12, 0x1e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, - 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x5f, 0x0a, 0x21, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x75, 0x74, - 0x61, 0x74, 0x6f, 0x72, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, + 0x97, 0x28, 0x02, 0x08, 0x01, 0x12, 0x49, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x37, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x01, + 0x12, 0x47, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x38, 0x12, + 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x08, 0xfa, 0x97, 0x28, 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, 0x4d, 0x0a, 0x0b, 0x54, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x39, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, - 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, + 0xfa, 0x97, 0x28, 0x04, 0x08, 0x01, 0x10, 0x02, 0x12, 0x44, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x31, 0x30, 0x12, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x04, 0x80, 0x98, 0x28, 0x01, 0x12, 0x42, + 0x0a, 0x0f, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x03, 0x12, 0x53, 0x0a, 0x20, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x59, 0x0a, 0x20, 0x54, 0x65, 0x73, 0x74, 0x4d, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, + 0x08, 0x03, 0x12, 0x65, 0x0a, 0x26, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x12, 0x5f, 0x0a, 0x21, 0x54, 0x65, 0x73, + 0x74, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x65, + 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x49, 0x6e, 0x6e, 0x65, 0x72, + 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x03, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, + 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, + 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x74, + 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2d, 0x6c, 0x69, 0x6e, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, + 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_go_internal_linter_testdata_valid_proto_rawDescOnce sync.Once - file_go_internal_linter_testdata_valid_proto_rawDescData = file_go_internal_linter_testdata_valid_proto_rawDesc + file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescOnce sync.Once + file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescData = file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDesc ) -func file_go_internal_linter_testdata_valid_proto_rawDescGZIP() []byte { - file_go_internal_linter_testdata_valid_proto_rawDescOnce.Do(func() { - file_go_internal_linter_testdata_valid_proto_rawDescData = protoimpl.X.CompressGZIP(file_go_internal_linter_testdata_valid_proto_rawDescData) +func file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescGZIP() []byte { + file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescOnce.Do(func() { + file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescData = protoimpl.X.CompressGZIP(file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescData) }) - return file_go_internal_linter_testdata_valid_proto_rawDescData + return file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDescData } -var file_go_internal_linter_testdata_valid_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_go_internal_linter_testdata_valid_proto_goTypes = []interface{}{ +var file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_protoc_gen_gitaly_lint_testdata_valid_proto_goTypes = []interface{}{ (*ValidRequest)(nil), // 0: test.ValidRequest (*ValidRequestWithoutRepo)(nil), // 1: test.ValidRequestWithoutRepo (*ValidStorageRequest)(nil), // 2: test.ValidStorageRequest @@ -685,7 +685,7 @@ var file_go_internal_linter_testdata_valid_proto_goTypes = []interface{}{ (*gitalypb.Repository)(nil), // 11: gitaly.Repository (*gitalypb.ObjectPool)(nil), // 12: gitaly.ObjectPool } -var file_go_internal_linter_testdata_valid_proto_depIdxs = []int32{ +var file_protoc_gen_gitaly_lint_testdata_valid_proto_depIdxs = []int32{ 11, // 0: test.ValidRequest.destination:type_name -> gitaly.Repository 0, // 1: test.ValidNestedRequest.inner_message:type_name -> test.ValidRequest 2, // 2: test.ValidStorageNestedRequest.inner_message:type_name -> test.ValidStorageRequest @@ -730,13 +730,13 @@ var file_go_internal_linter_testdata_valid_proto_depIdxs = []int32{ 0, // [0:7] is the sub-list for field type_name } -func init() { file_go_internal_linter_testdata_valid_proto_init() } -func file_go_internal_linter_testdata_valid_proto_init() { - if File_go_internal_linter_testdata_valid_proto != nil { +func init() { file_protoc_gen_gitaly_lint_testdata_valid_proto_init() } +func file_protoc_gen_gitaly_lint_testdata_valid_proto_init() { + if File_protoc_gen_gitaly_lint_testdata_valid_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_go_internal_linter_testdata_valid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidRequest); i { case 0: return &v.state @@ -748,7 +748,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidRequestWithoutRepo); i { case 0: return &v.state @@ -760,7 +760,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidStorageRequest); i { case 0: return &v.state @@ -772,7 +772,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidResponse); i { case 0: return &v.state @@ -784,7 +784,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidNestedRequest); i { case 0: return &v.state @@ -796,7 +796,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidStorageNestedRequest); i { case 0: return &v.state @@ -808,7 +808,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidNestedSharedRequest); i { case 0: return &v.state @@ -820,7 +820,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidInnerNestedRequest); i { case 0: return &v.state @@ -832,7 +832,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidStorageInnerNestedRequest); i { case 0: return &v.state @@ -844,7 +844,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidInnerNestedRequest_Header); i { case 0: return &v.state @@ -856,7 +856,7 @@ func file_go_internal_linter_testdata_valid_proto_init() { return nil } } - file_go_internal_linter_testdata_valid_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidStorageInnerNestedRequest_Header); i { case 0: return &v.state @@ -873,18 +873,18 @@ func file_go_internal_linter_testdata_valid_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_go_internal_linter_testdata_valid_proto_rawDesc, + RawDescriptor: file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDesc, NumEnums: 0, NumMessages: 11, NumExtensions: 0, NumServices: 2, }, - GoTypes: file_go_internal_linter_testdata_valid_proto_goTypes, - DependencyIndexes: file_go_internal_linter_testdata_valid_proto_depIdxs, - MessageInfos: file_go_internal_linter_testdata_valid_proto_msgTypes, + GoTypes: file_protoc_gen_gitaly_lint_testdata_valid_proto_goTypes, + DependencyIndexes: file_protoc_gen_gitaly_lint_testdata_valid_proto_depIdxs, + MessageInfos: file_protoc_gen_gitaly_lint_testdata_valid_proto_msgTypes, }.Build() - File_go_internal_linter_testdata_valid_proto = out.File - file_go_internal_linter_testdata_valid_proto_rawDesc = nil - file_go_internal_linter_testdata_valid_proto_goTypes = nil - file_go_internal_linter_testdata_valid_proto_depIdxs = nil + File_protoc_gen_gitaly_lint_testdata_valid_proto = out.File + file_protoc_gen_gitaly_lint_testdata_valid_proto_rawDesc = nil + file_protoc_gen_gitaly_lint_testdata_valid_proto_goTypes = nil + file_protoc_gen_gitaly_lint_testdata_valid_proto_depIdxs = nil } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.proto b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.proto similarity index 96% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.proto rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.proto index 9d1c9532e0..398c1b15fe 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid.proto +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid.proto @@ -2,11 +2,11 @@ syntax = "proto3"; package test; -option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata"; - import "lint.proto"; import "shared.proto"; +option go_package = "gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata"; + message ValidRequest { gitaly.Repository destination = 1 [(gitaly.target_repository)=true]; } @@ -18,7 +18,8 @@ message ValidStorageRequest { string storage_name = 1 [(gitaly.storage)=true]; } -message ValidResponse{} +message ValidResponse{ +} message ValidNestedRequest{ ValidRequest inner_message = 1; diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid_grpc.pb.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid_grpc.pb.go similarity index 99% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid_grpc.pb.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid_grpc.pb.go index c9d929b1ff..6d9ff8ad56 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter/testdata/valid_grpc.pb.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-lint/testdata/valid_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.1 +// source: protoc-gen-gitaly-lint/testdata/valid.proto package testdata @@ -97,7 +101,7 @@ var InterceptedService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "go/internal/linter/testdata/valid.proto", + Metadata: "protoc-gen-gitaly-lint/testdata/valid.proto", } // ValidServiceClient is the client API for ValidService service. @@ -653,5 +657,5 @@ var ValidService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "go/internal/linter/testdata/valid.proto", + Metadata: "protoc-gen-gitaly-lint/testdata/valid.proto", } diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/cmd/protoc-gen-gitaly/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-protolist/main.go similarity index 56% rename from workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/cmd/protoc-gen-gitaly/main.go rename to workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-protolist/main.go index efe8a312ed..7e775360eb 100644 --- a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/cmd/protoc-gen-gitaly/main.go +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/protoc-gen-gitaly-protolist/main.go @@ -1,53 +1,12 @@ -/*Command protoc-gen-gitaly is designed to be used as a protobuf compiler -plugin to verify Gitaly processes are being followed when writing RPC's. - -Usage - -The protoc-gen-gitaly linter can be chained into any protoc workflow that -requires verification that Gitaly RPC guidelines are followed. Typically -this can be done by adding the following argument to an existing protoc -command: - - --gitaly_out=. - -For example, you may add the linter as an argument to the command responsible -for generating Go code: - - protoc --go_out=. --gitaly_out=. *.proto - -Or, you can run the Gitaly linter by itself. To try out, run the following -command while in the project root: - - protoc --gitaly_out=. ./go/internal/linter/testdata/incomplete.proto - -You should see some errors printed to screen for improperly written -RPC's in the incomplete.proto file. - -Prerequisites - -The protobuf compiler (protoc) can be obtained from the GitHub page: -https://github.com/protocolbuffers/protobuf/releases - -Background - -The protobuf compiler accepts plugins to analyze protobuf files and generate -language specific code. - -These plugins require the following executable naming convention: - - protoc-gen-$NAME - -Where $NAME is the plugin name of the compiler desired. The protobuf compiler -will search the PATH until an executable with that name is found for a -desired plugin. For example, the following protoc command: - - protoc --gitaly_out=. *.proto - -The above will search the PATH for an executable named protoc-gen-gitaly - -The plugin accepts a protobuf message in STDIN that describes the parsed -protobuf files. A response is sent back on STDOUT that contains any errors. -*/ +// Command protoc-gen-gitaly-protolist is designed to be used as a protobuf compiler to generate a +// list of protobuf files via a publicly accessible variable. +// +// This plugin can be accessed by invoking the protoc compiler with the following arguments: +// +// protoc --plugin=protoc-gen-gitaly-protolist --gitaly_protolist_out=. +// +// The plugin accepts a protobuf message in STDIN that describes the parsed protobuf files. A +// response is sent back on STDOUT that contains any errors. package main import ( @@ -61,7 +20,6 @@ import ( "strings" "text/template" - "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/pluginpb" ) @@ -83,10 +41,6 @@ func main() { log.Fatalf("parsing input proto: %s", err) } - if err := lintProtos(req); err != nil { - log.Fatal(err) - } - if err := generateProtolistGo(req); err != nil { log.Fatal(err) } @@ -109,35 +63,6 @@ func parseArgs(argString string) (gitalyProtoDir string, gitalypbDir string) { return gitalyProtoDir, gitalypbDir } -func lintProtos(req *pluginpb.CodeGeneratorRequest) error { - var errMsgs []string - for _, pf := range req.GetProtoFile() { - errs := linter.LintFile(pf, req) - for _, err := range errs { - errMsgs = append(errMsgs, err.Error()) - } - } - - resp := &pluginpb.CodeGeneratorResponse{} - - if len(errMsgs) > 0 { - errMsg := strings.Join(errMsgs, "\n\t") - resp.Error = &errMsg - } - - // Send back the results. - data, err := proto.Marshal(resp) - if err != nil { - return fmt.Errorf("failed to marshal output proto: %s", err) - } - - _, err = os.Stdout.Write(data) - if err != nil { - return fmt.Errorf("failed to write output proto: %s", err) - } - return nil -} - func generateProtolistGo(req *pluginpb.CodeGeneratorRequest) error { var err error gitalyProtoDir, gitalypbDir := parseArgs(req.GetParameter()) diff --git a/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/replace-buildid/main.go b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/replace-buildid/main.go new file mode 100644 index 0000000000..0eab441491 --- /dev/null +++ b/workhorse-vendor/gitlab.com/gitlab-org/gitaly/v15/tools/replace-buildid/main.go @@ -0,0 +1,125 @@ +// The `replace-buildid` tool is used to replace a build ID in an ELF binary with a new build ID. +// Note that this tool is extremely naive: it simply takes the old input ID as string, verifies +// that this ID is contained in the binary exactly once, and then replaces it. It has no knowledge +// about ELF binaries whatsoever. +// +// This tool is mainly used to replace our static GNU build ID we set in our Makefile with a +// derived build ID without having to build binaries twice. + +package main + +import ( + "bytes" + "encoding/hex" + "flag" + "fmt" + "io" + "os" + "path/filepath" +) + +func main() { + var inputPath, outputPath, inputBuildID, outputBuildID string + + flag.StringVar(&inputPath, "input", "", "path to the binary whose GNU build ID should be replaced") + flag.StringVar(&outputPath, "output", "", "path whether the resulting binary should be placed") + flag.StringVar(&inputBuildID, "input-build-id", "", "static build ID to replace") + flag.StringVar(&outputBuildID, "output-build-id", "", "new build ID to replace old value with") + flag.Parse() + + if err := replaceBuildID(inputPath, outputPath, inputBuildID, outputBuildID); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } +} + +func replaceBuildID(inputPath, outputPath, inputBuildID, outputBuildID string) error { + if inputPath == "" { + return fmt.Errorf("missing input path") + } + if outputPath == "" { + return fmt.Errorf("missing output path") + } + if inputBuildID == "" { + return fmt.Errorf("missing output path") + } + if outputBuildID == "" { + return fmt.Errorf("missing output path") + } + if flag.NArg() > 0 { + return fmt.Errorf("extra arguments") + } + + inputBuildIDDecoded, err := hex.DecodeString(inputBuildID) + if err != nil { + return fmt.Errorf("decoding input build ID: %w", err) + } + + outputBuildIDDecoded, err := hex.DecodeString(outputBuildID) + if err != nil { + return fmt.Errorf("decoding output build ID: %w", err) + } + + if len(inputBuildIDDecoded) != len(outputBuildIDDecoded) { + return fmt.Errorf("input and output build IDs do not have the same length") + } + + data, err := readAndReplace(inputPath, inputBuildIDDecoded, outputBuildIDDecoded) + if err != nil { + return fmt.Errorf("could not replace build ID: %w", err) + } + + if err := writeBinary(outputPath, data); err != nil { + return fmt.Errorf("writing binary: %w", err) + } + + return nil +} + +func readAndReplace(binaryPath string, inputBuildID, outputBuildID []byte) ([]byte, error) { + inputFile, err := os.Open(binaryPath) + if err != nil { + return nil, fmt.Errorf("opening input file: %w", err) + } + defer inputFile.Close() + + data, err := io.ReadAll(inputFile) + if err != nil { + return nil, fmt.Errorf("reading input file: %w", err) + } + + if occurrences := bytes.Count(data, inputBuildID); occurrences != 1 { + return nil, fmt.Errorf("exactly one match for old build ID expected, got %d", occurrences) + } + + return bytes.ReplaceAll(data, inputBuildID, outputBuildID), nil +} + +func writeBinary(binaryPath string, contents []byte) error { + f, err := os.CreateTemp(filepath.Dir(binaryPath), filepath.Base(binaryPath)) + if err != nil { + return fmt.Errorf("could not create binary: %w", err) + } + defer func() { + _ = os.RemoveAll(f.Name()) + f.Close() + }() + + if err := f.Chmod(0o755); err != nil { + return fmt.Errorf("could not change permissions: %w", err) + } + + if _, err := io.Copy(f, bytes.NewReader(contents)); err != nil { + return fmt.Errorf("could not write binary: %w", err) + } + + if err := f.Close(); err != nil { + return fmt.Errorf("could not close binary: %w", err) + } + + if err := os.Rename(f.Name(), binaryPath); err != nil { + return fmt.Errorf("could not move binary into place: %w", err) + } + + return nil +}