Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions cmd/gitserver/server/server_grpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package server

import (
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/gitserver/proto"
"github.com/sourcegraph/sourcegraph/internal/gitserver/protocol"
"github.com/sourcegraph/sourcegraph/internal/grpc/streamio"
"github.com/sourcegraph/sourcegraph/lib/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

type GRPCServer struct {
Server *Server
proto.UnimplementedGitserverServiceServer
}

func (gs *GRPCServer) Exec(req *proto.ExecRequest, ss proto.GitserverService_ExecServer) error {
internalReq := protocol.ExecRequest{
Repo: api.RepoName(req.GetRepo()),
EnsureRevision: req.GetEnsureRevision(),
Args: req.GetArgs(),
Stdin: req.GetStdin(),
NoTimeout: req.GetNoTimeout(),
}

w := streamio.NewWriter(func(p []byte) error {
return ss.Send(&proto.ExecResponse{
Data: p,
})
})

// TODO(camdencheek): set user agent from all grpc clients
execStatus, err := gs.Server.exec(ss.Context(), gs.Server.Logger, &internalReq, "unknown-grpc-client", w)
if err != nil {
if v := (&NotFoundError{}); errors.As(err, &v) {
s, err := status.New(codes.NotFound, "repo not found").WithDetails(&proto.NotFoundPayload{
Repo: req.GetRepo(),
CloneInProgress: v.Payload.CloneInProgress,
CloneProgress: v.Payload.CloneProgress,
})
if err != nil {
gs.Server.Logger.Error("failed to marshal status", log.Error(err))
return err
}
return s.Err()

} else if errors.Is(err, ErrInvalidCommand) {
return status.New(codes.InvalidArgument, "invalid command").Err()
}

return err
}

if execStatus.ExitStatus != 0 || execStatus.Err != nil {
s, err := status.New(codes.Unknown, execStatus.Err.Error()).WithDetails(&proto.ExecStatusPayload{
StatusCode: int32(execStatus.ExitStatus),
Stderr: execStatus.Stderr,
})
if err != nil {
gs.Server.Logger.Error("failed to marshal status", log.Error(err))
return err
}
return s.Err()
}

return nil
}
12 changes: 12 additions & 0 deletions cmd/gitserver/shared/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package shared

import (
"github.com/sourcegraph/sourcegraph/internal/debugserver"
)

// GRPCWebUIDebugEndpoint returns a debug endpoint that serves the GRPCWebUI that targets
// this gitserver instance.
func GRPCWebUIDebugEndpoint() debugserver.Endpoint {
addr := getAddr()
return debugserver.NewGRPCWebUIEndpoint(addr)
}
7 changes: 6 additions & 1 deletion cmd/gitserver/shared/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ type svc struct{}
func (svc) Name() string { return "gitserver" }

func (svc) Configure() (env.Config, []debugserver.Endpoint) {
return LoadConfig(), nil
c := LoadConfig()
endpoints := []debugserver.Endpoint{
GRPCWebUIDebugEndpoint(),
}

return c, endpoints
}

func (svc) Start(ctx context.Context, observationCtx *observation.Context, ready service.ReadyFunc, config env.Config) error {
Expand Down
35 changes: 26 additions & 9 deletions cmd/gitserver/shared/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/tidwall/gjson"
"golang.org/x/sync/semaphore"
"golang.org/x/time/rate"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"

"github.com/sourcegraph/sourcegraph/cmd/gitserver/server"
"github.com/sourcegraph/sourcegraph/internal/actor"
Expand All @@ -38,7 +40,10 @@ import (
"github.com/sourcegraph/sourcegraph/internal/extsvc/npm"
"github.com/sourcegraph/sourcegraph/internal/extsvc/pypi"
"github.com/sourcegraph/sourcegraph/internal/extsvc/rubygems"
"github.com/sourcegraph/sourcegraph/internal/gitserver/proto"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
"github.com/sourcegraph/sourcegraph/internal/hostname"
"github.com/sourcegraph/sourcegraph/internal/httpcli"
"github.com/sourcegraph/sourcegraph/internal/instrumentation"
Expand Down Expand Up @@ -142,6 +147,12 @@ func Main(ctx context.Context, observationCtx *observation.Context, ready servic
GlobalBatchLogSemaphore: semaphore.NewWeighted(int64(batchLogGlobalConcurrencyLimit)),
}

grpcServer := grpc.NewServer(defaults.ServerOptions(logger)...)
grpcServer.RegisterService(&proto.GitserverService_ServiceDesc, &server.GRPCServer{
Server: &gitserver,
})
reflection.Register(grpcServer)

gitserver.RegisterMetrics(observationCtx, db)

if tmpDir, err := gitserver.SetupAndClearTmp(); err != nil {
Expand All @@ -159,6 +170,7 @@ func Main(ctx context.Context, observationCtx *observation.Context, ready servic
handler = requestclient.HTTPMiddleware(handler)
handler = trace.HTTPMiddleware(logger, handler, conf.DefaultClient())
handler = instrumentation.HTTPMiddleware("", handler)
handler = internalgrpc.MultiplexHandlers(grpcServer, handler)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand All @@ -178,15 +190,7 @@ func Main(ctx context.Context, observationCtx *observation.Context, ready servic

gitserver.StartClonePipeline(ctx)

addr := os.Getenv("GITSERVER_ADDR")
if addr == "" {
port := "3178"
host := ""
if env.InsecureDev {
host = "127.0.0.1"
}
addr = net.JoinHostPort(host, port)
}
addr := getAddr()
srv := &http.Server{
Addr: addr,
Handler: handler,
Expand Down Expand Up @@ -587,3 +591,16 @@ func externalAddress() string {
// hostname is a prefix of the reachable address (see hostnameMatch).
return hostname.Get()
}

func getAddr() string {
addr := os.Getenv("GITSERVER_ADDR")
if addr == "" {
port := "3178"
host := ""
if env.InsecureDev {
host = "127.0.0.1"
}
addr = net.JoinHostPort(host, port)
}
return addr
}
6 changes: 5 additions & 1 deletion enterprise/cmd/gitserver/shared/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ type svc struct{}
func (svc) Name() string { return "gitserver" }

func (svc) Configure() (env.Config, []debugserver.Endpoint) {
return shared.LoadConfig(), nil
c := shared.LoadConfig()
endpoints := []debugserver.Endpoint{
shared.GRPCWebUIDebugEndpoint(),
}
return c, endpoints
}

func (svc) Start(ctx context.Context, observationCtx *observation.Context, ready service.ReadyFunc, config env.Config) error {
Expand Down
7 changes: 1 addition & 6 deletions internal/debugserver/grpcui.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,16 @@ import (
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
"github.com/sourcegraph/sourcegraph/lib/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

const gRPCWebUIPath = "/debug/grpcui"

// NewGRPCWebUIEndpoint returns a new Endpoint that serves a gRPC Web UI instance
// that targets the gRPC server specified by target.
func NewGRPCWebUIEndpoint(target string) Endpoint {
var opts []grpc.DialOption
opts = append(opts, defaults.DialOptions()...)
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))

var handler http.Handler = &grpcHandler{
target: target,
dialOpts: opts,
dialOpts: defaults.DialOptions(),
}

// gRPC Web UI expects to serve all of its resources
Expand Down
Loading