diff options
author | Ahmad Hassan <ahassan@gitlab.com> | 2018-06-01 19:01:02 +0300 |
---|---|---|
committer | Kim Carlbäcker <kim.carlbacker@gmail.com> | 2018-06-01 19:01:02 +0300 |
commit | 16565770b29aad8f93b435fab7411e0ffb41956a (patch) | |
tree | 45bd199c5021aeef08f6b8f79929170e5e88effa | |
parent | 90d35a6d2782e70843cb8e79a4c9a34fa613d8c4 (diff) |
Add RestoreCustomHooks RPC
-rw-r--r-- | changelogs/unreleased/restore-custom-hooks-rpc.yml | 5 | ||||
-rw-r--r-- | internal/service/repository/restore_custom_hooks.go | 54 | ||||
-rw-r--r-- | internal/service/repository/restore_custom_hooks_test.go | 123 | ||||
-rw-r--r-- | internal/service/repository/testdata/corrupted_hooks.tar | 1 | ||||
-rw-r--r-- | internal/service/repository/testdata/custom_hooks.tar | bin | 0 -> 8192 bytes |
5 files changed, 181 insertions, 2 deletions
diff --git a/changelogs/unreleased/restore-custom-hooks-rpc.yml b/changelogs/unreleased/restore-custom-hooks-rpc.yml new file mode 100644 index 000000000..cc397aaaf --- /dev/null +++ b/changelogs/unreleased/restore-custom-hooks-rpc.yml @@ -0,0 +1,5 @@ +--- +title: RestoreCustomHooks +merge_request: 741 +author: +type: added diff --git a/internal/service/repository/restore_custom_hooks.go b/internal/service/repository/restore_custom_hooks.go index f95e66402..f920ce763 100644 --- a/internal/service/repository/restore_custom_hooks.go +++ b/internal/service/repository/restore_custom_hooks.go @@ -1,10 +1,60 @@ package repository import ( + "os/exec" + pb "gitlab.com/gitlab-org/gitaly-proto/go" + "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/streamio" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) -func (*server) RestoreCustomHooks(pb.RepositoryService_RestoreCustomHooksServer) error { - return helper.Unimplemented +func (s *server) RestoreCustomHooks(stream pb.RepositoryService_RestoreCustomHooksServer) error { + firstRequest, err := stream.Recv() + if err != nil { + return status.Errorf(codes.Internal, "RestoreCustomHooks: first request failed %v", err) + } + + repo := firstRequest.GetRepository() + if repo == nil { + return status.Errorf(codes.InvalidArgument, "RestoreCustomHooks: empty Repository") + } + + reader := streamio.NewReader(func() ([]byte, error) { + if firstRequest != nil { + data := firstRequest.GetData() + firstRequest = nil + return data, nil + } + + request, err := stream.Recv() + return request.GetData(), err + }) + + repoPath, err := helper.GetPath(repo) + if err != nil { + return status.Errorf(codes.Internal, "RestoreCustomHooks: getting repo path failed %v", err) + } + + cmdArgs := []string{ + "-xf", + "-", + "-C", + repoPath, + "custom_hooks", + } + + ctx := stream.Context() + cmd, err := command.New(ctx, exec.Command("tar", cmdArgs...), reader, nil, nil) + if err != nil { + return status.Errorf(codes.Internal, "RestoreCustomHooks: Could not untar custom hooks tar %v", err) + } + + if err := cmd.Wait(); err != nil { + return status.Errorf(codes.Internal, "RestoreCustomHooks: cmd wait failed: %v", err) + } + + return stream.SendAndClose(&pb.RestoreCustomHooksResponse{}) } diff --git a/internal/service/repository/restore_custom_hooks_test.go b/internal/service/repository/restore_custom_hooks_test.go new file mode 100644 index 000000000..cfe4fe822 --- /dev/null +++ b/internal/service/repository/restore_custom_hooks_test.go @@ -0,0 +1,123 @@ +package repository + +import ( + "io" + "os" + "path" + "testing" + + "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/streamio" + "google.golang.org/grpc/codes" + + pb "gitlab.com/gitlab-org/gitaly-proto/go" + + "github.com/stretchr/testify/require" +) + +func TestSuccessfullRestoreCustomHooksRequest(t *testing.T) { + server, serverSocketPath := runRepoServer(t) + defer server.Stop() + + client, conn := newRepositoryClient(t, serverSocketPath) + defer conn.Close() + + ctx, cancel := testhelper.Context() + defer cancel() + + testRepo, _, cleanupFn := testhelper.NewTestRepo(t) + + defer cleanupFn() + + stream, err := client.RestoreCustomHooks(ctx) + + require.NoError(t, err) + + repoPath, err := helper.GetPath(testRepo) + require.NoError(t, err) + defer os.RemoveAll(repoPath) + request := &pb.RestoreCustomHooksRequest{Repository: testRepo} + writer := streamio.NewWriter(func(p []byte) error { + request.Data = p + if err := stream.Send(request); err != nil { + return err + } + + request = &pb.RestoreCustomHooksRequest{} + return nil + }) + + file, err := os.Open("testdata/custom_hooks.tar") + require.NoError(t, err) + defer file.Close() + + _, err = io.Copy(writer, file) + require.NoError(t, err) + _, err = stream.CloseAndRecv() + require.NoError(t, err) + + require.FileExists(t, path.Join(repoPath, "custom_hooks/pre-push.sample")) +} + +func TestFailedRestoreCustomHooksDueToValidations(t *testing.T) { + server, serverSocketPath := runRepoServer(t) + defer server.Stop() + + client, conn := newRepositoryClient(t, serverSocketPath) + defer conn.Close() + + ctx, cancel := testhelper.Context() + defer cancel() + + stream, err := client.RestoreCustomHooks(ctx) + require.NoError(t, err) + + require.NoError(t, stream.Send(&pb.RestoreCustomHooksRequest{})) + + _, err = stream.CloseAndRecv() + testhelper.AssertGrpcError(t, err, codes.InvalidArgument, "") +} + +func TestFailedRestoreCustomHooksDueToBadTar(t *testing.T) { + server, serverSocketPath := runRepoServer(t) + defer server.Stop() + + client, conn := newRepositoryClient(t, serverSocketPath) + defer conn.Close() + + ctx, cancel := testhelper.Context() + defer cancel() + + testRepo, _, cleanupFn := testhelper.NewTestRepo(t) + + defer cleanupFn() + + stream, err := client.RestoreCustomHooks(ctx) + + require.NoError(t, err) + + repoPath, err := helper.GetPath(testRepo) + require.NoError(t, err) + defer os.RemoveAll(repoPath) + request := &pb.RestoreCustomHooksRequest{Repository: testRepo} + writer := streamio.NewWriter(func(p []byte) error { + request.Data = p + if err := stream.Send(request); err != nil { + return err + } + + request = &pb.RestoreCustomHooksRequest{} + return nil + }) + + file, err := os.Open("testdata/corrupted_hooks.tar") + require.NoError(t, err) + defer file.Close() + + _, err = io.Copy(writer, file) + require.NoError(t, err) + _, err = stream.CloseAndRecv() + + testhelper.AssertGrpcError(t, err, codes.Internal, "") +} diff --git a/internal/service/repository/testdata/corrupted_hooks.tar b/internal/service/repository/testdata/corrupted_hooks.tar new file mode 100644 index 000000000..fe580ca02 --- /dev/null +++ b/internal/service/repository/testdata/corrupted_hooks.tar @@ -0,0 +1 @@ +This is a corrupted tar file diff --git a/internal/service/repository/testdata/custom_hooks.tar b/internal/service/repository/testdata/custom_hooks.tar Binary files differnew file mode 100644 index 000000000..9630316d3 --- /dev/null +++ b/internal/service/repository/testdata/custom_hooks.tar |