diff options
Diffstat (limited to 'workhorse')
-rw-r--r-- | workhorse/gitaly_integration_test.go | 447 | ||||
-rw-r--r-- | workhorse/gitaly_test.go | 2 | ||||
-rw-r--r-- | workhorse/go.mod | 4 | ||||
-rw-r--r-- | workhorse/go.sum | 10 | ||||
-rw-r--r-- | workhorse/internal/gitaly/gitaly.go | 10 |
5 files changed, 269 insertions, 204 deletions
diff --git a/workhorse/gitaly_integration_test.go b/workhorse/gitaly_integration_test.go index ed44aaddbc3..a21c31aea49 100644 --- a/workhorse/gitaly_integration_test.go +++ b/workhorse/gitaly_integration_test.go @@ -8,6 +8,7 @@ import ( "bytes" "context" "fmt" + "net/url" "os" "os/exec" "path" @@ -26,32 +27,52 @@ import ( ) var ( - gitalyAddress string - jsonGitalyServer string + gitalyAddresses []string ) +// Convert from tcp://127.0.0.1:8075 to dns scheme variants: +// * dns:127.0.0.1:8075 +// * dns:///127.0.0.1:8075 +func convertToDNSSchemes(address string) []string { + uri, err := url.Parse(address) + if err != nil { + panic(fmt.Sprintf("invalid GITALY_ADDRESS url %s: %s", address, err)) + } + return []string{ + fmt.Sprintf("dns:///%s", uri.Host), + fmt.Sprintf("dns:%s", uri.Host), + } +} + +func jsonGitalyServer(address string) string { + return fmt.Sprintf(`"GitalyServer":{"Address":"%s", "Token": ""}`, address) +} + func init() { - gitalyAddress = os.Getenv("GITALY_ADDRESS") - jsonGitalyServer = fmt.Sprintf(`"GitalyServer":{"Address":"%s", "Token": ""}`, gitalyAddress) + rawAddress := os.Getenv("GITALY_ADDRESS") + if rawAddress != "" { + gitalyAddresses = append(gitalyAddresses, rawAddress) + gitalyAddresses = append(gitalyAddresses, convertToDNSSchemes(rawAddress)...) + } } func skipUnlessRealGitaly(t *testing.T) { - t.Log(gitalyAddress) - if gitalyAddress != "" { + t.Log(gitalyAddresses) + if len(gitalyAddresses) != 0 { return } t.Skip(`Please set GITALY_ADDRESS="..." to run Gitaly integration tests`) } -func realGitalyAuthResponse(apiResponse *api.Response) *api.Response { +func realGitalyAuthResponse(gitalyAddress string, apiResponse *api.Response) *api.Response { apiResponse.GitalyServer.Address = gitalyAddress return apiResponse } -func realGitalyOkBody(t *testing.T) *api.Response { - return realGitalyAuthResponse(gitOkBody(t)) +func realGitalyOkBody(t *testing.T, gitalyAddress string) *api.Response { + return realGitalyAuthResponse(gitalyAddress, gitOkBody(t)) } func ensureGitalyRepository(t *testing.T, apiResponse *api.Response) error { @@ -105,241 +126,273 @@ func ensureGitalyRepository(t *testing.T, apiResponse *api.Response) error { func TestAllowedClone(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - // Prepare test server and backend - ts := testAuthServer(t, nil, nil, 200, apiResponse) - defer ts.Close() - ws := startWorkhorseServer(ts.URL) - defer ws.Close() - - // Do the git clone - require.NoError(t, os.RemoveAll(scratchDir)) - cloneCmd := exec.Command("git", "clone", fmt.Sprintf("%s/%s", ws.URL, testRepo), checkoutDir) - runOrFail(t, cloneCmd) - - // We may have cloned an 'empty' repository, 'git log' will fail in it - logCmd := exec.Command("git", "log", "-1", "--oneline") - logCmd.Dir = checkoutDir - runOrFail(t, logCmd) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + // Prepare test server and backend + ts := testAuthServer(t, nil, nil, 200, apiResponse) + defer ts.Close() + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + // Do the git clone + require.NoError(t, os.RemoveAll(scratchDir)) + cloneCmd := exec.Command("git", "clone", fmt.Sprintf("%s/%s", ws.URL, testRepo), checkoutDir) + runOrFail(t, cloneCmd) + + // We may have cloned an 'empty' repository, 'git log' will fail in it + logCmd := exec.Command("git", "log", "-1", "--oneline") + logCmd.Dir = checkoutDir + runOrFail(t, logCmd) + }) + } } func TestAllowedShallowClone(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - // Prepare test server and backend - ts := testAuthServer(t, nil, nil, 200, apiResponse) - defer ts.Close() - ws := startWorkhorseServer(ts.URL) - defer ws.Close() - - // Shallow git clone (depth 1) - require.NoError(t, os.RemoveAll(scratchDir)) - cloneCmd := exec.Command("git", "clone", "--depth", "1", fmt.Sprintf("%s/%s", ws.URL, testRepo), checkoutDir) - runOrFail(t, cloneCmd) - - // We may have cloned an 'empty' repository, 'git log' will fail in it - logCmd := exec.Command("git", "log", "-1", "--oneline") - logCmd.Dir = checkoutDir - runOrFail(t, logCmd) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + // Prepare test server and backend + ts := testAuthServer(t, nil, nil, 200, apiResponse) + defer ts.Close() + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + // Shallow git clone (depth 1) + require.NoError(t, os.RemoveAll(scratchDir)) + cloneCmd := exec.Command("git", "clone", "--depth", "1", fmt.Sprintf("%s/%s", ws.URL, testRepo), checkoutDir) + runOrFail(t, cloneCmd) + + // We may have cloned an 'empty' repository, 'git log' will fail in it + logCmd := exec.Command("git", "log", "-1", "--oneline") + logCmd.Dir = checkoutDir + runOrFail(t, logCmd) + }) + } } func TestAllowedPush(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - // Prepare the test server and backend - ts := testAuthServer(t, nil, nil, 200, apiResponse) - defer ts.Close() - ws := startWorkhorseServer(ts.URL) - defer ws.Close() - - // Perform the git push - pushCmd := exec.Command("git", "push", fmt.Sprintf("%s/%s", ws.URL, testRepo), fmt.Sprintf("master:%s", newBranch())) - pushCmd.Dir = checkoutDir - runOrFail(t, pushCmd) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + // Prepare the test server and backend + ts := testAuthServer(t, nil, nil, 200, apiResponse) + defer ts.Close() + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + // Perform the git push + pushCmd := exec.Command("git", "push", fmt.Sprintf("%s/%s", ws.URL, testRepo), fmt.Sprintf("master:%s", newBranch())) + pushCmd.Dir = checkoutDir + runOrFail(t, pushCmd) + }) + } } func TestAllowedGetGitBlob(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - // the LICENSE file in the test repository - oid := "50b27c6518be44c42c4d87966ae2481ce895624c" - expectedBody := "The MIT License (MIT)" - bodyLen := 1075 - - jsonParams := fmt.Sprintf( - `{ - %s, - "GetBlobRequest":{ - "repository":{"storage_name":"%s", "relative_path":"%s"}, - "oid":"%s", - "limit":-1 - } - }`, - jsonGitalyServer, apiResponse.Repository.StorageName, apiResponse.Repository.RelativePath, oid, - ) - - resp, body, err := doSendDataRequest("/something", "git-blob", jsonParams) - require.NoError(t, err) - shortBody := string(body[:len(expectedBody)]) - - require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) - require.Equal(t, expectedBody, shortBody, "GET %q: response body", resp.Request.URL) - testhelper.RequireResponseHeader(t, resp, "Content-Length", strconv.Itoa(bodyLen)) - requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + // the LICENSE file in the test repository + oid := "50b27c6518be44c42c4d87966ae2481ce895624c" + expectedBody := "The MIT License (MIT)" + bodyLen := 1075 + + jsonParams := fmt.Sprintf( + `{ + %s, + "GetBlobRequest":{ + "repository":{"storage_name":"%s", "relative_path":"%s"}, + "oid":"%s", + "limit":-1 + } + }`, + jsonGitalyServer(gitalyAddress), apiResponse.Repository.StorageName, apiResponse.Repository.RelativePath, oid, + ) + + resp, body, err := doSendDataRequest("/something", "git-blob", jsonParams) + require.NoError(t, err) + shortBody := string(body[:len(expectedBody)]) + + require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) + require.Equal(t, expectedBody, shortBody, "GET %q: response body", resp.Request.URL) + testhelper.RequireResponseHeader(t, resp, "Content-Length", strconv.Itoa(bodyLen)) + requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + }) + } } func TestAllowedGetGitArchive(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - archivePath := path.Join(scratchDir, "my/path") - archivePrefix := "repo-1" - - msg := serializedProtoMessage("GetArchiveRequest", &gitalypb.GetArchiveRequest{ - Repository: &apiResponse.Repository, - CommitId: "HEAD", - Prefix: archivePrefix, - Format: gitalypb.GetArchiveRequest_TAR, - Path: []byte("files"), - }) - jsonParams := buildGitalyRPCParams(gitalyAddress, rpcArg{"ArchivePath", archivePath}, msg) - - resp, body, err := doSendDataRequest("/archive.tar", "git-archive", jsonParams) - require.NoError(t, err) - require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) - requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) - - // Ensure the tar file is readable - foundEntry := false - tr := tar.NewReader(bytes.NewReader(body)) - for { - hdr, err := tr.Next() - if err != nil { - break - } + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + archivePath := path.Join(scratchDir, "my/path") + archivePrefix := "repo-1" + + msg := serializedProtoMessage("GetArchiveRequest", &gitalypb.GetArchiveRequest{ + Repository: &apiResponse.Repository, + CommitId: "HEAD", + Prefix: archivePrefix, + Format: gitalypb.GetArchiveRequest_TAR, + Path: []byte("files"), + }) + jsonParams := buildGitalyRPCParams(gitalyAddress, rpcArg{"ArchivePath", archivePath}, msg) + + resp, body, err := doSendDataRequest("/archive.tar", "git-archive", jsonParams) + require.NoError(t, err) + require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) + requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + + // Ensure the tar file is readable + foundEntry := false + tr := tar.NewReader(bytes.NewReader(body)) + for { + hdr, err := tr.Next() + if err != nil { + break + } + + if hdr.Name == archivePrefix+"/" { + foundEntry = true + break + } + } - if hdr.Name == archivePrefix+"/" { - foundEntry = true - break - } + require.True(t, foundEntry, "Couldn't find %v directory entry", archivePrefix) + }) } - - require.True(t, foundEntry, "Couldn't find %v directory entry", archivePrefix) } func TestAllowedGetGitArchiveOldPayload(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - repo := &apiResponse.Repository - require.NoError(t, ensureGitalyRepository(t, apiResponse)) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + repo := &apiResponse.Repository + require.NoError(t, ensureGitalyRepository(t, apiResponse)) - archivePath := path.Join(scratchDir, "my/path") - archivePrefix := "repo-1" + archivePath := path.Join(scratchDir, "my/path") + archivePrefix := "repo-1" - jsonParams := fmt.Sprintf( - `{ + jsonParams := fmt.Sprintf( + `{ %s, "GitalyRepository":{"storage_name":"%s","relative_path":"%s"}, "ArchivePath":"%s", "ArchivePrefix":"%s", "CommitId":"%s" }`, - jsonGitalyServer, repo.StorageName, repo.RelativePath, archivePath, archivePrefix, "HEAD", - ) - - resp, body, err := doSendDataRequest("/archive.tar", "git-archive", jsonParams) - require.NoError(t, err) - require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) - requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) - - // Ensure the tar file is readable - foundEntry := false - tr := tar.NewReader(bytes.NewReader(body)) - for { - hdr, err := tr.Next() - if err != nil { - break - } + jsonGitalyServer(gitalyAddress), repo.StorageName, repo.RelativePath, archivePath, archivePrefix, "HEAD", + ) + + resp, body, err := doSendDataRequest("/archive.tar", "git-archive", jsonParams) + require.NoError(t, err) + require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) + requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + + // Ensure the tar file is readable + foundEntry := false + tr := tar.NewReader(bytes.NewReader(body)) + for { + hdr, err := tr.Next() + if err != nil { + break + } + + if hdr.Name == archivePrefix+"/" { + foundEntry = true + break + } + } - if hdr.Name == archivePrefix+"/" { - foundEntry = true - break - } + require.True(t, foundEntry, "Couldn't find %v directory entry", archivePrefix) + }) } - - require.True(t, foundEntry, "Couldn't find %v directory entry", archivePrefix) } func TestAllowedGetGitDiff(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - msg := serializedMessage("RawDiffRequest", &gitalypb.RawDiffRequest{ - Repository: &apiResponse.Repository, - LeftCommitId: "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9", - RightCommitId: "732401c65e924df81435deb12891ef570167d2e2", - }) - jsonParams := buildGitalyRPCParams(gitalyAddress, msg) - - resp, body, err := doSendDataRequest("/something", "git-diff", jsonParams) - require.NoError(t, err) - - require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) - requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) - - expectedBody := "diff --git a/LICENSE b/LICENSE\n" - require.Equal(t, expectedBody, string(body[:len(expectedBody)]), - "GET %q: response body", resp.Request.URL) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + msg := serializedMessage("RawDiffRequest", &gitalypb.RawDiffRequest{ + Repository: &apiResponse.Repository, + LeftCommitId: "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9", + RightCommitId: "732401c65e924df81435deb12891ef570167d2e2", + }) + jsonParams := buildGitalyRPCParams(gitalyAddress, msg) + + resp, body, err := doSendDataRequest("/something", "git-diff", jsonParams) + require.NoError(t, err) + + require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) + requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + + expectedBody := "diff --git a/LICENSE b/LICENSE\n" + require.Equal(t, expectedBody, string(body[:len(expectedBody)]), + "GET %q: response body", resp.Request.URL) + }) + } } func TestAllowedGetGitFormatPatch(t *testing.T) { skipUnlessRealGitaly(t) - // Create the repository in the Gitaly server - apiResponse := realGitalyOkBody(t) - require.NoError(t, ensureGitalyRepository(t, apiResponse)) - - msg := serializedMessage("RawPatchRequest", &gitalypb.RawPatchRequest{ - Repository: &apiResponse.Repository, - LeftCommitId: "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9", - RightCommitId: "0e1b353b348f8477bdbec1ef47087171c5032cd9", - }) - jsonParams := buildGitalyRPCParams(gitalyAddress, msg) - - resp, body, err := doSendDataRequest("/something", "git-format-patch", jsonParams) - require.NoError(t, err) - - require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) - requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) - - requirePatchSeries(t, body, - "732401c65e924df81435deb12891ef570167d2e2", - "33bcff41c232a11727ac6d660bd4b0c2ba86d63d", - "0e1b353b348f8477bdbec1ef47087171c5032cd9", - ) + for _, gitalyAddress := range gitalyAddresses { + t.Run(gitalyAddress, func(t *testing.T) { + // Create the repository in the Gitaly server + apiResponse := realGitalyOkBody(t, gitalyAddress) + require.NoError(t, ensureGitalyRepository(t, apiResponse)) + + msg := serializedMessage("RawPatchRequest", &gitalypb.RawPatchRequest{ + Repository: &apiResponse.Repository, + LeftCommitId: "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9", + RightCommitId: "0e1b353b348f8477bdbec1ef47087171c5032cd9", + }) + jsonParams := buildGitalyRPCParams(gitalyAddress, msg) + + resp, body, err := doSendDataRequest("/something", "git-format-patch", jsonParams) + require.NoError(t, err) + + require.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL) + requireNginxResponseBuffering(t, "no", resp, "GET %q: nginx response buffering", resp.Request.URL) + + requirePatchSeries(t, body, + "732401c65e924df81435deb12891ef570167d2e2", + "33bcff41c232a11727ac6d660bd4b0c2ba86d63d", + "0e1b353b348f8477bdbec1ef47087171c5032cd9", + ) + }) + } } var extractPatchSeriesMatcher = regexp.MustCompile(`^From (\w+)`) diff --git a/workhorse/gitaly_test.go b/workhorse/gitaly_test.go index 2d7f727003f..de896475a99 100644 --- a/workhorse/gitaly_test.go +++ b/workhorse/gitaly_test.go @@ -439,7 +439,7 @@ func TestPostUploadPackProxiedToGitalySuccessfully(t *testing.T) { bodySplit := strings.SplitN(body, "\000", 2) require.Len(t, bodySplit, 2) - gitalyRequest := &gitalypb.PostUploadPackRequest{} + gitalyRequest := &gitalypb.PostUploadPackWithSidechannelRequest{} require.NoError(t, jsonpb.UnmarshalString(bodySplit[0], gitalyRequest)) require.Equal(t, apiResponse.Repository.StorageName, gitalyRequest.Repository.StorageName) diff --git a/workhorse/go.mod b/workhorse/go.mod index 6e397a75019..76374a28f5c 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -26,7 +26,7 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/smartystreets/goconvey v1.7.2 github.com/stretchr/testify v1.8.1 - gitlab.com/gitlab-org/gitaly/v15 v15.8.1 + gitlab.com/gitlab-org/gitaly/v15 v15.9.0-rc4 gitlab.com/gitlab-org/golang-archive-zip v0.1.1 gitlab.com/gitlab-org/labkit v1.17.0 gocloud.dev v0.28.0 @@ -111,7 +111,7 @@ require ( golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect golang.org/x/mod v0.6.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect golang.org/x/text v0.6.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/workhorse/go.sum b/workhorse/go.sum index 5e1d22d2fa1..64749d157d3 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -1435,6 +1435,7 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -1845,8 +1846,8 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -gitlab.com/gitlab-org/gitaly/v15 v15.8.1 h1:i/38/jLhvXwiztdrUCh9YxCrYufWS0K6pKQnbF3vy8U= -gitlab.com/gitlab-org/gitaly/v15 v15.8.1/go.mod h1:typ7BQ9JuglkeTvW3Vn1SwFcZ1FMn8P3GrWcPuZQ0EU= +gitlab.com/gitlab-org/gitaly/v15 v15.9.0-rc4 h1:n6VW2djSoiGaajMUkVy+crRnyiUePcW1v1T3wPd2hhI= +gitlab.com/gitlab-org/gitaly/v15 v15.9.0-rc4/go.mod h1:y0OCqEn0WWmyycVpde494A5qhCszhlx2b+od6vSzsOU= gitlab.com/gitlab-org/golang-archive-zip v0.1.1 h1:35k9giivbxwF03+8A05Cm8YoxoakU8FBCj5gysjCTCE= gitlab.com/gitlab-org/golang-archive-zip v0.1.1/go.mod h1:ZDtqpWPGPB9qBuZnZDrKQjIdJtkN7ZAoVwhT6H2o2kE= gitlab.com/gitlab-org/labkit v1.17.0 h1:mEkoLzXorLNdt8NkfgYS5xMDhdqCsIJaeEVtSf7d8cU= @@ -2003,6 +2004,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE= golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -2328,8 +2330,8 @@ golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/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/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/workhorse/internal/gitaly/gitaly.go b/workhorse/internal/gitaly/gitaly.go index af7425be1cf..eace87dda36 100644 --- a/workhorse/internal/gitaly/gitaly.go +++ b/workhorse/internal/gitaly/gitaly.go @@ -192,6 +192,16 @@ func newConnection(server api.GitalyServer) (*grpc.ClientConn, error) { ), ), ), + + // In https://gitlab.com/groups/gitlab-org/-/epics/8971, we added DNS discovery support to Praefect. This was + // done by making two changes: + // - Configure client-side round-robin load-balancing in client dial options. We added that as a default option + // inside gitaly client in gitaly client since v15.9.0 + // - Configure DNS resolving. Due to some technical limitations, we don't use gRPC's built-in DNS resolver. + // Instead, we implement our own DNS resolver. This resolver is exposed via the following configuration. + // Afterward, workhorse can detect and handle DNS discovery automatically. The user needs to setup and set + // Gitaly address to something like "dns:gitaly.service.dc1.consul" + gitalyclient.WithGitalyDNSResolver(gitalyclient.DefaultDNSResolverBuilderConfig()), ) conn, connErr := gitalyclient.DialSidechannel(context.Background(), server.Address, sidechannelRegistry, connOpts) // lint:allow context.Background |