diff --git a/cmd/gitserver/server/server_grpc.go b/cmd/gitserver/server/server_grpc.go new file mode 100644 index 000000000000..51c756cf4df9 --- /dev/null +++ b/cmd/gitserver/server/server_grpc.go @@ -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 +} diff --git a/cmd/gitserver/shared/debug.go b/cmd/gitserver/shared/debug.go new file mode 100644 index 000000000000..aebce98693ea --- /dev/null +++ b/cmd/gitserver/shared/debug.go @@ -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) +} diff --git a/cmd/gitserver/shared/service.go b/cmd/gitserver/shared/service.go index 454bbc9b5215..ae777c9a98f3 100644 --- a/cmd/gitserver/shared/service.go +++ b/cmd/gitserver/shared/service.go @@ -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 { diff --git a/cmd/gitserver/shared/shared.go b/cmd/gitserver/shared/shared.go index 515e46699018..e5f2a4eb3539 100644 --- a/cmd/gitserver/shared/shared.go +++ b/cmd/gitserver/shared/shared.go @@ -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" @@ -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" @@ -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 { @@ -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() @@ -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, @@ -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 +} diff --git a/enterprise/cmd/gitserver/shared/service.go b/enterprise/cmd/gitserver/shared/service.go index 43489fc9b126..bc5ae987d2a7 100644 --- a/enterprise/cmd/gitserver/shared/service.go +++ b/enterprise/cmd/gitserver/shared/service.go @@ -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 { diff --git a/internal/debugserver/grpcui.go b/internal/debugserver/grpcui.go index 68f40e46a5cc..da1e3420ed0e 100644 --- a/internal/debugserver/grpcui.go +++ b/internal/debugserver/grpcui.go @@ -8,7 +8,6 @@ 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 = "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/debug/grpcui" @@ -16,13 +15,9 @@ const gRPCWebUIPath = "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/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 diff --git a/internal/gitserver/client.go b/internal/gitserver/client.go index 47079c912568..988ac5351061 100644 --- a/internal/gitserver/client.go +++ b/internal/gitserver/client.go @@ -27,6 +27,8 @@ import ( "go.opentelemetry.io/otel/attribute" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" + "google.golang.org/grpc" + "google.golang.org/grpc/status" sglog "github.com/sourcegraph/log" @@ -36,8 +38,12 @@ import ( "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/authz" "github.com/sourcegraph/sourcegraph/internal/conf" + "github.com/sourcegraph/sourcegraph/internal/featureflag" "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" + "github.com/sourcegraph/sourcegraph/internal/gitserver/proto" "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" + "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" + "github.com/sourcegraph/sourcegraph/internal/grpc/streamio" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/lazyregexp" "github.com/sourcegraph/sourcegraph/internal/observation" @@ -557,7 +563,7 @@ type badRequestError struct{ error } func (e badRequestError) BadRequest() bool { return true } -func (c *RemoteGitCommand) sendExec(ctx context.Context) (_ io.ReadCloser, _ http.Header, errRes error) { +func (c *RemoteGitCommand) sendExec(ctx context.Context) (_ io.ReadCloser, errRes error) { repoName := protocol.NormalizeRepo(c.repo) span, ctx := ot.StartSpanFromContext(ctx, "Client.sendExec") //nolint:staticcheck // OT is deprecated @@ -575,38 +581,131 @@ func (c *RemoteGitCommand) sendExec(ctx context.Context) (_ io.ReadCloser, _ htt // Check that ctx is not expired. if err := ctx.Err(); err != nil { deadlineExceededCounter.Inc() - return nil, nil, err + return nil, err } - req := &protocol.ExecRequest{ - Repo: repoName, - EnsureRevision: c.EnsureRevision(), - Args: c.args[1:], - Stdin: c.stdin, - NoTimeout: c.noTimeout, + if featureflag.FromContext(ctx).GetBoolOr("grpc", false) { + req := &proto.ExecRequest{ + Repo: string(repoName), + EnsureRevision: c.EnsureRevision(), + Args: c.args[1:], + Stdin: c.stdin, + NoTimeout: c.noTimeout, + } + addr, err := c.execer.AddrForRepo(ctx, repoName) + if err != nil { + return nil, err + } + + conn, err := grpc.DialContext(ctx, addr, defaults.DialOptions()...) + if err != nil { + return nil, err + } + + client := proto.NewGitserverServiceClient(conn) + stream, err := client.Exec(ctx, req) + if err != nil { + return nil, err + } + r := streamio.NewReader(func() ([]byte, error) { + msg, err := stream.Recv() + if err != nil { + + return nil, err + } + return msg.GetData(), nil + }) + + return &readCloseWrapper{r: r, closeFn: conn.Close}, err + + } else { + req := &protocol.ExecRequest{ + Repo: repoName, + EnsureRevision: c.EnsureRevision(), + Args: c.args[1:], + Stdin: c.stdin, + NoTimeout: c.noTimeout, + } + resp, err := c.execer.httpPost(ctx, repoName, "exec", req) + if err != nil { + return nil, err + } + + switch resp.StatusCode { + case http.StatusOK: + return &cmdReader{rc: resp.Body, trailer: resp.Trailer}, nil + + case http.StatusNotFound: + var payload protocol.NotFoundPayload + if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil { + resp.Body.Close() + return nil, err + } + resp.Body.Close() + return nil, &gitdomain.RepoNotExistError{Repo: repoName, CloneInProgress: payload.CloneInProgress, CloneProgress: payload.CloneProgress} + + default: + resp.Body.Close() + return nil, errors.Errorf("unexpected status code: %d", resp.StatusCode) + } } - resp, err := c.execFn(ctx, repoName, "exec", req) +} + +type readCloseWrapper struct { + r io.Reader + closeFn func() error +} + +func (r *readCloseWrapper) Read(p []byte) (int, error) { + n, err := r.r.Read(p) if err != nil { - return nil, nil, err + st, ok := status.FromError(err) + if !ok { + return n, err + } + + for _, detail := range st.Details() { + switch payload := detail.(type) { + case *proto.ExecStatusPayload: + return n, &CommandStatusError{ + Message: st.Message(), + Stderr: payload.Stderr, + StatusCode: payload.StatusCode, + } + case *proto.NotFoundPayload: + return n, &gitdomain.RepoNotExistError{ + Repo: api.RepoName(payload.Repo), + CloneInProgress: payload.CloneInProgress, + CloneProgress: payload.CloneProgress, + } + } + } } + return n, err +} - switch resp.StatusCode { - case http.StatusOK: - return resp.Body, resp.Trailer, nil +func (r *readCloseWrapper) Close() error { + return r.closeFn() +} - case http.StatusNotFound: - var payload protocol.NotFoundPayload - if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil { - resp.Body.Close() - return nil, nil, err - } - resp.Body.Close() - return nil, nil, &gitdomain.RepoNotExistError{Repo: repoName, CloneInProgress: payload.CloneInProgress, CloneProgress: payload.CloneProgress} +type CommandStatusError struct { + Message string + StatusCode int32 + Stderr string +} - default: - resp.Body.Close() - return nil, nil, errors.Errorf("unexpected status code: %d", resp.StatusCode) +func (c *CommandStatusError) Error() string { + stderr := c.Stderr + if len(stderr) > 100 { + stderr = stderr[:100] + "... (truncated)" + } + if c.Message != "" { + return fmt.Sprintf("%s (stderr: %q)", c.Message, stderr) + } + if c.StatusCode != 0 { + return fmt.Sprintf("non-zero exit status: %d (stderr: %q)", c.StatusCode, stderr) } + return stderr } func (c *clientImplementor) Search(ctx context.Context, args *protocol.SearchRequest, onMatches func([]protocol.CommitMatch)) (limitHit bool, err error) { @@ -878,7 +977,7 @@ func (c *clientImplementor) gitCommand(repo api.RepoName, arg ...string) GitComm } return &RemoteGitCommand{ repo: repo, - execFn: c.httpPost, + execer: c, args: append([]string{git}, arg...), } } diff --git a/internal/gitserver/client_test.go b/internal/gitserver/client_test.go index 708ede6a0245..ce5d3df361ed 100644 --- a/internal/gitserver/client_test.go +++ b/internal/gitserver/client_test.go @@ -7,6 +7,9 @@ import ( "encoding/base64" "encoding/json" "fmt" + + "github.com/sourcegraph/log/logtest" + "io" "net/http" "net/http/httptest" @@ -19,6 +22,11 @@ import ( "testing" "time" + "github.com/sourcegraph/sourcegraph/internal/gitserver/proto" + internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc" + "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" + "google.golang.org/grpc" + "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/schema" @@ -26,8 +34,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/sourcegraph/log/logtest" - "github.com/sourcegraph/sourcegraph/cmd/gitserver/server" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/database" @@ -437,7 +443,7 @@ func TestClient_ResolveRevisions(t *testing.T) { }} db := newMockDB() - srv := httptest.NewServer((&server.Server{ + s := server.Server{ Logger: logtest.Scoped(t), ReposDir: filepath.Join(root, "repos"), GetRemoteURLFunc: func(_ context.Context, name api.RepoName) (string, error) { @@ -447,7 +453,14 @@ func TestClient_ResolveRevisions(t *testing.T) { return &server.GitRepoSyncer{}, nil }, DB: db, - }).Handler()) + } + + grpcServer := grpc.NewServer(defaults.ServerOptions(logtest.Scoped(t))...) + grpcServer.RegisterService(&proto.GitserverService_ServiceDesc, &server.GRPCServer{Server: &s}) + + handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) + srv := httptest.NewServer(handler) + defer srv.Close() u, _ := url.Parse(srv.URL) diff --git a/internal/gitserver/git_command.go b/internal/gitserver/git_command.go index 183b35af714b..7563594c4d64 100644 --- a/internal/gitserver/git_command.go +++ b/internal/gitserver/git_command.go @@ -168,35 +168,36 @@ type RemoteGitCommand struct { stdin []byte noTimeout bool exitStatus int - execFn func(ctx context.Context, repo api.RepoName, op string, payload any) (resp *http.Response, err error) + execer execer +} + +type execer interface { + httpPost(ctx context.Context, repo api.RepoName, op string, payload any) (resp *http.Response, err error) + AddrForRepo(ctx context.Context, repo api.RepoName) (string, error) } // DividedOutput runs the command and returns its standard output and standard error. func (c *RemoteGitCommand) DividedOutput(ctx context.Context) ([]byte, []byte, error) { - rc, trailer, err := c.sendExec(ctx) + rc, err := c.sendExec(ctx) if err != nil { return nil, nil, err } + defer rc.Close() stdout, err := io.ReadAll(rc) if err != nil { + if v := (&CommandStatusError{}); errors.As(err, &v) { + c.exitStatus = int(v.StatusCode) + if v.Message != "" { + return stdout, []byte(v.Stderr), errors.New(v.Message) + } else { + return stdout, []byte(v.Stderr), v + } + } return nil, nil, errors.Wrap(err, "reading exec output") } - if err := rc.Close(); err != nil { - return nil, nil, errors.Wrap(err, "closing exec reader") - } - c.exitStatus, err = strconv.Atoi(trailer.Get("X-Exec-Exit-Status")) - if err != nil { - return nil, nil, err - } - - stderr := []byte(trailer.Get("X-Exec-Stderr")) - if errorMsg := trailer.Get("X-Exec-Error"); errorMsg != "" { - return stdout, stderr, errors.New(errorMsg) - } - - return stdout, stderr, nil + return stdout, nil, nil } // Output runs the command and returns its standard output. @@ -233,15 +234,7 @@ func (c *RemoteGitCommand) String() string { return fmt.Sprintf("%q", c.args) } // non-zero return value, Read returns a non io.EOF error. Do not pass in a // started command. func (c *RemoteGitCommand) StdoutReader(ctx context.Context) (io.ReadCloser, error) { - rc, trailer, err := c.sendExec(ctx) - if err != nil { - return nil, err - } - - return &cmdReader{ - rc: rc, - trailer: trailer, - }, nil + return c.sendExec(ctx) } type cmdReader struct { @@ -252,17 +245,32 @@ type cmdReader struct { func (c *cmdReader) Read(p []byte) (int, error) { n, err := c.rc.Read(p) if err == io.EOF { - stderr := c.trailer.Get("X-Exec-Stderr") - if len(stderr) > 100 { - stderr = stderr[:100] + "... (truncated)" + statusCode, err := strconv.Atoi(c.trailer.Get("X-Exec-Exit-Status")) + if err != nil { + return n, errors.Wrap(err, "failed to parse exit status code") } - if errorMsg := c.trailer.Get("X-Exec-Error"); errorMsg != "" { - return 0, errors.Errorf("%s (stderr: %q)", errorMsg, stderr) + + errorMessage := c.trailer.Get("X-Exec-Error") + + // did the command exit cleanly? + if statusCode == 0 && errorMessage == "" { + // yes - propagate io.EOF + + return n, io.EOF } - if exitStatus := c.trailer.Get("X-Exec-Exit-Status"); exitStatus != "0" { - return 0, errors.Errorf("non-zero exit status: %s (stderr: %q)", exitStatus, stderr) + + // no - report it + + stderr := c.trailer.Get("X-Exec-Stderr") + err = &CommandStatusError{ + Stderr: stderr, + StatusCode: int32(statusCode), + Message: errorMessage, } + + return n, err } + return n, err } diff --git a/internal/gitserver/integration_tests/test_utils.go b/internal/gitserver/integration_tests/test_utils.go index 2b4c5bbabbfe..cc5c15e589c3 100644 --- a/internal/gitserver/integration_tests/test_utils.go +++ b/internal/gitserver/integration_tests/test_utils.go @@ -11,15 +11,20 @@ import ( "strings" "testing" + "golang.org/x/sync/semaphore" + "google.golang.org/grpc" + sglog "github.com/sourcegraph/log" "github.com/sourcegraph/sourcegraph/cmd/gitserver/server" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/database" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/gitserver/proto" + internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc" + "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/observation" - "golang.org/x/sync/semaphore" ) var root string @@ -51,20 +56,26 @@ func InitGitserver() { gr := database.NewMockGitserverRepoStore() db.GitserverReposFunc.SetDefaultReturn(gr) + s := server.Server{ + Logger: sglog.Scoped("server", "the gitserver service"), + ObservationCtx: &observation.TestContext, + ReposDir: filepath.Join(root, "repos"), + GetRemoteURLFunc: func(ctx context.Context, name api.RepoName) (string, error) { + return filepath.Join(root, "remotes", string(name)), nil + }, + GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) { + return &server.GitRepoSyncer{}, nil + }, + GlobalBatchLogSemaphore: semaphore.NewWeighted(32), + DB: db, + } + + grpcServer := grpc.NewServer(defaults.ServerOptions(logger)...) + grpcServer.RegisterService(&proto.GitserverService_ServiceDesc, &server.GRPCServer{Server: &s}) + handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) + srv := &http.Server{ - Handler: (&server.Server{ - Logger: sglog.Scoped("server", "the gitserver service"), - ObservationCtx: &observation.TestContext, - ReposDir: filepath.Join(root, "repos"), - GetRemoteURLFunc: func(ctx context.Context, name api.RepoName) (string, error) { - return filepath.Join(root, "remotes", string(name)), nil - }, - GetVCSSyncer: func(ctx context.Context, name api.RepoName) (server.VCSSyncer, error) { - return &server.GitRepoSyncer{}, nil - }, - GlobalBatchLogSemaphore: semaphore.NewWeighted(32), - DB: db, - }).Handler(), + Handler: handler, } go func() { if err := srv.Serve(l); err != nil { diff --git a/internal/gitserver/proto/buf.gen.yaml b/internal/gitserver/proto/buf.gen.yaml new file mode 100644 index 000000000000..ca493510d2ef --- /dev/null +++ b/internal/gitserver/proto/buf.gen.yaml @@ -0,0 +1,11 @@ +# Configuration file for https://buf.build/, which we use for Protobuf code generation. +version: v1 +plugins: + - plugin: buf.build/protocolbuffers/go + out: . + opt: + - paths=source_relative + - plugin: buf.build/grpc/go + out: . + opt: + - paths=source_relative diff --git a/internal/gitserver/proto/gitserver.pb.go b/internal/gitserver/proto/gitserver.pb.go new file mode 100644 index 000000000000..425738008315 --- /dev/null +++ b/internal/gitserver/proto/gitserver.pb.go @@ -0,0 +1,411 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: gitserver.proto + +package proto + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ExecRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` + EnsureRevision string `protobuf:"bytes,2,opt,name=ensure_revision,json=ensureRevision,proto3" json:"ensure_revision,omitempty"` + Args []string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` + Stdin []byte `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"` + NoTimeout bool `protobuf:"varint,5,opt,name=no_timeout,json=noTimeout,proto3" json:"no_timeout,omitempty"` +} + +func (x *ExecRequest) Reset() { + *x = ExecRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecRequest) ProtoMessage() {} + +func (x *ExecRequest) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecRequest.ProtoReflect.Descriptor instead. +func (*ExecRequest) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{0} +} + +func (x *ExecRequest) GetRepo() string { + if x != nil { + return x.Repo + } + return "" +} + +func (x *ExecRequest) GetEnsureRevision() string { + if x != nil { + return x.EnsureRevision + } + return "" +} + +func (x *ExecRequest) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *ExecRequest) GetStdin() []byte { + if x != nil { + return x.Stdin + } + return nil +} + +func (x *ExecRequest) GetNoTimeout() bool { + if x != nil { + return x.NoTimeout + } + return false +} + +type ExecResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *ExecResponse) Reset() { + *x = ExecResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecResponse) ProtoMessage() {} + +func (x *ExecResponse) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecResponse.ProtoReflect.Descriptor instead. +func (*ExecResponse) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{1} +} + +func (x *ExecResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type NotFoundPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` + CloneInProgress bool `protobuf:"varint,2,opt,name=clone_in_progress,json=cloneInProgress,proto3" json:"clone_in_progress,omitempty"` + CloneProgress string `protobuf:"bytes,3,opt,name=clone_progress,json=cloneProgress,proto3" json:"clone_progress,omitempty"` +} + +func (x *NotFoundPayload) Reset() { + *x = NotFoundPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotFoundPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotFoundPayload) ProtoMessage() {} + +func (x *NotFoundPayload) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotFoundPayload.ProtoReflect.Descriptor instead. +func (*NotFoundPayload) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{2} +} + +func (x *NotFoundPayload) GetRepo() string { + if x != nil { + return x.Repo + } + return "" +} + +func (x *NotFoundPayload) GetCloneInProgress() bool { + if x != nil { + return x.CloneInProgress + } + return false +} + +func (x *NotFoundPayload) GetCloneProgress() string { + if x != nil { + return x.CloneProgress + } + return "" +} + +type ExecStatusPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StatusCode int32 `protobuf:"varint,1,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` + Stderr string `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` +} + +func (x *ExecStatusPayload) Reset() { + *x = ExecStatusPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecStatusPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecStatusPayload) ProtoMessage() {} + +func (x *ExecStatusPayload) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecStatusPayload.ProtoReflect.Descriptor instead. +func (*ExecStatusPayload) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{3} +} + +func (x *ExecStatusPayload) GetStatusCode() int32 { + if x != nil { + return x.StatusCode + } + return 0 +} + +func (x *ExecStatusPayload) GetStderr() string { + if x != nil { + return x.Stderr + } + return "" +} + +var File_gitserver_proto protoreflect.FileDescriptor + +var file_gitserver_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x09, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, + 0x0b, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, + 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6e, 0x73, 0x75, 0x72, + 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, + 0x64, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x78, 0x0a, 0x0f, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, + 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x2a, 0x0a, + 0x11, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x49, + 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, + 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x22, 0x4c, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x32, 0x4f, + 0x0a, 0x10, 0x47, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x45, 0x78, 0x65, 0x63, 0x12, 0x16, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, + 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_gitserver_proto_rawDescOnce sync.Once + file_gitserver_proto_rawDescData = file_gitserver_proto_rawDesc +) + +func file_gitserver_proto_rawDescGZIP() []byte { + file_gitserver_proto_rawDescOnce.Do(func() { + file_gitserver_proto_rawDescData = protoimpl.X.CompressGZIP(file_gitserver_proto_rawDescData) + }) + return file_gitserver_proto_rawDescData +} + +var file_gitserver_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_gitserver_proto_goTypes = []interface{}{ + (*ExecRequest)(nil), // 0: gitserver.ExecRequest + (*ExecResponse)(nil), // 1: gitserver.ExecResponse + (*NotFoundPayload)(nil), // 2: gitserver.NotFoundPayload + (*ExecStatusPayload)(nil), // 3: gitserver.ExecStatusPayload +} +var file_gitserver_proto_depIdxs = []int32{ + 0, // 0: gitserver.GitserverService.Exec:input_type -> gitserver.ExecRequest + 1, // 1: gitserver.GitserverService.Exec:output_type -> gitserver.ExecResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_gitserver_proto_init() } +func file_gitserver_proto_init() { + if File_gitserver_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_gitserver_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotFoundPayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecStatusPayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_gitserver_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_gitserver_proto_goTypes, + DependencyIndexes: file_gitserver_proto_depIdxs, + MessageInfos: file_gitserver_proto_msgTypes, + }.Build() + File_gitserver_proto = out.File + file_gitserver_proto_rawDesc = nil + file_gitserver_proto_goTypes = nil + file_gitserver_proto_depIdxs = nil +} diff --git a/internal/gitserver/proto/gitserver.proto b/internal/gitserver/proto/gitserver.proto new file mode 100644 index 000000000000..4209596bba0d --- /dev/null +++ b/internal/gitserver/proto/gitserver.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package gitserver; + +option go_package = "github.com/sourcegraph/sourcegraph/internal/gitserver/proto"; + +service GitserverService { + rpc Exec(ExecRequest) returns (stream ExecResponse) {} +} + +message ExecRequest { + string repo = 1; + string ensure_revision = 2; + repeated string args = 3; + bytes stdin = 4; + bool no_timeout = 5; +} + +message ExecResponse { + bytes data = 1; +} + +message NotFoundPayload { + string repo = 1; + bool clone_in_progress = 2; + string clone_progress = 3; +} + +message ExecStatusPayload { + int32 status_code = 1; + string stderr = 2; +} diff --git a/internal/gitserver/proto/gitserver_grpc.pb.go b/internal/gitserver/proto/gitserver_grpc.pb.go new file mode 100644 index 000000000000..b26595c1a501 --- /dev/null +++ b/internal/gitserver/proto/gitserver_grpc.pb.go @@ -0,0 +1,133 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: gitserver.proto + +package proto + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// GitserverServiceClient is the client API for GitserverService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type GitserverServiceClient interface { + Exec(ctx context.Context, in *ExecRequest, opts ...grpc.CallOption) (GitserverService_ExecClient, error) +} + +type gitserverServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewGitserverServiceClient(cc grpc.ClientConnInterface) GitserverServiceClient { + return &gitserverServiceClient{cc} +} + +func (c *gitserverServiceClient) Exec(ctx context.Context, in *ExecRequest, opts ...grpc.CallOption) (GitserverService_ExecClient, error) { + stream, err := c.cc.NewStream(ctx, &GitserverService_ServiceDesc.Streams[0], "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/gitserver.GitserverService/Exec", opts...) + if err != nil { + return nil, err + } + x := &gitserverServiceExecClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type GitserverService_ExecClient interface { + Recv() (*ExecResponse, error) + grpc.ClientStream +} + +type gitserverServiceExecClient struct { + grpc.ClientStream +} + +func (x *gitserverServiceExecClient) Recv() (*ExecResponse, error) { + m := new(ExecResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GitserverServiceServer is the server API for GitserverService service. +// All implementations must embed UnimplementedGitserverServiceServer +// for forward compatibility +type GitserverServiceServer interface { + Exec(*ExecRequest, GitserverService_ExecServer) error + mustEmbedUnimplementedGitserverServiceServer() +} + +// UnimplementedGitserverServiceServer must be embedded to have forward compatible implementations. +type UnimplementedGitserverServiceServer struct { +} + +func (UnimplementedGitserverServiceServer) Exec(*ExecRequest, GitserverService_ExecServer) error { + return status.Errorf(codes.Unimplemented, "method Exec not implemented") +} +func (UnimplementedGitserverServiceServer) mustEmbedUnimplementedGitserverServiceServer() {} + +// UnsafeGitserverServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GitserverServiceServer will +// result in compilation errors. +type UnsafeGitserverServiceServer interface { + mustEmbedUnimplementedGitserverServiceServer() +} + +func RegisterGitserverServiceServer(s grpc.ServiceRegistrar, srv GitserverServiceServer) { + s.RegisterService(&GitserverService_ServiceDesc, srv) +} + +func _GitserverService_Exec_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(ExecRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(GitserverServiceServer).Exec(m, &gitserverServiceExecServer{stream}) +} + +type GitserverService_ExecServer interface { + Send(*ExecResponse) error + grpc.ServerStream +} + +type gitserverServiceExecServer struct { + grpc.ServerStream +} + +func (x *gitserverServiceExecServer) Send(m *ExecResponse) error { + return x.ServerStream.SendMsg(m) +} + +// GitserverService_ServiceDesc is the grpc.ServiceDesc for GitserverService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var GitserverService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "gitserver.GitserverService", + HandlerType: (*GitserverServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Exec", + Handler: _GitserverService_Exec_Handler, + ServerStreams: true, + }, + }, + Metadata: "gitserver.proto", +} diff --git a/internal/grpc/defaults/defaults.go b/internal/grpc/defaults/defaults.go index b34a00a974af..d7442723b341 100644 --- a/internal/grpc/defaults/defaults.go +++ b/internal/grpc/defaults/defaults.go @@ -7,6 +7,7 @@ package defaults import ( "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/sourcegraph/log" "github.com/sourcegraph/sourcegraph/internal/actor" @@ -22,6 +23,7 @@ func DialOptions() []grpc.DialOption { // because these options depend on some globals (tracer, trace sampling) // that are not initialized during init time. return []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithChainStreamInterceptor( internalgrpc.StreamClientPropagator(actor.ActorPropagator{}), internalgrpc.StreamClientPropagator(policy.ShouldTracePropagator{}), diff --git a/internal/search/searcher/client_grpc.go b/internal/search/searcher/client_grpc.go index 15ccbdcd29d7..85cdde16fd8d 100644 --- a/internal/search/searcher/client_grpc.go +++ b/internal/search/searcher/client_grpc.go @@ -9,13 +9,12 @@ import ( "time" "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" "github.com/sourcegraph/sourcegraph/cmd/searcher/protocol" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/endpoint" "github.com/sourcegraph/sourcegraph/internal/errcode" - grpcdefaults "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" + "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" "github.com/sourcegraph/sourcegraph/internal/search" proto "github.com/sourcegraph/sourcegraph/internal/searcher/v1" "github.com/sourcegraph/sourcegraph/lib/errors" @@ -83,11 +82,7 @@ func SearchGRPC( return false, errors.Wrap(err, "failed to parse URL") } - var opts []grpc.DialOption - opts = append(opts, grpcdefaults.DialOptions()...) - opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) - - clientConn, err := grpc.DialContext(ctx, parsed.Host, opts...) + clientConn, err := grpc.DialContext(ctx, parsed.Host, defaults.DialOptions()...) if err != nil { return false, err } diff --git a/internal/symbols/client.go b/internal/symbols/client.go index 37239b92e893..38f4a64ff153 100644 --- a/internal/symbols/client.go +++ b/internal/symbols/client.go @@ -17,7 +17,6 @@ import ( otlog "github.com/opentracing/opentracing-go/log" "github.com/sourcegraph/go-ctags" "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" "github.com/sourcegraph/sourcegraph/internal/actor" "github.com/sourcegraph/sourcegraph/internal/api" @@ -522,14 +521,7 @@ func (c *Client) dialGRPC(ctx context.Context, repository api.RepoName) (*grpc.C return nil, errors.Wrap(err, "parsing symbols service URL") } - opts := []grpc.DialOption{ - // 🚨 SECURITY: We use insecure connections to the symbols service. During the - // grpc prototyping phase - we're leaving TLS authentication out of scope. - grpc.WithTransportCredentials(insecure.NewCredentials()), - } - - opts = append(opts, defaults.DialOptions()...) - conn, err := grpc.DialContext(ctx, u.Host, opts...) + conn, err := grpc.DialContext(ctx, u.Host, defaults.DialOptions()...) if err != nil { return nil, errors.Wrap(err, "dialing symbols GRPC service") }