1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package git
import (
"context"
"errors"
"fmt"
"gitlab.com/gitlab-org/gitaly/internal/git/hooks"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/internal/log"
"gitlab.com/gitlab-org/gitaly/internal/praefect/metadata"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
)
// WithRefTxHook returns an option that populates the safe command with the
// environment variables necessary to properly execute a reference hook for
// repository changes that may possibly update references
func WithRefTxHook(ctx context.Context, repo *gitalypb.Repository, cfg config.Cfg) CmdOpt {
return func(cc *cmdCfg) error {
if repo == nil {
return fmt.Errorf("missing repo: %w", ErrInvalidArg)
}
if err := cc.configureHooks(ctx, repo, cfg, nil); err != nil {
return fmt.Errorf("ref hook env var: %w", err)
}
return nil
}
}
// configureHooks updates the command configuration to include all environment
// variables required by the reference transaction hook and any other needed
// options to successfully execute hooks.
func (cc *cmdCfg) configureHooks(
ctx context.Context,
repo *gitalypb.Repository,
cfg config.Cfg,
receiveHooksPayload *ReceiveHooksPayload,
) error {
if cc.hooksConfigured {
return errors.New("hooks already configured")
}
transaction, praefect, err := metadata.TransactionMetadataFromContext(ctx)
if err != nil {
return err
}
payload, err := NewHooksPayload(cfg, repo, transaction, praefect, receiveHooksPayload).Env()
if err != nil {
return err
}
cc.env = append(
cc.env,
payload,
"GITALY_BIN_DIR="+cfg.BinDir,
fmt.Sprintf("%s=%s", log.GitalyLogDirEnvKey, cfg.Logging.Dir),
)
cc.globals = append(cc.globals, ValueFlag{"-c", fmt.Sprintf("core.hooksPath=%s", hooks.Path(cfg))})
cc.hooksConfigured = true
return nil
}
// ReceivePackRequest abstracts away the different requests that end up
// spawning git-receive-pack.
type ReceivePackRequest interface {
GetGlId() string
GetGlUsername() string
GetGlRepository() string
GetRepository() *gitalypb.Repository
}
// WithReceivePackHooks returns an option that populates the safe command with the environment
// variables necessary to properly execute the pre-receive, update and post-receive hooks for
// git-receive-pack(1).
func WithReceivePackHooks(ctx context.Context, cfg config.Cfg, req ReceivePackRequest, protocol string) CmdOpt {
return func(cc *cmdCfg) error {
if err := cc.configureHooks(ctx, req.GetRepository(), config.Config, &ReceiveHooksPayload{
UserID: req.GetGlId(),
Username: req.GetGlUsername(),
Protocol: protocol,
}); err != nil {
return err
}
return nil
}
}
|