diff --git a/_support/makegen.go b/_support/makegen.go index 91f1814ff5c598864d6fbe00ad48c65b42707362..bb4b79b1ea921a7455e801f680e5067783066596 100644 --- a/_support/makegen.go +++ b/_support/makegen.go @@ -144,7 +144,7 @@ func (gm *gitalyMake) CommandPackages() []string { for _, dir := range entries { //Do not build gitaly-remote by default - if dir.Name() == "gitaly-remote" { + if dir.Name() == "gitaly-remote" || dir.Name() == "hooks" { continue } if !dir.IsDir() { diff --git a/cmd/hooks/hooks.go b/cmd/hooks/hooks.go new file mode 100644 index 0000000000000000000000000000000000000000..5f00d720e773b998d639b39c0099d891a25f19ee --- /dev/null +++ b/cmd/hooks/hooks.go @@ -0,0 +1,22 @@ +package hooks + +import ( + "bufio" + "io" +) + +// ReadRefs reads a list of newline delimeted refs from a reader +func ReadRefs(r io.Reader) ([]string, error) { + s := bufio.NewScanner(r) + + var refs []string + for s.Scan() { + refs = append(refs, s.Text()) + } + + if err := s.Err(); err != nil { + return nil, err + } + + return refs, nil +} diff --git a/cmd/hooks/postreceive/postceive.go b/cmd/hooks/postreceive/postceive.go new file mode 100644 index 0000000000000000000000000000000000000000..b861f3e3781856150c20ccb0bc3e91f5732e0797 --- /dev/null +++ b/cmd/hooks/postreceive/postceive.go @@ -0,0 +1,68 @@ +package main + +import ( + "context" + "log" + "os" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + gitalyauth "gitlab.com/gitlab-org/gitaly/auth" + "gitlab.com/gitlab-org/gitaly/client" + "gitlab.com/gitlab-org/gitaly/cmd/hooks" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + "google.golang.org/grpc" +) + +func main() { + refs, err := hooks.ReadRefs(os.Stdin) + if err != nil { + log.Fatalf("error when reading refs: %v", err) + } + keyID := os.Getenv("GL_ID") + repoPath, err := os.Getwd() + if err != nil { + log.Fatalf("error when getting pwd: %v", err) + } + glRepository := os.Getenv("GL_REPOSITORY") + url := os.Getenv("GL_URL") + + conn, err := client.Dial(url, dialOpts()) + if err != nil { + log.Fatalf("error when dialing: %v", err) + } + + c := gitalypb.NewHookServiceClient(conn) + + if _, err = c.PostReceive(context.Background(), &gitalypb.PostReceiveHookRequest{ + RepoPath: repoPath, + KeyId: keyID, + GlRepository: glRepository, + Refs: refs, + }); err != nil { + log.Fatalf("error when calling pre receive hook: %v", err) + } +} + +func dialOpts() []grpc.DialOption { + connOpts := client.DefaultDialOpts + if token := os.Getenv("GITALY_TOKEN"); token != "" { + connOpts = append(connOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentials(token))) + } + + // Add grpc client interceptors + connOpts = append(connOpts, grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), // Tracing + grpccorrelation.StreamClientCorrelationInterceptor(), // Correlation + )), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), // Tracing + grpccorrelation.UnaryClientCorrelationInterceptor(), // Correlation + ))) + + return connOpts +} diff --git a/cmd/hooks/prereceive/preceive.go b/cmd/hooks/prereceive/preceive.go new file mode 100644 index 0000000000000000000000000000000000000000..f05d7e9726b20648a8129a63d215ba113b04bf26 --- /dev/null +++ b/cmd/hooks/prereceive/preceive.go @@ -0,0 +1,70 @@ +package main + +import ( + "context" + "log" + "os" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + gitalyauth "gitlab.com/gitlab-org/gitaly/auth" + "gitlab.com/gitlab-org/gitaly/client" + "gitlab.com/gitlab-org/gitaly/cmd/hooks" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + "google.golang.org/grpc" +) + +func main() { + refs, err := hooks.ReadRefs(os.Stdin) + if err != nil { + log.Fatalf("error when reading refs: %v", err) + } + keyID := os.Getenv("GL_ID") + protocol := os.Getenv("GL_PROTOCOL") + repoPath, err := os.Getwd() + if err != nil { + log.Fatalf("error when getting pwd: %v", err) + } + glRepository := os.Getenv("GL_REPOSITORY") + url := os.Getenv("GL_URL") + + conn, err := client.Dial(url, dialOpts()) + if err != nil { + log.Fatalf("error when dialing: %v", err) + } + + c := gitalypb.NewHookServiceClient(conn) + + if _, err = c.PreReceive(context.Background(), &gitalypb.PreReceiveHookRequest{ + GlRepository: glRepository, + RepoPath: repoPath, + KeyId: keyID, + Protocol: protocol, + Refs: refs, + }); err != nil { + log.Fatalf("error when calling pre receive hook: %v", err) + } +} + +func dialOpts() []grpc.DialOption { + connOpts := client.DefaultDialOpts + if token := os.Getenv("GITALY_TOKEN"); token != "" { + connOpts = append(connOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentials(token))) + } + + // Add grpc client interceptors + connOpts = append(connOpts, grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), // Tracing + grpccorrelation.StreamClientCorrelationInterceptor(), // Correlation + )), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), // Tracing + grpccorrelation.UnaryClientCorrelationInterceptor(), // Correlation + ))) + + return connOpts +} diff --git a/cmd/hooks/update/update.go b/cmd/hooks/update/update.go new file mode 100644 index 0000000000000000000000000000000000000000..d40c7604d0cafad34a68a50079c547951c0deed1 --- /dev/null +++ b/cmd/hooks/update/update.go @@ -0,0 +1,70 @@ +package main + +import ( + "context" + "log" + "os" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + gitalyauth "gitlab.com/gitlab-org/gitaly/auth" + "gitlab.com/gitlab-org/gitaly/client" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + "google.golang.org/grpc" +) + +func main() { + keyID := os.Getenv("GL_ID") + repoPath, err := os.Getwd() + if err != nil { + log.Fatalf("error when getting pwd: %v", err) + } + + if len(os.Args) < 4 { + log.Fatalf("only found %d arguments, 3 required", len(os.Args)-1) + } + + refName, oldVal, newVal := os.Args[1], os.Args[2], os.Args[3] + + url := os.Getenv("GL_URL") + + conn, err := client.Dial(url, dialOpts()) + if err != nil { + log.Fatalf("error when dialing: %v", err) + } + + c := gitalypb.NewHookServiceClient(conn) + + if _, err = c.Update(context.Background(), &gitalypb.UpdateHookRequest{ + RepoPath: repoPath, + KeyId: keyID, + Ref: refName, + OldValue: oldVal, + NewValue: newVal, + }); err != nil { + log.Fatalf("error when calling pre receive hook: %v", err) + } +} + +func dialOpts() []grpc.DialOption { + connOpts := client.DefaultDialOpts + if token := os.Getenv("GITALY_TOKEN"); token != "" { + connOpts = append(connOpts, grpc.WithPerRPCCredentials(gitalyauth.RPCCredentials(token))) + } + + // Add grpc client interceptors + connOpts = append(connOpts, grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), // Tracing + grpccorrelation.StreamClientCorrelationInterceptor(), // Correlation + )), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), // Tracing + grpccorrelation.UnaryClientCorrelationInterceptor(), // Correlation + ))) + + return connOpts +} diff --git a/go.mod b/go.mod index 6cd6efcec29dc37260e2e68acad1324d38a59e78..a2e728d26c43e40fc3bc609a72215d1880f4800a 100644 --- a/go.mod +++ b/go.mod @@ -9,19 +9,16 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/kelseyhightower/envconfig v1.3.0 - github.com/kr/pretty v0.1.0 // indirect github.com/libgit2/git2go v0.0.0-20190104134018-ecaeb7a21d47 github.com/prometheus/client_golang v1.0.0 github.com/sirupsen/logrus v1.2.0 github.com/stretchr/testify v1.3.0 github.com/tinylib/msgp v1.1.0 // indirect gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c - golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 // indirect - golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 + golang.org/x/net v0.0.0-20190620200207-3b0461eec859 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 golang.org/x/sys v0.0.0-20190422165155-953cdadca894 google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898 // indirect - google.golang.org/grpc v1.16.0 - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + google.golang.org/grpc v1.21.1 gopkg.in/yaml.v2 v2.2.2 // indirect ) diff --git a/go.sum b/go.sum index 9bce6f0955bec582ddd419e0284d02b5b56b8822..641653ecc0b84be4191fc13d092f98261bacc8b9 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= @@ -51,11 +52,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/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= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/lightstep/lightstep-tracer-go v0.15.6 h1:D0GGa7afJ7GcQvu5as6ssLEEKYXvRgKI5d5cevtz8r4= @@ -115,16 +111,16 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= @@ -138,12 +134,12 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -151,13 +147,13 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898 h1:yvw+zsSmSM02Z5H google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/grpc v1.16.0 h1:dz5IJGuC2BB7qXR5AyHNwAUBhZscK2xVez7mznh72sY= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/DataDog/dd-trace-go.v1 v1.7.0 h1:7wbMayb6JXcbAS95RN7MI42W3o1BCxCcdIzZfVWBAiE= gopkg.in/DataDog/dd-trace-go.v1 v1.7.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -166,3 +162,4 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/git/hooks/hooks.go b/internal/git/hooks/hooks.go index c77c3ed1e373ba8f7f080901f2b0d7492c1b9f2e..94426b8bd52f212b9798831e4cd4bc153f987b1b 100644 --- a/internal/git/hooks/hooks.go +++ b/internal/git/hooks/hooks.go @@ -25,3 +25,16 @@ func Path() string { return path.Join(config.Config.Ruby.Dir, "git-hooks") } + +// GitPath returns the path where the go implemeneted global git hooks are located +func GitPath() string { + if len(Override) > 0 { + return Override + } + + if os.Getenv("GITALY_TESTING_NO_GIT_HOOKS") == "1" { + return "/var/empty" + } + + return path.Join(config.Config.BinDir, "hooks") +} diff --git a/internal/rubyserver/rubyserver.go b/internal/rubyserver/rubyserver.go index 4b031762a1447d9d4a6a59c23f045e5a1361bc88..37bec65513aa291cc3812df437743763dbbbea81 100644 --- a/internal/rubyserver/rubyserver.go +++ b/internal/rubyserver/rubyserver.go @@ -111,7 +111,8 @@ func Start() (*Server, error) { fmt.Sprintf("GITALY_RUBY_MAX_COMMIT_OR_TAG_MESSAGE_SIZE=%d", helper.MaxCommitOrTagMessageSize), "GITALY_RUBY_GITALY_BIN_DIR="+cfg.BinDir, "GITALY_VERSION="+version.GetVersion(), - "GITALY_GIT_HOOKS_DIR="+hooks.Path()) + "GITALY_GIT_HOOKS_DIR="+hooks.GitPath(), + ) env = append(env, gitlabshell.Env()...) env = append(env, command.GitEnv...) diff --git a/internal/service/hook/post_receive.go b/internal/service/hook/post_receive.go new file mode 100644 index 0000000000000000000000000000000000000000..09f94ea71e888b896e6a6d795f276d04f1047221 --- /dev/null +++ b/internal/service/hook/post_receive.go @@ -0,0 +1,39 @@ +package hook + +import ( + "bytes" + "context" + "fmt" + "os/exec" + + "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/git/hooks" + "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" +) + +func (s *server) PostReceive(ctx context.Context, in *gitalypb.PostReceiveHookRequest) (*gitalypb.PostReceiveHookResponse, error) { + postreceiveHook := fmt.Sprintf("%s/post-receive", hooks.Path()) + + var stdin bytes.Buffer + for _, ref := range in.GetRefs() { + stdin.WriteString(fmt.Sprintf("%s\n", ref)) + } + + env := []string{ + fmt.Sprintf("GL_REPO_PATH=%s", in.GetRepoPath()), + fmt.Sprintf("GL_ID=%s", in.GetKeyId()), + fmt.Sprintf("GL_REPOSITORY=%s", in.GetGlRepository()), + } + + cmd, err := command.New(ctx, exec.Command(postreceiveHook), &stdin, nil, nil, env...) + if err != nil { + return &gitalypb.PostReceiveHookResponse{}, helper.ErrInternal(err) + } + + if err := cmd.Wait(); err != nil { + return &gitalypb.PostReceiveHookResponse{}, helper.ErrInternal(err) + } + + return &gitalypb.PostReceiveHookResponse{}, nil +} diff --git a/internal/service/hook/pre_receive.go b/internal/service/hook/pre_receive.go new file mode 100644 index 0000000000000000000000000000000000000000..671d15124f8d714ab202b6bef43a39dee7b0e15b --- /dev/null +++ b/internal/service/hook/pre_receive.go @@ -0,0 +1,40 @@ +package hook + +import ( + "bytes" + "context" + "fmt" + "os/exec" + + "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/git/hooks" + "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" +) + +func (s *server) PreReceive(ctx context.Context, in *gitalypb.PreReceiveHookRequest) (*gitalypb.PreReceiveHookResponse, error) { + prereceiveHook := fmt.Sprintf("%s/pre-receive", hooks.Path()) + + var stdin bytes.Buffer + for _, ref := range in.GetRefs() { + stdin.WriteString(fmt.Sprintf("%s\n", ref)) + } + + env := []string{ + fmt.Sprintf("GL_ID=%s", in.GetKeyId()), + fmt.Sprintf("GL_PROTOCOL=%s", in.GetProtocol()), + fmt.Sprintf("GL_REPO_PATH=%s", in.GetRepoPath()), + fmt.Sprintf("GL_REPOSITORY=%s", in.GetGlRepository()), + } + + cmd, err := command.New(ctx, exec.Command(prereceiveHook), &stdin, nil, nil, env...) + if err != nil { + return &gitalypb.PreReceiveHookResponse{}, helper.ErrInternal(err) + } + + if err := cmd.Wait(); err != nil { + return &gitalypb.PreReceiveHookResponse{}, helper.ErrInternal(err) + } + + return &gitalypb.PreReceiveHookResponse{}, nil +} diff --git a/internal/service/hook/server.go b/internal/service/hook/server.go new file mode 100644 index 0000000000000000000000000000000000000000..1977af1df5ba28ab72b653fc63e468c5f702f2eb --- /dev/null +++ b/internal/service/hook/server.go @@ -0,0 +1,10 @@ +package hook + +import "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + +type server struct{} + +// NewServer creates a new instance of a gRPC namespace server +func NewServer() gitalypb.HookServiceServer { + return &server{} +} diff --git a/internal/service/hook/update.go b/internal/service/hook/update.go new file mode 100644 index 0000000000000000000000000000000000000000..e080b66b4b9120b69685d2c7e49106ffa89a240f --- /dev/null +++ b/internal/service/hook/update.go @@ -0,0 +1,32 @@ +package hook + +import ( + "context" + "fmt" + "os/exec" + + "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/git/hooks" + "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" +) + +func (s *server) Update(ctx context.Context, in *gitalypb.UpdateHookRequest) (*gitalypb.UpdateHookResponse, error) { + updateHook := fmt.Sprintf("%s/pre-receive", hooks.Path()) + + env := []string{ + fmt.Sprintf("GL_ID=%s", in.GetKeyId()), + fmt.Sprintf("GL_REPO_PATH=%s", in.GetRepoPath()), + } + + cmd, err := command.New(ctx, exec.Command(updateHook, in.GetRef(), in.GetOldValue(), in.GetNewValue()), nil, nil, nil, env...) + if err != nil { + return &gitalypb.UpdateHookResponse{}, helper.ErrInternal(err) + } + + if err := cmd.Wait(); err != nil { + return &gitalypb.UpdateHookResponse{}, helper.ErrInternal(err) + } + + return &gitalypb.UpdateHookResponse{}, nil +} diff --git a/internal/service/smarthttp/receive_pack.go b/internal/service/smarthttp/receive_pack.go index 4014d4ad8aa16c8975928ef657387ce1198ee98f..8b02aecbf8b4500beb3181b7e3a9ff920951fa5c 100644 --- a/internal/service/smarthttp/receive_pack.go +++ b/internal/service/smarthttp/receive_pack.go @@ -1,9 +1,12 @@ package smarthttp import ( + "fmt" + grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" @@ -38,7 +41,7 @@ func (s *server) PostReceivePack(stream gitalypb.SmartHTTPService_PostReceivePac return stream.Send(&gitalypb.PostReceivePackResponse{Data: p}) }) - env := append(git.HookEnv(req), "GL_PROTOCOL=http") + env := append(git.HookEnv(req), "GL_PROTOCOL=http", fmt.Sprintf("GL_URL=%s", config.Config.SocketPath)) repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { diff --git a/internal/service/ssh/receive_pack.go b/internal/service/ssh/receive_pack.go index 170a28b5ca61f433494efbedfc04467356c78a62..610ebb1aa053cad953275306245217f4854b5888 100644 --- a/internal/service/ssh/receive_pack.go +++ b/internal/service/ssh/receive_pack.go @@ -6,6 +6,7 @@ import ( grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly/internal/command" + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" @@ -50,8 +51,7 @@ func sshReceivePack(stream gitalypb.SSHService_SSHReceivePackServer, req *gitaly return stream.Send(&gitalypb.SSHReceivePackResponse{Stderr: p}) }) - env := append(git.HookEnv(req), "GL_PROTOCOL=ssh") - + env := append(git.HookEnv(req), "GL_PROTOCOL=ssh", fmt.Sprintf("GL_URL=%s", config.Config.SocketPath)) repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { return err diff --git a/proto/go/gitalypb/hook.pb.go b/proto/go/gitalypb/hook.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..3c5e33c714b85f7e5efde920c7062ac28ad902bb --- /dev/null +++ b/proto/go/gitalypb/hook.pb.go @@ -0,0 +1,498 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: hook.proto + +package gitalypb + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type PreReceiveHookRequest struct { + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + Protocol string `protobuf:"bytes,3,opt,name=protocol,proto3" json:"protocol,omitempty"` + Refs []string `protobuf:"bytes,4,rep,name=refs,proto3" json:"refs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PreReceiveHookRequest) Reset() { *m = PreReceiveHookRequest{} } +func (m *PreReceiveHookRequest) String() string { return proto.CompactTextString(m) } +func (*PreReceiveHookRequest) ProtoMessage() {} +func (*PreReceiveHookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{0} +} + +func (m *PreReceiveHookRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PreReceiveHookRequest.Unmarshal(m, b) +} +func (m *PreReceiveHookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PreReceiveHookRequest.Marshal(b, m, deterministic) +} +func (m *PreReceiveHookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PreReceiveHookRequest.Merge(m, src) +} +func (m *PreReceiveHookRequest) XXX_Size() int { + return xxx_messageInfo_PreReceiveHookRequest.Size(m) +} +func (m *PreReceiveHookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PreReceiveHookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PreReceiveHookRequest proto.InternalMessageInfo + +func (m *PreReceiveHookRequest) GetRepository() *Repository { + if m != nil { + return m.Repository + } + return nil +} + +func (m *PreReceiveHookRequest) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *PreReceiveHookRequest) GetProtocol() string { + if m != nil { + return m.Protocol + } + return "" +} + +func (m *PreReceiveHookRequest) GetRefs() []string { + if m != nil { + return m.Refs + } + return nil +} + +type PreReceiveHookResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PreReceiveHookResponse) Reset() { *m = PreReceiveHookResponse{} } +func (m *PreReceiveHookResponse) String() string { return proto.CompactTextString(m) } +func (*PreReceiveHookResponse) ProtoMessage() {} +func (*PreReceiveHookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{1} +} + +func (m *PreReceiveHookResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PreReceiveHookResponse.Unmarshal(m, b) +} +func (m *PreReceiveHookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PreReceiveHookResponse.Marshal(b, m, deterministic) +} +func (m *PreReceiveHookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PreReceiveHookResponse.Merge(m, src) +} +func (m *PreReceiveHookResponse) XXX_Size() int { + return xxx_messageInfo_PreReceiveHookResponse.Size(m) +} +func (m *PreReceiveHookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PreReceiveHookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PreReceiveHookResponse proto.InternalMessageInfo + +type PostReceiveHookRequest struct { + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + Refs []string `protobuf:"bytes,3,rep,name=refs,proto3" json:"refs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PostReceiveHookRequest) Reset() { *m = PostReceiveHookRequest{} } +func (m *PostReceiveHookRequest) String() string { return proto.CompactTextString(m) } +func (*PostReceiveHookRequest) ProtoMessage() {} +func (*PostReceiveHookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{2} +} + +func (m *PostReceiveHookRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PostReceiveHookRequest.Unmarshal(m, b) +} +func (m *PostReceiveHookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PostReceiveHookRequest.Marshal(b, m, deterministic) +} +func (m *PostReceiveHookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PostReceiveHookRequest.Merge(m, src) +} +func (m *PostReceiveHookRequest) XXX_Size() int { + return xxx_messageInfo_PostReceiveHookRequest.Size(m) +} +func (m *PostReceiveHookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PostReceiveHookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PostReceiveHookRequest proto.InternalMessageInfo + +func (m *PostReceiveHookRequest) GetRepository() *Repository { + if m != nil { + return m.Repository + } + return nil +} + +func (m *PostReceiveHookRequest) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *PostReceiveHookRequest) GetRefs() []string { + if m != nil { + return m.Refs + } + return nil +} + +type PostReceiveHookResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PostReceiveHookResponse) Reset() { *m = PostReceiveHookResponse{} } +func (m *PostReceiveHookResponse) String() string { return proto.CompactTextString(m) } +func (*PostReceiveHookResponse) ProtoMessage() {} +func (*PostReceiveHookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{3} +} + +func (m *PostReceiveHookResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PostReceiveHookResponse.Unmarshal(m, b) +} +func (m *PostReceiveHookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PostReceiveHookResponse.Marshal(b, m, deterministic) +} +func (m *PostReceiveHookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PostReceiveHookResponse.Merge(m, src) +} +func (m *PostReceiveHookResponse) XXX_Size() int { + return xxx_messageInfo_PostReceiveHookResponse.Size(m) +} +func (m *PostReceiveHookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PostReceiveHookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PostReceiveHookResponse proto.InternalMessageInfo + +type UpdateHookRequest struct { + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + Ref string `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"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpdateHookRequest) Reset() { *m = UpdateHookRequest{} } +func (m *UpdateHookRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateHookRequest) ProtoMessage() {} +func (*UpdateHookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{4} +} + +func (m *UpdateHookRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UpdateHookRequest.Unmarshal(m, b) +} +func (m *UpdateHookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UpdateHookRequest.Marshal(b, m, deterministic) +} +func (m *UpdateHookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateHookRequest.Merge(m, src) +} +func (m *UpdateHookRequest) XXX_Size() int { + return xxx_messageInfo_UpdateHookRequest.Size(m) +} +func (m *UpdateHookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_UpdateHookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_UpdateHookRequest proto.InternalMessageInfo + +func (m *UpdateHookRequest) GetRepository() *Repository { + if m != nil { + return m.Repository + } + return nil +} + +func (m *UpdateHookRequest) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *UpdateHookRequest) GetRef() string { + if m != nil { + return m.Ref + } + return "" +} + +func (m *UpdateHookRequest) GetOldValue() string { + if m != nil { + return m.OldValue + } + return "" +} + +func (m *UpdateHookRequest) GetNewValue() string { + if m != nil { + return m.NewValue + } + return "" +} + +type UpdateHookResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpdateHookResponse) Reset() { *m = UpdateHookResponse{} } +func (m *UpdateHookResponse) String() string { return proto.CompactTextString(m) } +func (*UpdateHookResponse) ProtoMessage() {} +func (*UpdateHookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_3eef30da1c11ee1b, []int{5} +} + +func (m *UpdateHookResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UpdateHookResponse.Unmarshal(m, b) +} +func (m *UpdateHookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UpdateHookResponse.Marshal(b, m, deterministic) +} +func (m *UpdateHookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateHookResponse.Merge(m, src) +} +func (m *UpdateHookResponse) XXX_Size() int { + return xxx_messageInfo_UpdateHookResponse.Size(m) +} +func (m *UpdateHookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_UpdateHookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_UpdateHookResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*PreReceiveHookRequest)(nil), "gitaly.PreReceiveHookRequest") + proto.RegisterType((*PreReceiveHookResponse)(nil), "gitaly.PreReceiveHookResponse") + proto.RegisterType((*PostReceiveHookRequest)(nil), "gitaly.PostReceiveHookRequest") + proto.RegisterType((*PostReceiveHookResponse)(nil), "gitaly.PostReceiveHookResponse") + proto.RegisterType((*UpdateHookRequest)(nil), "gitaly.UpdateHookRequest") + proto.RegisterType((*UpdateHookResponse)(nil), "gitaly.UpdateHookResponse") +} + +func init() { proto.RegisterFile("hook.proto", fileDescriptor_3eef30da1c11ee1b) } + +var fileDescriptor_3eef30da1c11ee1b = []byte{ + // 373 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x92, 0x41, 0x6f, 0xa2, 0x50, + 0x10, 0xc7, 0x83, 0x28, 0x91, 0x71, 0x0f, 0xbb, 0x2f, 0xab, 0x8b, 0x6c, 0x76, 0x6b, 0x38, 0x71, + 0x29, 0xb4, 0xf6, 0x1b, 0xf4, 0xd4, 0xf6, 0x64, 0x68, 0x6a, 0xd2, 0x5e, 0x0c, 0xc2, 0xa8, 0x04, + 0xea, 0xd0, 0x07, 0x6a, 0xf8, 0x0e, 0x3d, 0xf5, 0xd2, 0xef, 0xd0, 0x8f, 0xd8, 0x53, 0x03, 0x0f, + 0x95, 0x14, 0x3d, 0x7a, 0x9b, 0x99, 0xdf, 0x9b, 0x79, 0xff, 0xf7, 0x9f, 0x07, 0xb0, 0x20, 0x0a, + 0xad, 0x98, 0x53, 0x4a, 0x4c, 0x99, 0x07, 0xa9, 0x1b, 0x65, 0xfa, 0x8f, 0x64, 0xe1, 0x72, 0xf4, + 0x45, 0xd5, 0x78, 0x93, 0xa0, 0x3b, 0xe2, 0xe8, 0xa0, 0x87, 0xc1, 0x1a, 0x6f, 0x88, 0x42, 0x07, + 0x5f, 0x56, 0x98, 0xa4, 0x6c, 0x08, 0xc0, 0x31, 0xa6, 0x24, 0x48, 0x89, 0x67, 0x9a, 0x34, 0x90, + 0xcc, 0xce, 0x90, 0x59, 0x62, 0x88, 0xe5, 0xec, 0x88, 0x53, 0x39, 0xc5, 0xba, 0xa0, 0x84, 0x98, + 0x4d, 0x02, 0x5f, 0x6b, 0x0c, 0x24, 0x53, 0x75, 0x5a, 0x21, 0x66, 0xb7, 0x3e, 0xd3, 0xa1, 0x5d, + 0xdc, 0xe6, 0x51, 0xa4, 0xc9, 0x05, 0xd8, 0xe5, 0x8c, 0x41, 0x93, 0xe3, 0x2c, 0xd1, 0x9a, 0x03, + 0xd9, 0x54, 0x9d, 0x22, 0x36, 0x34, 0xe8, 0x7d, 0xd7, 0x94, 0xc4, 0xb4, 0x4c, 0xd0, 0xd8, 0x40, + 0x6f, 0x44, 0x49, 0x7a, 0x5a, 0xb9, 0x5b, 0x49, 0x72, 0x45, 0x52, 0x1f, 0xfe, 0xd4, 0x2e, 0x2e, + 0x35, 0x7d, 0x48, 0xf0, 0xeb, 0x21, 0xf6, 0xdd, 0xf4, 0x54, 0x7a, 0x7e, 0x82, 0xcc, 0x71, 0x56, + 0x3a, 0x97, 0x87, 0xec, 0x2f, 0xa8, 0x14, 0xf9, 0x93, 0xb5, 0x1b, 0xad, 0x50, 0x6b, 0x0a, 0x47, + 0x29, 0xf2, 0xc7, 0x79, 0x9e, 0xc3, 0x25, 0x6e, 0x4a, 0xd8, 0x12, 0x70, 0x89, 0x9b, 0x02, 0x1a, + 0xbf, 0x81, 0x55, 0xb5, 0x8a, 0x27, 0x0c, 0x5f, 0x1b, 0xd0, 0xc9, 0x0b, 0xf7, 0xc8, 0xd7, 0x81, + 0x87, 0x6c, 0x0c, 0xb0, 0x5f, 0x00, 0xfb, 0xb7, 0x95, 0x7d, 0xf0, 0xa3, 0xe8, 0xff, 0x8f, 0xe1, + 0xd2, 0x1f, 0xf5, 0xf3, 0xdd, 0x6c, 0xb5, 0x25, 0x5d, 0xba, 0x64, 0x8f, 0xd0, 0xa9, 0xb8, 0xc8, + 0xf6, 0x9d, 0x07, 0x77, 0xaa, 0x9f, 0x1d, 0xe5, 0xf5, 0xd1, 0x77, 0xa0, 0x88, 0x87, 0xb1, 0xfe, + 0xb6, 0xab, 0xb6, 0x14, 0x5d, 0x3f, 0x84, 0x6a, 0xb3, 0xae, 0x2f, 0x9e, 0xf2, 0x73, 0x91, 0x3b, + 0xb5, 0x3c, 0x7a, 0xb6, 0x45, 0x78, 0x4e, 0x7c, 0x6e, 0x8b, 0x6e, 0xbb, 0xf8, 0xbc, 0xf6, 0x9c, + 0xca, 0x3c, 0x9e, 0x4e, 0x95, 0xa2, 0x74, 0xf5, 0x15, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x03, 0xc2, + 0x5c, 0x71, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// HookServiceClient is the client API for HookService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type HookServiceClient interface { + PreReceive(ctx context.Context, in *PreReceiveHookRequest, opts ...grpc.CallOption) (*PreReceiveHookResponse, error) + PostReceive(ctx context.Context, in *PostReceiveHookRequest, opts ...grpc.CallOption) (*PostReceiveHookResponse, error) + Update(ctx context.Context, in *UpdateHookRequest, opts ...grpc.CallOption) (*UpdateHookResponse, error) +} + +type hookServiceClient struct { + cc *grpc.ClientConn +} + +func NewHookServiceClient(cc *grpc.ClientConn) HookServiceClient { + return &hookServiceClient{cc} +} + +func (c *hookServiceClient) PreReceive(ctx context.Context, in *PreReceiveHookRequest, opts ...grpc.CallOption) (*PreReceiveHookResponse, error) { + out := new(PreReceiveHookResponse) + err := c.cc.Invoke(ctx, "/gitaly.HookService/PreReceive", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookServiceClient) PostReceive(ctx context.Context, in *PostReceiveHookRequest, opts ...grpc.CallOption) (*PostReceiveHookResponse, error) { + out := new(PostReceiveHookResponse) + err := c.cc.Invoke(ctx, "/gitaly.HookService/PostReceive", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hookServiceClient) Update(ctx context.Context, in *UpdateHookRequest, opts ...grpc.CallOption) (*UpdateHookResponse, error) { + out := new(UpdateHookResponse) + err := c.cc.Invoke(ctx, "/gitaly.HookService/Update", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HookServiceServer is the server API for HookService service. +type HookServiceServer interface { + PreReceive(context.Context, *PreReceiveHookRequest) (*PreReceiveHookResponse, error) + PostReceive(context.Context, *PostReceiveHookRequest) (*PostReceiveHookResponse, error) + Update(context.Context, *UpdateHookRequest) (*UpdateHookResponse, error) +} + +// UnimplementedHookServiceServer can be embedded to have forward compatible implementations. +type UnimplementedHookServiceServer struct { +} + +func (*UnimplementedHookServiceServer) PreReceive(ctx context.Context, req *PreReceiveHookRequest) (*PreReceiveHookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PreReceive not implemented") +} +func (*UnimplementedHookServiceServer) PostReceive(ctx context.Context, req *PostReceiveHookRequest) (*PostReceiveHookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PostReceive not implemented") +} +func (*UnimplementedHookServiceServer) Update(ctx context.Context, req *UpdateHookRequest) (*UpdateHookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") +} + +func RegisterHookServiceServer(s *grpc.Server, srv HookServiceServer) { + s.RegisterService(&_HookService_serviceDesc, srv) +} + +func _HookService_PreReceive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PreReceiveHookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookServiceServer).PreReceive(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gitaly.HookService/PreReceive", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookServiceServer).PreReceive(ctx, req.(*PreReceiveHookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookService_PostReceive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PostReceiveHookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookServiceServer).PostReceive(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gitaly.HookService/PostReceive", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookServiceServer).PostReceive(ctx, req.(*PostReceiveHookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HookService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HookServiceServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gitaly.HookService/Update", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HookServiceServer).Update(ctx, req.(*UpdateHookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _HookService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "gitaly.HookService", + HandlerType: (*HookServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PreReceive", + Handler: _HookService_PreReceive_Handler, + }, + { + MethodName: "PostReceive", + Handler: _HookService_PostReceive_Handler, + }, + { + MethodName: "Update", + Handler: _HookService_Update_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "hook.proto", +} diff --git a/proto/go/gitalypb/protolist.go b/proto/go/gitalypb/protolist.go index c85049d62bc62e11de6b42a0a4bc9957039a622a..041d84511ee363e61d1c337ea71f55b47fb384d4 100644 --- a/proto/go/gitalypb/protolist.go +++ b/proto/go/gitalypb/protolist.go @@ -9,6 +9,7 @@ var GitalyProtos = []string{ "commit.proto", "conflicts.proto", "diff.proto", + "hook.proto", "namespace.proto", "objectpool.proto", "operations.proto", diff --git a/proto/hook.proto b/proto/hook.proto new file mode 100644 index 0000000000000000000000000000000000000000..e963b115f7ff86107ef8c7510e903e96a1001a2f --- /dev/null +++ b/proto/hook.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +package gitaly; + +option go_package = "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"; + +import "shared.proto"; + +service HookService { + rpc PreReceive(PreReceiveHookRequest) returns (PreReceiveHookResponse) { + option (op_type) = { + op: MUTATOR + target_repository_field: "1" + }; + } + rpc PostReceive(PostReceiveHookRequest) returns (PostReceiveHookResponse) { + option (op_type) = { + op: MUTATOR + target_repository_field: "1" + }; + } + rpc Update(UpdateHookRequest) returns (UpdateHookResponse) { + option (op_type) = { + op: MUTATOR + target_repository_field: "1" + }; + } +} + +message PreReceiveHookRequest { + Repository repository = 1; + string key_id = 2; + string protocol = 3; + repeated string refs = 4; +} + +message PreReceiveHookResponse{} + + +message PostReceiveHookRequest { + Repository repository = 1; + string key_id = 2; + repeated string refs = 3; +} + +message PostReceiveHookResponse{} + +message UpdateHookRequest { + Repository repository = 1; + string key_id = 2; + string ref = 3; + string old_value = 4; + string new_value = 5; +} + +message UpdateHookResponse{} diff --git a/ruby/gitlab-shell/hooks/post-receive b/ruby/gitlab-shell/hooks/post-receive index 2b6538f0323d08966071c43da8c575cfb8f7890b..b8b2850b22a85032f3c26573b23dfe202493acb9 100755 --- a/ruby/gitlab-shell/hooks/post-receive +++ b/ruby/gitlab-shell/hooks/post-receive @@ -6,7 +6,8 @@ refs = $stdin.read key_id = ENV.delete('GL_ID') gl_repository = ENV['GL_REPOSITORY'] -repo_path = Dir.pwd +#repo_path = Dir.pwd +repo_path = ENV['GL_REPO_PATH'] require_relative '../lib/gitlab_custom_hook' require_relative '../lib/hooks_utils' diff --git a/ruby/gitlab-shell/hooks/pre-receive b/ruby/gitlab-shell/hooks/pre-receive index 6ce5879519575bca9854a0fe93f13b71dac9830e..658a712c51e2c0442f8f1bf557edb8d6a2bb1077 100755 --- a/ruby/gitlab-shell/hooks/pre-receive +++ b/ruby/gitlab-shell/hooks/pre-receive @@ -6,7 +6,8 @@ refs = $stdin.read key_id = ENV.delete('GL_ID') protocol = ENV.delete('GL_PROTOCOL') -repo_path = Dir.pwd +#repo_path = Dir.pwd +repo_path = ENV.delete('GL_REPO_PATH') gl_repository = ENV['GL_REPOSITORY'] def increase_reference_counter(gl_repository, repo_path) diff --git a/ruby/gitlab-shell/hooks/update b/ruby/gitlab-shell/hooks/update index 4c2fc08b0d7cfcf90bf4f296bccc8468f8668a89..78e43d293d7889532c21e77cfc29787ed81ce600 100755 --- a/ruby/gitlab-shell/hooks/update +++ b/ruby/gitlab-shell/hooks/update @@ -6,7 +6,8 @@ ref_name = ARGV[0] old_value = ARGV[1] new_value = ARGV[2] -repo_path = Dir.pwd +#repo_path = Dir.pwd +repo_path = ENV.delete('GL_REPO_PATH') key_id = ENV.delete('GL_ID') require_relative '../lib/gitlab_custom_hook' diff --git a/ruby/proto/gitaly.rb b/ruby/proto/gitaly.rb index c35bc6e06c737a3a7f922136d80c5b1bcf588803..d0a179470595502727b8db79a68e7fde05b8a33c 100644 --- a/ruby/proto/gitaly.rb +++ b/ruby/proto/gitaly.rb @@ -13,6 +13,8 @@ require 'gitaly/conflicts_services_pb' require 'gitaly/diff_services_pb' +require 'gitaly/hook_services_pb' + require 'gitaly/namespace_services_pb' require 'gitaly/objectpool_services_pb' diff --git a/ruby/proto/gitaly/hook_pb.rb b/ruby/proto/gitaly/hook_pb.rb new file mode 100644 index 0000000000000000000000000000000000000000..7181c71b32a97fcd53a624551bfc775c567ed66f --- /dev/null +++ b/ruby/proto/gitaly/hook_pb.rb @@ -0,0 +1,41 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: hook.proto + +require 'google/protobuf' + +require 'shared_pb' +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "gitaly.PreReceiveHookRequest" do + optional :repository, :message, 1, "gitaly.Repository" + optional :key_id, :string, 2 + optional :protocol, :string, 3 + repeated :refs, :string, 4 + end + add_message "gitaly.PreReceiveHookResponse" do + end + add_message "gitaly.PostReceiveHookRequest" do + optional :repository, :message, 1, "gitaly.Repository" + optional :key_id, :string, 2 + repeated :refs, :string, 3 + end + add_message "gitaly.PostReceiveHookResponse" do + end + add_message "gitaly.UpdateHookRequest" do + optional :repository, :message, 1, "gitaly.Repository" + optional :key_id, :string, 2 + optional :ref, :string, 3 + optional :old_value, :string, 4 + optional :new_value, :string, 5 + end + add_message "gitaly.UpdateHookResponse" do + end +end + +module Gitaly + PreReceiveHookRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PreReceiveHookRequest").msgclass + PreReceiveHookResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PreReceiveHookResponse").msgclass + PostReceiveHookRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PostReceiveHookRequest").msgclass + PostReceiveHookResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.PostReceiveHookResponse").msgclass + UpdateHookRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UpdateHookRequest").msgclass + UpdateHookResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("gitaly.UpdateHookResponse").msgclass +end diff --git a/ruby/proto/gitaly/hook_services_pb.rb b/ruby/proto/gitaly/hook_services_pb.rb new file mode 100644 index 0000000000000000000000000000000000000000..2a5aaa11f90aa117a60d37c07511293ca772c1fd --- /dev/null +++ b/ruby/proto/gitaly/hook_services_pb.rb @@ -0,0 +1,24 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: hook.proto for package 'gitaly' + +require 'grpc' +require 'hook_pb' + +module Gitaly + module HookService + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'gitaly.HookService' + + rpc :PreReceive, PreReceiveHookRequest, PreReceiveHookResponse + rpc :PostReceive, PostReceiveHookRequest, PostReceiveHookResponse + rpc :Update, UpdateHookRequest, UpdateHookResponse + end + + Stub = Service.rpc_stub_class + end +end