Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRubén Dávila <ruben@gitlab.com>2018-07-30 04:59:53 +0300
committerRubén Dávila <ruben@gitlab.com>2018-08-07 20:03:16 +0300
commit16ba20281169c1460a6ceb207e21b1b0799f50aa (patch)
treee0134755461499666f2f0b0f9ebbf7fc061ea963
parent23df453426141ec5553d662297faff145690a14d (diff)
Add ability to support custom options for git-receive-pack
In order to reject pushes that are larger then the size configured by the user on GitLab we need to support custom options for the `git -c` command. Specifically we're going to receive receive.MaxInputSize= from the Gitaly client. Pushes over HTTP are also protected by this setting.
-rw-r--r--changelogs/unreleased/rd-add-support-for-max-input-size-config.yml5
-rw-r--r--internal/git/helper.go13
-rw-r--r--internal/service/smarthttp/receive_pack.go11
-rw-r--r--internal/service/ssh/receive_pack.go11
-rw-r--r--internal/service/ssh/receive_pack_test.go52
-rw-r--r--vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION2
-rw-r--r--vendor/vendor.json10
7 files changed, 81 insertions, 23 deletions
diff --git a/changelogs/unreleased/rd-add-support-for-max-input-size-config.yml b/changelogs/unreleased/rd-add-support-for-max-input-size-config.yml
new file mode 100644
index 000000000..8695fa7fe
--- /dev/null
+++ b/changelogs/unreleased/rd-add-support-for-max-input-size-config.yml
@@ -0,0 +1,5 @@
+---
+title: Add ability to support custom options for git-receive-pack
+merge_request: 834
+author:
+type: added
diff --git a/internal/git/helper.go b/internal/git/helper.go
index ba4e476de..8af8511d9 100644
--- a/internal/git/helper.go
+++ b/internal/git/helper.go
@@ -59,3 +59,16 @@ func Version() (string, error) {
return ver[2], nil
}
+
+// BuildGitOptions helps to generate options to the git command.
+// If gitOpts is not empty then its values are passed as part of
+// the "-c" option of the git command, the other values are passed along with the subcommand.
+func BuildGitOptions(gitOpts []string, otherOpts ...string) []string {
+ args := []string{}
+
+ if len(gitOpts) > 0 {
+ args = append([]string{"-c"}, gitOpts...)
+ }
+
+ return append(args, otherOpts...)
+}
diff --git a/internal/service/smarthttp/receive_pack.go b/internal/service/smarthttp/receive_pack.go
index 441793a8c..e342f051e 100644
--- a/internal/service/smarthttp/receive_pack.go
+++ b/internal/service/smarthttp/receive_pack.go
@@ -7,6 +7,7 @@ import (
"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/git"
"gitlab.com/gitlab-org/gitaly/internal/helper"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
@@ -22,9 +23,10 @@ func (s *server) PostReceivePack(stream pb.SmartHTTPService_PostReceivePackServe
}
grpc_logrus.Extract(stream.Context()).WithFields(log.Fields{
- "GlID": req.GlId,
- "GlRepository": req.GlRepository,
- "GlUsername": req.GlUsername,
+ "GlID": req.GlId,
+ "GlRepository": req.GlRepository,
+ "GlUsername": req.GlUsername,
+ "GitConfigOptions": req.GitConfigOptions,
}).Debug("PostReceivePack")
if err := validateReceivePackRequest(req); err != nil {
@@ -53,7 +55,8 @@ func (s *server) PostReceivePack(stream pb.SmartHTTPService_PostReceivePackServe
return err
}
- osCommand := exec.Command(command.GitPath(), "receive-pack", "--stateless-rpc", repoPath)
+ gitOptions := git.BuildGitOptions(req.GitConfigOptions, "receive-pack", "--stateless-rpc", repoPath)
+ osCommand := exec.Command(command.GitPath(), gitOptions...)
cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, nil, env...)
if err != nil {
diff --git a/internal/service/ssh/receive_pack.go b/internal/service/ssh/receive_pack.go
index f4986f315..e66ec4e74 100644
--- a/internal/service/ssh/receive_pack.go
+++ b/internal/service/ssh/receive_pack.go
@@ -7,6 +7,7 @@ import (
"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/git"
"gitlab.com/gitlab-org/gitaly/internal/helper"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
@@ -22,9 +23,10 @@ func (s *server) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error
}
grpc_logrus.Extract(stream.Context()).WithFields(log.Fields{
- "GlID": req.GlId,
- "GlRepository": req.GlRepository,
- "GlUsername": req.GlUsername,
+ "GlID": req.GlId,
+ "GlRepository": req.GlRepository,
+ "GlUsername": req.GlUsername,
+ "GitConfigOptions": req.GitConfigOptions,
}).Debug("SSHReceivePack")
if err = validateFirstReceivePackRequest(req); err != nil {
@@ -55,7 +57,8 @@ func (s *server) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error
return err
}
- osCommand := exec.Command(command.GitPath(), "receive-pack", repoPath)
+ gitOptions := git.BuildGitOptions(req.GitConfigOptions, "receive-pack", repoPath)
+ osCommand := exec.Command(command.GitPath(), gitOptions...)
cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, stderr, env...)
if err != nil {
diff --git a/internal/service/ssh/receive_pack_test.go b/internal/service/ssh/receive_pack_test.go
index 9aa6754eb..c3e1d24ee 100644
--- a/internal/service/ssh/receive_pack_test.go
+++ b/internal/service/ssh/receive_pack_test.go
@@ -3,6 +3,7 @@ package ssh
import (
"bytes"
"fmt"
+ "io/ioutil"
"os"
"os/exec"
"path"
@@ -13,6 +14,7 @@ import (
"github.com/golang/protobuf/jsonpb"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/git"
"gitlab.com/gitlab-org/gitaly/internal/testhelper"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
@@ -79,7 +81,15 @@ func TestReceivePackPushSuccess(t *testing.T) {
server, serverSocketPath := runSSHServer(t)
defer server.Stop()
- lHead, rHead, err := testCloneAndPush(t, serverSocketPath, testRepo.GetStorageName(), "1")
+ lHead, rHead, err := testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: "1"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if strings.Compare(lHead, rHead) != 0 {
+ t.Errorf("local and remote head not equal. push failed: %q != %q", lHead, rHead)
+ }
+
+ lHead, rHead, err = testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: "1", gitConfigOptions: []string{"receive.MaxInputSize=10000"}})
if err != nil {
t.Fatal(err)
}
@@ -92,17 +102,29 @@ func TestReceivePackPushFailure(t *testing.T) {
server, serverSocketPath := runSSHServer(t)
defer server.Stop()
- _, _, err := testCloneAndPush(t, serverSocketPath, "foobar", "1")
+ _, _, err := testCloneAndPush(t, serverSocketPath, pushParams{storageName: "foobar", glID: "1"})
if err == nil {
t.Errorf("local and remote head equal. push did not fail")
}
- _, _, err = testCloneAndPush(t, serverSocketPath, testRepo.GetStorageName(), "")
+
+ _, _, err = testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: ""})
if err == nil {
t.Errorf("local and remote head equal. push did not fail")
}
+
+ currentGitVersion, _ := git.Version()
+
+ // receive.MaxInputSize is only available since Git 2.11.0
+ // Skip this test from the job that uses Git 2.9.0
+ if currentGitVersion != "2.9.0" {
+ _, _, err = testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: "1", gitConfigOptions: []string{"receive.MaxInputSize=1"}})
+ if err == nil {
+ t.Errorf("local and remote head equal. push did not fail")
+ }
+ }
}
-func testCloneAndPush(t *testing.T, serverSocketPath string, storageName, glID string) (string, string, error) {
+func testCloneAndPush(t *testing.T, serverSocketPath string, params pushParams) (string, string, error) {
storagePath := testhelper.GitlabTestStoragePath()
tempRepo := "gitlab-test-ssh-receive-pack.git"
testRepoPath := path.Join(storagePath, testRepo.GetRelativePath())
@@ -124,12 +146,13 @@ func testCloneAndPush(t *testing.T, serverSocketPath string, storageName, glID s
makeCommit(t, localRepoPath)
- pbTempRepo := &pb.Repository{StorageName: storageName, RelativePath: tempRepo}
+ pbTempRepo := &pb.Repository{StorageName: params.storageName, RelativePath: tempRepo}
pbMarshaler := &jsonpb.Marshaler{}
payload, err := pbMarshaler.MarshalToString(&pb.SSHReceivePackRequest{
- Repository: pbTempRepo,
- GlRepository: pbTempRepo.GetRelativePath(),
- GlId: glID,
+ Repository: pbTempRepo,
+ GlRepository: pbTempRepo.GetRelativePath(),
+ GlId: params.glID,
+ GitConfigOptions: params.gitConfigOptions,
})
require.NoError(t, err)
@@ -159,6 +182,11 @@ func makeCommit(t *testing.T, localRepoPath string) ([]byte, []byte, bool) {
commitMsg := fmt.Sprintf("Testing ReceivePack RPC around %d", time.Now().Unix())
committerName := "Scrooge McDuck"
committerEmail := "scrooge@mcduck.com"
+ newFilePath := localRepoPath + "/foo.txt"
+
+ // Create a tiny file and add it to the index
+ require.NoError(t, ioutil.WriteFile(newFilePath, []byte("foo bar"), 0644))
+ testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "add", ".")
// The latest commit ID on the remote repo
oldHead := bytes.TrimSpace(testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "rev-parse", "master"))
@@ -166,7 +194,7 @@ func makeCommit(t *testing.T, localRepoPath string) ([]byte, []byte, bool) {
testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath,
"-c", fmt.Sprintf("user.name=%s", committerName),
"-c", fmt.Sprintf("user.email=%s", committerEmail),
- "commit", "--allow-empty", "-m", commitMsg)
+ "commit", "-m", commitMsg)
if t.Failed() {
return nil, nil, false
}
@@ -184,3 +212,9 @@ func drainPostReceivePackResponse(stream pb.SSH_SSHReceivePackClient) error {
}
return err
}
+
+type pushParams struct {
+ storageName string
+ glID string
+ gitConfigOptions []string
+}
diff --git a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
index e23e3fd29..5af665a17 100644
--- a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
+++ b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
@@ -1 +1 @@
-0.112.0
+0.111.0
diff --git a/vendor/vendor.json b/vendor/vendor.json
index ef4c8deb8..376d4a1b1 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -201,12 +201,12 @@
"revisionTime": "2017-12-31T12:27:32Z"
},
{
- "checksumSHA1": "oUra5duKbNfxA8e++b+QbLQYYXU=",
+ "checksumSHA1": "+GRNcdfnAibgtDObICxZIFk7i9Q=",
"path": "gitlab.com/gitlab-org/gitaly-proto/go",
- "revision": "e3a5c0a6da1c62f406f6b74b281dad43f8b74ea5",
- "revisionTime": "2018-08-02T15:59:47Z",
- "version": "v0.112.0",
- "versionExact": "v0.112.0"
+ "revision": "b26cda22da41c708d18be78c519a38810acfdc80",
+ "revisionTime": "2018-07-31T12:04:23Z",
+ "version": "v0.111.0",
+ "versionExact": "v0.111.0"
},
{
"checksumSHA1": "nqWNlnMmVpt628zzvyo6Yv2CX5Q=",