diff options
author | Stan Hu <stanhu@gmail.com> | 2020-09-19 23:30:32 +0300 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2020-09-21 07:53:12 +0300 |
commit | b62da200fb1559b6014f392c9c2bb2ebda9ee3d7 (patch) | |
tree | 4ba4936d677c7e7412fd9c701cd201952ea4175c | |
parent | 2f16d97afa2e8accb4144f04e2e1e90bf4d1e9fb (diff) |
Pass correlation ID to hooks
Previously the `correlation_id` was not passed along the `X-Request-Id`
header to the GitLab API requests
(e.g. `/api/v4/internal/{pre_receive,post_receive}`). Now we extract the
`CORRELATION_ID` environment variable, store it in the context for the
gitaly-hooks binary, and pass the context along to the API requests.
This requires an update to gitlab-shell to support this:
https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/413
Fixes https://gitlab.com/gitlab-org/gitaly/-/issues/2725
-rw-r--r-- | changelogs/unreleased/sh-pass-correlation-id-to-hooks.yml | 5 | ||||
-rw-r--r-- | cmd/gitaly-hooks/hooks.go | 4 | ||||
-rw-r--r-- | go.mod | 4 | ||||
-rw-r--r-- | go.sum | 8 | ||||
-rw-r--r-- | internal/gitaly/hook/access.go | 25 | ||||
-rw-r--r-- | internal/gitaly/hook/access_test.go | 11 | ||||
-rw-r--r-- | internal/gitaly/hook/postreceive.go | 2 | ||||
-rw-r--r-- | internal/gitaly/hook/prereceive.go | 4 |
8 files changed, 39 insertions, 24 deletions
diff --git a/changelogs/unreleased/sh-pass-correlation-id-to-hooks.yml b/changelogs/unreleased/sh-pass-correlation-id-to-hooks.yml new file mode 100644 index 000000000..a333d182e --- /dev/null +++ b/changelogs/unreleased/sh-pass-correlation-id-to-hooks.yml @@ -0,0 +1,5 @@ +--- +title: Pass correlation ID to hooks +merge_request: 2576 +author: +type: fixed diff --git a/cmd/gitaly-hooks/hooks.go b/cmd/gitaly-hooks/hooks.go index 61ea7979b..208e47b5c 100644 --- a/cmd/gitaly-hooks/hooks.go +++ b/cmd/gitaly-hooks/hooks.go @@ -25,6 +25,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/stream" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" + "gitlab.com/gitlab-org/labkit/tracing" "google.golang.org/grpc" ) @@ -79,6 +80,9 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + ctx, finished := tracing.ExtractFromEnv(ctx) + defer finished() + repository, err := repositoryFromEnv() if err != nil { logger.Fatalf("error when getting repository: %v", err) @@ -17,10 +17,10 @@ require ( github.com/prometheus/client_golang v1.0.0 github.com/prometheus/procfs v0.0.3 // indirect github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237 - github.com/sirupsen/logrus v1.4.2 + github.com/sirupsen/logrus v1.6.0 github.com/stretchr/testify v1.4.0 github.com/uber/jaeger-client-go v2.15.0+incompatible - gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200821152636-82ec8144fb2a + gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200921044701-1a2bfecd2f0e gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 @@ -189,6 +189,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi 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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= 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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -308,6 +310,8 @@ github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 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/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -353,8 +357,8 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ 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/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200821152636-82ec8144fb2a h1:MkoiKzWGRz2RCfDU6uFAO1vDLNZMSlyDWadL41nYjfw= -gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200821152636-82ec8144fb2a/go.mod h1:RABblvnnhHpFU/lexlwGqpKgZsLV3RGA2D/Elp5/KEA= +gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200921044701-1a2bfecd2f0e h1:kqUd95SLY+StJ14/rJdFwurKword02z9oGxEcDJH7gg= +gitlab.com/gitlab-org/gitlab-shell v0.0.0-20200921044701-1a2bfecd2f0e/go.mod h1:RABblvnnhHpFU/lexlwGqpKgZsLV3RGA2D/Elp5/KEA= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200507062444-0149780c759d h1:Q5yZi+AelheHuvq/OK6DiaBzLU1AHrm7eWh88uE8Tsk= diff --git a/internal/gitaly/hook/access.go b/internal/gitaly/hook/access.go index 380f77001..07699147c 100644 --- a/internal/gitaly/hook/access.go +++ b/internal/gitaly/hook/access.go @@ -1,6 +1,7 @@ package hook import ( + "context" "encoding/json" "fmt" "io" @@ -54,11 +55,11 @@ func marshallGitObjectDirs(gitObjectDirRel string, gitAltObjectDirsRel []string) // GitlabAPI is an interface for accessing the gitlab internal API type GitlabAPI interface { // Allowed queries the gitlab internal api /allowed endpoint to determine if a ref change for a given repository and user is allowed - Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) + Allowed(ctx context.Context, repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) // PreReceive queries the gitlab internal api /pre_receive to increase the reference counter - PreReceive(glRepository string) (bool, error) + PreReceive(ctx context.Context, glRepository string) (bool, error) // PostReceive queries the gitlab internal api /post_receive to decrease the reference counter - PostReceive(glRepository, glID, changes string, pushOptions ...string) (bool, []PostReceiveMessage, error) + PostReceive(ctx context.Context, glRepository, glID, changes string, pushOptions ...string) (bool, []PostReceiveMessage, error) } // gitlabAPI is a wrapper around client.GitlabNetClient with API methods for gitlab git receive hooks @@ -102,7 +103,7 @@ func NewGitlabAPI(gitlabCfg config.Gitlab) (GitlabAPI, error) { } // Allowed checks if a ref change for a given repository is allowed through the gitlab internal api /allowed endpoint -func (a *gitlabAPI) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) { +func (a *gitlabAPI) Allowed(ctx context.Context, repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) { repoPath, err := helper.GetRepoPath(repo) if err != nil { return false, "", fmt.Errorf("getting the repository path: %w", err) @@ -126,7 +127,7 @@ func (a *gitlabAPI) Allowed(repo *gitalypb.Repository, glRepository, glID, glPro return false, "", fmt.Errorf("setting gl_id: %w", err) } - resp, err := a.client.Post("/allowed", &req) + resp, err := a.client.Post(ctx, "/allowed", &req) if err != nil { return false, "", err } @@ -166,8 +167,8 @@ type preReceiveResponse struct { } // PreReceive increases the reference counter for a push for a given gl_repository through the gitlab internal API /pre_receive endpoint -func (a *gitlabAPI) PreReceive(glRepository string) (bool, error) { - resp, err := a.client.Post("/pre_receive", map[string]string{"gl_repository": glRepository}) +func (a *gitlabAPI) PreReceive(ctx context.Context, glRepository string) (bool, error) { + resp, err := a.client.Post(ctx, "/pre_receive", map[string]string{"gl_repository": glRepository}) if err != nil { return false, fmt.Errorf("http post to gitlab api /pre_receive endpoint: %w", err) } @@ -212,8 +213,8 @@ type PostReceiveMessage struct { } // PostReceive decreases the reference counter for a push for a given gl_repository through the gitlab internal API /post_receive endpoint -func (a *gitlabAPI) PostReceive(glRepository, glID, changes string, pushOptions ...string) (bool, []PostReceiveMessage, error) { - resp, err := a.client.Post("/post_receive", map[string]interface{}{"gl_repository": glRepository, "identifier": glID, "changes": changes, "push_options": pushOptions}) +func (a *gitlabAPI) PostReceive(ctx context.Context, glRepository, glID, changes string, pushOptions ...string) (bool, []PostReceiveMessage, error) { + resp, err := a.client.Post(ctx, "/post_receive", map[string]interface{}{"gl_repository": glRepository, "identifier": glID, "changes": changes, "push_options": pushOptions}) if err != nil { return false, nil, fmt.Errorf("http post to gitlab api /post_receive endpoint: %w", err) } @@ -273,15 +274,15 @@ func (a *AllowedRequest) parseAndSetGLID(glID string) error { type mockAPI struct { } -func (m *mockAPI) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) { +func (m *mockAPI) Allowed(ctx context.Context, repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, string, error) { return true, "", nil } -func (m *mockAPI) PreReceive(glRepository string) (bool, error) { +func (m *mockAPI) PreReceive(ctx context.Context, glRepository string) (bool, error) { return true, nil } -func (m *mockAPI) PostReceive(glRepository, glID, changes string, gitPushOptions ...string) (bool, []PostReceiveMessage, error) { +func (m *mockAPI) PostReceive(ctx context.Context, glRepository, glID, changes string, gitPushOptions ...string) (bool, []PostReceiveMessage, error) { return true, nil, nil } diff --git a/internal/gitaly/hook/access_test.go b/internal/gitaly/hook/access_test.go index 06a8b9db3..deb17bfcb 100644 --- a/internal/gitaly/hook/access_test.go +++ b/internal/gitaly/hook/access_test.go @@ -1,6 +1,7 @@ package hook_test import ( + "context" "encoding/json" "net/http" "net/http/httptest" @@ -104,7 +105,7 @@ func TestAllowedVerifyParams(t *testing.T) { } for _, tc := range testCases { - allowed, _, err := c.Allowed(tc.repo, tc.glRepository, tc.glID, tc.protocol, tc.changes) + allowed, _, err := c.Allowed(context.Background(), tc.repo, tc.glRepository, tc.glID, tc.protocol, tc.changes) require.NoError(t, err) require.Equal(t, tc.allowed, allowed) } @@ -199,7 +200,7 @@ func TestEscapedAndRelativeURLs(t *testing.T) { }, }) require.NoError(t, err) - allowed, _, err := c.Allowed(testRepo, glRepository, glID, protocol, changes) + allowed, _, err := c.Allowed(context.Background(), testRepo, glRepository, glID, protocol, changes) require.NoError(t, err) require.True(t, allowed) }) @@ -332,7 +333,7 @@ func TestAllowedResponseHandling(t *testing.T) { }) require.NoError(t, err) - allowed, message, err := c.Allowed(testRepo, "repo-1", "key-123", "http", "a\nb\nc\nd") + allowed, message, err := c.Allowed(context.Background(), testRepo, "repo-1", "key-123", "http", "a\nb\nc\nd") require.Equal(t, tc.allowed, allowed) if err != nil { require.Contains(t, err.Error(), tc.errMsg) @@ -420,7 +421,7 @@ func TestPrereceive(t *testing.T) { }) require.NoError(t, err) - success, err := c.PreReceive("key-123") + success, err := c.PreReceive(context.Background(), "key-123") require.Equal(t, tc.success, success) if err != nil { require.Contains(t, err.Error(), tc.errMsg) @@ -499,7 +500,7 @@ func TestPostReceive(t *testing.T) { repositoryID := "project-123" identifier := "key-123" changes := "000 000 refs/heads/master" - success, _, err := c.PostReceive(repositoryID, identifier, changes, tc.pushOptions...) + success, _, err := c.PostReceive(context.Background(), repositoryID, identifier, changes, tc.pushOptions...) require.Equal(t, tc.success, success) if err != nil { require.Contains(t, err.Error(), tc.errMsg) diff --git a/internal/gitaly/hook/postreceive.go b/internal/gitaly/hook/postreceive.go index d67fd2ee7..fcd6def80 100644 --- a/internal/gitaly/hook/postreceive.go +++ b/internal/gitaly/hook/postreceive.go @@ -133,7 +133,7 @@ func (m *GitLabHookManager) PostReceiveHook(ctx context.Context, repo *gitalypb. glID, glRepo := getEnvVar("GL_ID", env), getEnvVar("GL_REPOSITORY", env) - ok, messages, err := m.gitlabAPI.PostReceive(glRepo, glID, string(changes), pushOptions...) + ok, messages, err := m.gitlabAPI.PostReceive(ctx, glRepo, glID, string(changes), pushOptions...) if err != nil { return fmt.Errorf("GitLab: %v", err) } diff --git a/internal/gitaly/hook/prereceive.go b/internal/gitaly/hook/prereceive.go index 441318aa7..4eeaec89a 100644 --- a/internal/gitaly/hook/prereceive.go +++ b/internal/gitaly/hook/prereceive.go @@ -70,7 +70,7 @@ func (m *GitLabHookManager) PreReceiveHook(ctx context.Context, repo *gitalypb.R // Only the primary should execute hooks and increment reference counters. if primary { - allowed, message, err := m.gitlabAPI.Allowed(repo, glRepo, glID, glProtocol, string(changes)) + allowed, message, err := m.gitlabAPI.Allowed(ctx, repo, glRepo, glID, glProtocol, string(changes)) if err != nil { return fmt.Errorf("GitLab: %v", err) } @@ -96,7 +96,7 @@ func (m *GitLabHookManager) PreReceiveHook(ctx context.Context, repo *gitalypb.R } // reference counter - ok, err := m.gitlabAPI.PreReceive(glRepo) + ok, err := m.gitlabAPI.PreReceive(ctx, glRepo) if err != nil { return helper.ErrInternalf("calling pre_receive endpoint: %v", err) } |