diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2020-03-13 19:13:13 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2020-03-16 14:06:35 +0300 |
commit | 75f23507af40aed4739571e1caa38ca46cd1e0ba (patch) | |
tree | ab085d0af31df6912b6cf5b08b4b8b1fac129c21 | |
parent | a95cf2d3a0dd0a5c835f39735f6aab4e13b410c4 (diff) |
ssh: upload_pack: Wire up UploadPackFilter feature flag
While the HTTP upload_pack service already honors the UploadPackFilter
feature flag to enable partial clones, the SSH sibling doesn't. As a
result, partial clones are unsupported via SSH even if the feature flag
is enabled.
Fix the gap between both services by passing both uploadpack.allowFilter and
uploadpack.allowanySHA1InWant to git-upload-pack(1), same as for the
HTTP service. Add a test to verify partial clones work as expected.
-rw-r--r-- | changelogs/unreleased/pks-ssh-upload-pack-filter.yml | 5 | ||||
-rw-r--r-- | internal/service/ssh/upload_pack.go | 5 | ||||
-rw-r--r-- | internal/service/ssh/upload_pack_test.go | 52 |
3 files changed, 62 insertions, 0 deletions
diff --git a/changelogs/unreleased/pks-ssh-upload-pack-filter.yml b/changelogs/unreleased/pks-ssh-upload-pack-filter.yml new file mode 100644 index 000000000..cf47ec014 --- /dev/null +++ b/changelogs/unreleased/pks-ssh-upload-pack-filter.yml @@ -0,0 +1,5 @@ +--- +title: Support partial clones with SSH transports +merge_request: 1893 +author: +type: added diff --git a/internal/service/ssh/upload_pack.go b/internal/service/ssh/upload_pack.go index d7ed643bd..94161fead 100644 --- a/internal/service/ssh/upload_pack.go +++ b/internal/service/ssh/upload_pack.go @@ -10,6 +10,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/pktline" "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/internal/service/inspect" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" @@ -74,6 +75,10 @@ func (s *server) sshUploadPack(stream gitalypb.SSHService_SSHUploadPackServer, r git.WarnIfTooManyBitmaps(ctx, repoPath) var globalOpts []git.Option + if featureflag.IsEnabled(ctx, featureflag.UploadPackFilter) { + globalOpts = append(globalOpts, git.UploadPackFilterConfig()...) + } + for _, o := range req.GitConfigOptions { globalOpts = append(globalOpts, git.ValueFlag{"-c", o}) } diff --git a/internal/service/ssh/upload_pack_test.go b/internal/service/ssh/upload_pack_test.go index 4445d724b..30ef62590 100644 --- a/internal/service/ssh/upload_pack_test.go +++ b/internal/service/ssh/upload_pack_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc/codes" @@ -217,6 +218,57 @@ func TestUploadPackCloneSuccess(t *testing.T) { } } +func TestUploadPackCloneWithPartialCloneFilter(t *testing.T) { + server, serverSocketPath := runSSHServer(t) + defer server.Stop() + + // Ruby file which is ~1kB in size and not present in HEAD + blobLessThanLimit := "6ee41e85cc9bf33c10b690df09ca735b22f3790f" + // Image which is ~100kB in size and not present in HEAD + blobGreaterThanLimit := "18079e308ff9b3a5e304941020747e5c39b46c88" + + tests := []struct { + desc string + flags []string + repoTest func(t *testing.T, repoPath string) + }{ + { + desc: "full_clone", + repoTest: func(t *testing.T, repoPath string) { + testhelper.GitObjectMustExist(t, repoPath, blobGreaterThanLimit) + }, + }, + { + desc: "partial_clone", + flags: []string{featureflag.UploadPackFilter}, + repoTest: func(t *testing.T, repoPath string) { + testhelper.GitObjectMustNotExist(t, repoPath, blobGreaterThanLimit) + }, + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + // Run the clone with filtering enabled in both runs. The only + // difference is that in the first run, we have the + // UploadPackFilter flag disabled. + localPath := path.Join(testRepoRoot, fmt.Sprintf("gitlab-test-upload-pack-local-%s", tc.desc)) + cmd := cloneCommand{ + repository: testRepo, + command: exec.Command("git", "clone", "--filter=blob:limit=2048", "git@localhost:test/test.git", localPath), + server: serverSocketPath, + featureFlags: tc.flags, + } + err := cmd.execute(t) + defer os.RemoveAll(localPath) + require.NoError(t, err, "clone failed") + + testhelper.GitObjectMustExist(t, localPath, blobLessThanLimit) + tc.repoTest(t, localPath) + }) + } +} + func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { restore := testhelper.EnableGitProtocolV2Support() defer restore() |