summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsh McKenzie <amckenzie@gitlab.com>2019-10-29 00:58:31 +0000
committerAsh McKenzie <amckenzie@gitlab.com>2019-10-29 00:58:31 +0000
commit0afa8ec5fcc571d7bdfb5f52533e3df4ab78f793 (patch)
treecc0ac9e4c29b4f3b954aa9912403fe1bfc9c9867
parent7d36bc3bba67d42f7d23bd16624ef5e6aab2bddc (diff)
parentbee2c423858c0763cce91bcacf345eb0b45227a6 (diff)
downloadgitlab-shell-0afa8ec5fcc571d7bdfb5f52533e3df4ab78f793.tar.gz
Merge branch 'pass-ff-to-gitaly' into 'master'
Add support for Gitaly feature flags See merge request gitlab-org/gitlab-shell!351
-rw-r--r--internal/command/receivepack/gitalycall.go1
-rw-r--r--internal/command/receivepack/gitalycall_test.go2
-rw-r--r--internal/command/uploadarchive/gitalycall.go1
-rw-r--r--internal/command/uploadarchive/gitalycall_test.go2
-rw-r--r--internal/command/uploadpack/gitalycall.go1
-rw-r--r--internal/command/uploadpack/gitalycall_test.go13
-rw-r--r--internal/gitlabnet/accessverifier/client.go7
-rw-r--r--internal/gitlabnet/testserver/gitalyserver.go22
-rw-r--r--internal/handler/exec.go16
-rw-r--r--internal/handler/exec_test.go44
-rw-r--r--internal/testhelper/requesthandlers/requesthandlers.go5
11 files changed, 101 insertions, 13 deletions
diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go
index f440672..a8d8160 100644
--- a/internal/command/receivepack/gitalycall.go
+++ b/internal/command/receivepack/gitalycall.go
@@ -18,6 +18,7 @@ func (c *Command) performGitalyCall(response *accessverifier.Response) error {
ServiceName: string(commandargs.ReceivePack),
Address: response.Gitaly.Address,
Token: response.Gitaly.Token,
+ Features: response.Gitaly.Features,
}
request := &pb.SSHReceivePackRequest{
diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go
index 361596a..de20bfd 100644
--- a/internal/command/receivepack/gitalycall_test.go
+++ b/internal/command/receivepack/gitalycall_test.go
@@ -14,7 +14,7 @@ import (
)
func TestReceivePack(t *testing.T) {
- gitalyAddress, cleanup := testserver.StartGitalyServer(t)
+ gitalyAddress, _, cleanup := testserver.StartGitalyServer(t)
defer cleanup()
requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress)
diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go
index 1dfc864..269a8e2 100644
--- a/internal/command/uploadarchive/gitalycall.go
+++ b/internal/command/uploadarchive/gitalycall.go
@@ -18,6 +18,7 @@ func (c *Command) performGitalyCall(response *accessverifier.Response) error {
ServiceName: string(commandargs.UploadArchive),
Address: response.Gitaly.Address,
Token: response.Gitaly.Token,
+ Features: response.Gitaly.Features,
}
request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo}
diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go
index 5c5353f..5345119 100644
--- a/internal/command/uploadarchive/gitalycall_test.go
+++ b/internal/command/uploadarchive/gitalycall_test.go
@@ -14,7 +14,7 @@ import (
)
func TestUploadPack(t *testing.T) {
- gitalyAddress, cleanup := testserver.StartGitalyServer(t)
+ gitalyAddress, _, cleanup := testserver.StartGitalyServer(t)
defer cleanup()
requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress)
diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go
index 8b97dee..8c8a254 100644
--- a/internal/command/uploadpack/gitalycall.go
+++ b/internal/command/uploadpack/gitalycall.go
@@ -18,6 +18,7 @@ func (c *Command) performGitalyCall(response *accessverifier.Response) error {
ServiceName: string(commandargs.UploadPack),
Address: response.Gitaly.Address,
Token: response.Gitaly.Token,
+ Features: response.Gitaly.Features,
}
request := &pb.SSHUploadPackRequest{
diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go
index 71a253b..8c74212 100644
--- a/internal/command/uploadpack/gitalycall_test.go
+++ b/internal/command/uploadpack/gitalycall_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs"
@@ -14,7 +15,7 @@ import (
)
func TestUploadPack(t *testing.T) {
- gitalyAddress, cleanup := testserver.StartGitalyServer(t)
+ gitalyAddress, testServer, cleanup := testserver.StartGitalyServer(t)
defer cleanup()
requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress)
@@ -37,4 +38,14 @@ func TestUploadPack(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "UploadPack: "+repo, output.String())
+
+ for k, v := range map[string]string{
+ "gitaly-feature-cache_invalidator": "true",
+ "gitaly-feature-inforef_uploadpack_cache": "false",
+ } {
+ actual := testServer.ReceivedMD[k]
+ assert.Len(t, actual, 1)
+ assert.Equal(t, v, actual[0])
+ }
+ assert.Empty(t, testServer.ReceivedMD["some-other-ff"])
}
diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go
index 217dcdb..3075ede 100644
--- a/internal/gitlabnet/accessverifier/client.go
+++ b/internal/gitlabnet/accessverifier/client.go
@@ -31,9 +31,10 @@ type Request struct {
}
type Gitaly struct {
- Repo pb.Repository `json:"repository"`
- Address string `json:"address"`
- Token string `json:"token"`
+ Repo pb.Repository `json:"repository"`
+ Address string `json:"address"`
+ Token string `json:"token"`
+ Features map[string]string `json:"features"`
}
type CustomPayloadData struct {
diff --git a/internal/gitlabnet/testserver/gitalyserver.go b/internal/gitlabnet/testserver/gitalyserver.go
index 694fd41..6d0c130 100644
--- a/internal/gitlabnet/testserver/gitalyserver.go
+++ b/internal/gitlabnet/testserver/gitalyserver.go
@@ -10,49 +10,56 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
+ "google.golang.org/grpc/metadata"
pb "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
)
-type testGitalyServer struct{}
+type TestGitalyServer struct{ ReceivedMD metadata.MD }
-func (s *testGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error {
+func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error {
req, err := stream.Recv()
if err != nil {
return err
}
+ s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
+
response := []byte("ReceivePack: " + req.GlId + " " + req.Repository.GlRepository)
stream.Send(&pb.SSHReceivePackResponse{Stdout: response})
return nil
}
-func (s *testGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServer) error {
+func (s *TestGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServer) error {
req, err := stream.Recv()
if err != nil {
return err
}
+ s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
+
response := []byte("UploadPack: " + req.Repository.GlRepository)
stream.Send(&pb.SSHUploadPackResponse{Stdout: response})
return nil
}
-func (s *testGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error {
+func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error {
req, err := stream.Recv()
if err != nil {
return err
}
+ s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
+
response := []byte("UploadArchive: " + req.Repository.GlRepository)
stream.Send(&pb.SSHUploadArchiveResponse{Stdout: response})
return nil
}
-func StartGitalyServer(t *testing.T) (string, func()) {
+func StartGitalyServer(t *testing.T) (string, *TestGitalyServer, func()) {
tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api")
gitalySocketPath := path.Join(tempDir, "gitaly.sock")
@@ -64,7 +71,8 @@ func StartGitalyServer(t *testing.T) (string, func()) {
listener, err := net.Listen("unix", gitalySocketPath)
require.NoError(t, err)
- pb.RegisterSSHServiceServer(server, &testGitalyServer{})
+ testServer := TestGitalyServer{}
+ pb.RegisterSSHServiceServer(server, &testServer)
go server.Serve(listener)
@@ -74,5 +82,5 @@ func StartGitalyServer(t *testing.T) (string, func()) {
os.RemoveAll(tempDir)
}
- return gitalySocketUrl, cleanup
+ return gitalySocketUrl, &testServer, cleanup
}
diff --git a/internal/handler/exec.go b/internal/handler/exec.go
index ba9a4ff..19621fa 100644
--- a/internal/handler/exec.go
+++ b/internal/handler/exec.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"os"
+ "strings"
"gitlab.com/gitlab-org/gitaly/auth"
"gitlab.com/gitlab-org/gitaly/client"
@@ -11,6 +12,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/internal/config"
"gitlab.com/gitlab-org/labkit/tracing"
"google.golang.org/grpc"
+ "google.golang.org/grpc/metadata"
)
// GitalyHandlerFunc implementations are responsible for making
@@ -29,6 +31,7 @@ type GitalyCommand struct {
ServiceName string
Address string
Token string
+ Features map[string]string
}
// RunGitalyCommand provides a bootstrap for Gitaly commands executed
@@ -48,6 +51,18 @@ func (gc *GitalyCommand) RunGitalyCommand(handler GitalyHandlerFunc) error {
return err
}
+func withOutgoingMetadata(ctx context.Context, features map[string]string) context.Context {
+ md := metadata.New(nil)
+ for k, v := range features {
+ if !strings.HasPrefix(k, "gitaly-feature-") {
+ continue
+ }
+ md.Append(k, v)
+ }
+
+ return metadata.NewOutgoingContext(ctx, md)
+}
+
func getConn(gc *GitalyCommand) (*GitalyConn, error) {
if gc.Address == "" {
return nil, fmt.Errorf("no gitaly_address given")
@@ -80,6 +95,7 @@ func getConn(gc *GitalyCommand) (*GitalyConn, error) {
)
ctx, finished := tracing.ExtractFromEnv(context.Background())
+ ctx = withOutgoingMetadata(ctx, gc.Features)
conn, err := client.Dial(gc.Address, connOpts)
if err != nil {
diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go
index 6c7d3f5..7c85e16 100644
--- a/internal/handler/exec_test.go
+++ b/internal/handler/exec_test.go
@@ -5,8 +5,10 @@ import (
"errors"
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
+ "google.golang.org/grpc/metadata"
"gitlab.com/gitlab-org/gitlab-shell/internal/config"
)
@@ -40,3 +42,45 @@ func TestMissingGitalyAddress(t *testing.T) {
err := cmd.RunGitalyCommand(makeHandler(t, nil))
require.EqualError(t, err, "no gitaly_address given")
}
+
+func TestGetConnMetadata(t *testing.T) {
+ tests := []struct {
+ name string
+ gc *GitalyCommand
+ want map[string]string
+ }{
+ {
+ name: "gitaly_feature_flags",
+ gc: &GitalyCommand{
+ Config: &config.Config{},
+ Address: "tcp://localhost:9999",
+ Features: map[string]string{
+ "gitaly-feature-cache_invalidator": "true",
+ "other-ff": "true",
+ "gitaly-feature-inforef_uploadpack_cache": "false",
+ },
+ },
+ want: map[string]string{
+ "gitaly-feature-cache_invalidator": "true",
+ "gitaly-feature-inforef_uploadpack_cache": "false",
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ conn, err := getConn(tt.gc)
+ require.NoError(t, err)
+
+ md, exists := metadata.FromOutgoingContext(conn.ctx)
+ require.True(t, exists)
+ require.Equal(t, len(tt.want), md.Len())
+
+ for k, v := range tt.want {
+ values := md.Get(k)
+ assert.Equal(t, 1, len(values))
+ assert.Equal(t, v, values[0])
+ }
+
+ })
+ }
+}
diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go
index 11817e8..fef53b6 100644
--- a/internal/testhelper/requesthandlers/requesthandlers.go
+++ b/internal/testhelper/requesthandlers/requesthandlers.go
@@ -47,6 +47,11 @@ func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testse
},
"address": gitalyAddress,
"token": "token",
+ "features": map[string]string{
+ "gitaly-feature-cache_invalidator": "true",
+ "gitaly-feature-inforef_uploadpack_cache": "false",
+ "some-other-ff": "true",
+ },
},
}
require.NoError(t, json.NewEncoder(w).Encode(body))