diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2020-12-02 16:57:02 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2020-12-03 16:28:43 +0300 |
commit | c840f15dccaff1498ab7dadae47af48470df0566 (patch) | |
tree | e315f2d3c94c4a0a6be2a20cd3209f9228848b77 | |
parent | 807efa20454da3210f8d1fc59da97816e5635d25 (diff) |
hooks: Setup and use payload
While the preceding commit implemented the new HooksPayload structure
which is going to contain all Gitaly-relevant parameters eventually, it
didn't yet set up the environments. This commit here thus starts
injecting the payload into the hooks' environment.
As the payload has a fallback to use the now-deprecated environment
variables GITALY_REPO and the likes, we can also go all-in and directly
start to use theh payload returned by `HooksPayloadFromEnv()`. If we
don't have a payload injected but got those old envvars, it would work
fine regardless.
-rw-r--r-- | cmd/gitaly-hooks/hooks.go | 48 | ||||
-rw-r--r-- | cmd/gitaly-hooks/hooks_test.go | 5 | ||||
-rw-r--r-- | internal/git/hooks.go | 6 | ||||
-rw-r--r-- | internal/git/hooks_test.go | 1 | ||||
-rw-r--r-- | internal/gitaly/service/operations/update_with_hooks.go | 6 | ||||
-rw-r--r-- | ruby/lib/gitlab/git/hook.rb | 10 |
6 files changed, 40 insertions, 36 deletions
diff --git a/cmd/gitaly-hooks/hooks.go b/cmd/gitaly-hooks/hooks.go index 8d7504138..fb36734cf 100644 --- a/cmd/gitaly-hooks/hooks.go +++ b/cmd/gitaly-hooks/hooks.go @@ -10,11 +10,11 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/jsonpb" "github.com/sirupsen/logrus" gitalyauth "gitlab.com/gitlab-org/gitaly/auth" "gitlab.com/gitlab-org/gitaly/client" "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/gitaly/hook" gitalylog "gitlab.com/gitlab-org/gitaly/internal/log" @@ -69,12 +69,12 @@ func main() { ctx, finished := tracing.ExtractFromEnv(ctx) defer finished() - repository, err := repositoryFromEnv() + payload, err := git.HooksPayloadFromEnv(os.Environ()) if err != nil { - logger.Fatalf("error when getting repository: %v", err) + logger.Fatalf("error when getting hooks payload: %v", err) } - conn, err := gitalyFromEnv() + conn, err := dialGitaly(payload) if err != nil { logger.Fatalf("error when connecting to gitaly: %v", err) } @@ -92,7 +92,7 @@ func main() { ref, oldValue, newValue := args[0], args[1], args[2] req := &gitalypb.UpdateHookRequest{ - Repository: repository, + Repository: payload.Repo, EnvironmentVariables: glValues(), Ref: []byte(ref), OldValue: oldValue, @@ -124,7 +124,7 @@ func main() { } if err := preReceiveHookStream.Send(&gitalypb.PreReceiveHookRequest{ - Repository: repository, + Repository: payload.Repo, EnvironmentVariables: environment, GitPushOptions: gitPushOptions(), }); err != nil { @@ -156,7 +156,7 @@ func main() { } if err := postReceiveHookStream.Send(&gitalypb.PostReceiveHookRequest{ - Repository: repository, + Repository: payload.Repo, EnvironmentVariables: environment, GitPushOptions: gitPushOptions(), }); err != nil { @@ -208,7 +208,7 @@ func main() { } if err := referenceTransactionHookStream.Send(&gitalypb.ReferenceTransactionHookRequest{ - Repository: repository, + Repository: payload.Repo, EnvironmentVariables: environment, State: state, }); err != nil { @@ -233,37 +233,13 @@ func main() { func noopSender(c chan error) {} -func repositoryFromEnv() (*gitalypb.Repository, error) { - repoString, ok := os.LookupEnv("GITALY_REPO") - if !ok { - return nil, errors.New("GITALY_REPO not found") - } - - var repo gitalypb.Repository - if err := jsonpb.UnmarshalString(repoString, &repo); err != nil { - return nil, fmt.Errorf("unmarshal JSON %q: %w", repoString, err) - } - - return &repo, nil -} - -func gitalyFromEnv() (*grpc.ClientConn, error) { - gitalySocket := os.Getenv("GITALY_SOCKET") - if gitalySocket == "" { - return nil, errors.New("GITALY_SOCKET not set") - } - - gitalyToken, ok := os.LookupEnv("GITALY_TOKEN") - if !ok { - return nil, errors.New("GITALY_TOKEN not set") - } - +func dialGitaly(payload git.HooksPayload) (*grpc.ClientConn, error) { dialOpts := client.DefaultDialOpts - if gitalyToken != "" { - dialOpts = append(dialOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(gitalyToken))) + if payload.InternalSocketToken != "" { + dialOpts = append(dialOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(payload.InternalSocketToken))) } - conn, err := client.Dial("unix://"+gitalySocket, dialOpts) + conn, err := client.Dial("unix://"+payload.InternalSocket, dialOpts) if err != nil { return nil, fmt.Errorf("error when dialing: %w", err) } diff --git a/cmd/gitaly-hooks/hooks_test.go b/cmd/gitaly-hooks/hooks_test.go index 221607876..d4a0a9907 100644 --- a/cmd/gitaly-hooks/hooks_test.go +++ b/cmd/gitaly-hooks/hooks_test.go @@ -17,6 +17,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/hooks" "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" gitalyhook "gitlab.com/gitlab-org/gitaly/internal/gitaly/hook" @@ -51,8 +52,12 @@ func envForHooks(t testing.TB, gitlabShellDir string, repo *gitalypb.Repository, env, err := gitlabshell.EnvFromConfig(config.Config) require.NoError(t, err) + payload, err := git.NewHooksPayload(config.Config, repo).Env() + require.NoError(t, err) + env = append(env, os.Environ()...) env = append(env, []string{ + payload, fmt.Sprintf("GITALY_RUBY_DIR=%s", rubyDir), fmt.Sprintf("GL_ID=%s", glHookValues.GLID), fmt.Sprintf("GL_REPOSITORY=%s", glHookValues.GLRepo), diff --git a/internal/git/hooks.go b/internal/git/hooks.go index 5b2b7a4c8..27b1ea354 100644 --- a/internal/git/hooks.go +++ b/internal/git/hooks.go @@ -195,7 +195,13 @@ func refHookEnv(ctx context.Context, repo *gitalypb.Repository, cfg config.Cfg) return nil, err } + payload, err := NewHooksPayload(cfg, repo).Env() + if err != nil { + return nil, err + } + return []string{ + payload, "GITALY_BIN_DIR=" + cfg.BinDir, "GITALY_SOCKET=" + cfg.GitalyInternalSocketPath(), fmt.Sprintf("GITALY_REPO=%s", repoJSON), diff --git a/internal/git/hooks_test.go b/internal/git/hooks_test.go index 35c7645cf..ca3a79efb 100644 --- a/internal/git/hooks_test.go +++ b/internal/git/hooks_test.go @@ -68,6 +68,7 @@ func TestWithRefHook(t *testing.T) { } require.EqualValues(t, []string{ + "GITALY_HOOKS_PAYLOAD", "GITALY_BIN_DIR", "GITALY_SOCKET", "GITALY_REPO", diff --git a/internal/gitaly/service/operations/update_with_hooks.go b/internal/gitaly/service/operations/update_with_hooks.go index 5b9dec0cc..eae2c05b2 100644 --- a/internal/gitaly/service/operations/update_with_hooks.go +++ b/internal/gitaly/service/operations/update_with_hooks.go @@ -38,6 +38,11 @@ func (s *Server) updateReferenceWithHooks(ctx context.Context, repo *gitalypb.Re return err } + payload, err := git.NewHooksPayload(s.cfg, repo).Env() + if err != nil { + return err + } + if reference == "" { return helper.ErrInternalf("updateReferenceWithHooks: got no reference") } @@ -49,6 +54,7 @@ func (s *Server) updateReferenceWithHooks(ctx context.Context, repo *gitalypb.Re } env := append([]string{ + payload, "GL_PROTOCOL=web", fmt.Sprintf("GL_ID=%s", user.GetGlId()), fmt.Sprintf("GL_USERNAME=%s", user.GetGlUsername()), diff --git a/ruby/lib/gitlab/git/hook.rb b/ruby/lib/gitlab/git/hook.rb index 271dc419e..695433960 100644 --- a/ruby/lib/gitlab/git/hook.rb +++ b/ruby/lib/gitlab/git/hook.rb @@ -115,8 +115,18 @@ module Gitlab err_message end + def hooks_payload + Base64.strict_encode64({ + repository: repository.gitaly_repository.to_json, + binary_directory: Gitlab.config.gitaly.bin_dir, + internal_socket: Gitlab.config.gitaly.internal_socket, + internal_socket_token: ENV['GITALY_TOKEN'] + }.to_json) + end + def env_base_vars(gl_id, gl_username) { + 'GITALY_HOOKS_PAYLOAD' => hooks_payload, 'GITALY_GITLAB_SHELL_DIR' => Gitlab.config.gitlab_shell.path, 'GITLAB_SHELL_DIR' => Gitlab.config.gitlab_shell.path, 'GITALY_LOG_DIR' => Gitlab.config.logging.dir, |