diff --git a/buildenv/envs.go b/buildenv/envs.go index 67cb8f801e..0c5f86d031 100644 --- a/buildenv/envs.go +++ b/buildenv/envs.go @@ -143,6 +143,10 @@ type Environment struct { // services used by IAP enabled HTTP paths. // map[backend-service-name]service_id iapServiceIDs map[string]string + + // GomoteTransferBucket is the bucket used by the gomote GRPC service + // to transfer files between gomote clients and the gomote instances. + GomoteTransferBucket string } // ComputePrefix returns the URI prefix for Compute Engine resources in a project. @@ -304,6 +308,7 @@ var Production = &Environment{ "coordinator-internal-iap": "7963570695201399464", "relui-internal": "155577380958854618", }, + GomoteTransferBucket: "gomote-transfer", } var Development = &Environment{ diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go index abf8e3e9ab..572d499073 100644 --- a/cmd/coordinator/coordinator.go +++ b/cmd/coordinator/coordinator.go @@ -66,6 +66,7 @@ import ( "golang.org/x/build/revdial/v2" "golang.org/x/build/types" "golang.org/x/time/rate" + "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -343,6 +344,7 @@ func main() { } sshCA := mustRetrieveSSHCertificateAuthority() + var gomoteBucket string var opts []grpc.ServerOption if *buildEnvName == "" && *mode != "dev" && metadata.OnGCE() { projectID, err := metadata.ProjectID() @@ -350,6 +352,7 @@ func main() { log.Fatalf("metadata.ProjectID() = %v", err) } env := buildenv.ByProjectID(projectID) + gomoteBucket = env.GomoteTransferBucket var coordinatorBackend, serviceID = "coordinator-internal-iap", "" if serviceID = env.IAPServiceID(coordinatorBackend); serviceID == "" { log.Fatalf("unable to retrieve Service ID for backend service=%q", coordinatorBackend) @@ -363,7 +366,7 @@ func main() { dashV1 := legacydash.Handler(gce.GoDSClient(), maintnerClient, string(masterKey()), grpcServer) dashV2 := &builddash.Handler{Datastore: gce.GoDSClient(), Maintner: maintnerClient} gs := &gRPCServer{dashboardURL: "https://build.golang.org"} - gomoteServer := gomote.New(remote.NewSessionPool(context.Background()), sched, sshCA) + gomoteServer := gomote.New(remote.NewSessionPool(context.Background()), sched, sshCA, gomoteBucket, mustStorageClient()) protos.RegisterCoordinatorServer(grpcServer, gs) gomoteprotos.RegisterGomoteServiceServer(grpcServer, gomoteServer) mux.HandleFunc("/", grpcHandlerFunc(grpcServer, handleStatus)) // Serve a status page at farmer.golang.org. @@ -2202,3 +2205,14 @@ func mustRetrieveSSHCertificateAuthority() (privateKey []byte) { } return } + +func mustStorageClient() *storage.Client { + if metadata.OnGCE() { + return pool.NewGCEConfiguration().StorageClient() + } + storageClient, err := storage.NewClient(context.Background(), option.WithoutAuthentication()) + if err != nil { + log.Fatalf("unable to create storage client: %s", err) + } + return storageClient +} diff --git a/internal/gomote/gomote.go b/internal/gomote/gomote.go index d0fc8ab929..acbd158619 100644 --- a/internal/gomote/gomote.go +++ b/internal/gomote/gomote.go @@ -16,6 +16,8 @@ import ( "strings" "time" + "cloud.google.com/go/storage" + "github.com/google/uuid" "golang.org/x/build/buildlet" "golang.org/x/build/dashboard" "golang.org/x/build/internal/access" @@ -34,24 +36,33 @@ type scheduler interface { GetBuildlet(ctx context.Context, si *schedule.SchedItem) (buildlet.Client, error) } +// bucketHandle interface used to enable testing of the storage.bucketHandle. +type bucketHandle interface { + GenerateSignedPostPolicyV4(object string, opts *storage.PostPolicyV4Options) (*storage.PostPolicyV4, error) +} + // Server is a gomote server implementation. type Server struct { // embed the unimplemented server. protos.UnimplementedGomoteServiceServer + bucket bucketHandle buildlets *remote.SessionPool + gceBucketName string scheduler scheduler sshCertificateAuthority ssh.Signer } // New creates a gomote server. If the rawCAPriKey is invalid, the program will exit. -func New(rsp *remote.SessionPool, sched *schedule.Scheduler, rawCAPriKey []byte) *Server { +func New(rsp *remote.SessionPool, sched *schedule.Scheduler, rawCAPriKey []byte, gomoteGCSBucket string, storageClient *storage.Client) *Server { signer, err := ssh.ParsePrivateKey(rawCAPriKey) if err != nil { log.Fatalf("unable to parse raw certificate authority private key into signer=%s", err) } return &Server{ + bucket: storageClient.Bucket(gomoteGCSBucket), buildlets: rsp, + gceBucketName: gomoteGCSBucket, scheduler: sched, sshCertificateAuthority: signer, } @@ -336,6 +347,39 @@ func (s *Server) SignSSHKey(ctx context.Context, req *protos.SignSSHKeyRequest) }, nil } +// UploadFile creates a URL and a set of HTTP post fields which are used to upload a file to a staging GCS bucket. Uploaded files are made available to the +// gomote instances via a subsequent call to one of the WriteFromURL endpoints. +func (s *Server) UploadFile(ctx context.Context, req *protos.UploadFileRequest) (*protos.UploadFileResponse, error) { + _, err := access.IAPFromContext(ctx) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "request does not contain the required authentication") + } + url, fields, err := s.signURLForUpload(uuid.NewString()) + if err != nil { + log.Printf("unable to create signed URL: %s", err) + return nil, status.Errorf(codes.Internal, "unable to create signed url") + } + return &protos.UploadFileResponse{ + Url: url, + Fields: fields, + }, nil +} + +// signURLForUpload generates a signed URL and a set of http Post fields to be used to upload an object to GCS without authenticating. +func (s *Server) signURLForUpload(object string) (url string, fields map[string]string, err error) { + if object == "" { + return "", nil, errors.New("invalid object name") + } + pv4, err := s.bucket.GenerateSignedPostPolicyV4(object, &storage.PostPolicyV4Options{ + Expires: time.Now().Add(10 * time.Minute), + Insecure: false, + }) + if err != nil { + return "", nil, fmt.Errorf("unable to generate signed url: %w", err) + } + return pv4.URL, pv4.Fields, nil +} + // WriteTGZFromURL will instruct the gomote instance to download the tar.gz from the provided URL. The tar.gz file will be unpacked in the work directory // relative to the directory provided. func (s *Server) WriteTGZFromURL(ctx context.Context, req *protos.WriteTGZFromURLRequest) (*protos.WriteTGZFromURLResponse, error) { diff --git a/internal/gomote/gomote_test.go b/internal/gomote/gomote_test.go index db0f2dec87..7a6f4b452d 100644 --- a/internal/gomote/gomote_test.go +++ b/internal/gomote/gomote_test.go @@ -9,11 +9,13 @@ package gomote import ( "context" + "errors" "fmt" "io" "testing" "time" + "cloud.google.com/go/storage" "github.com/google/go-cmp/cmp" "golang.org/x/build/internal/access" "golang.org/x/build/internal/coordinator/remote" @@ -27,13 +29,17 @@ import ( "google.golang.org/protobuf/testing/protocmp" ) +const testBucketName = "unit-testing-bucket" + func fakeGomoteServer(t *testing.T, ctx context.Context) protos.GomoteServiceServer { signer, err := ssh.ParsePrivateKey([]byte(devCertCAPrivate)) if err != nil { t.Fatalf("unable to parse raw certificate authority private key into signer=%s", err) } return &Server{ + bucket: &fakeBucketHandler{bucketName: testBucketName}, buildlets: remote.NewSessionPool(ctx), + gceBucketName: testBucketName, scheduler: schedule.NewFake(), sshCertificateAuthority: signer, } @@ -675,6 +681,48 @@ func TestSignSSHKeyError(t *testing.T) { } } +func TestUploadFile(t *testing.T) { + ctx := access.FakeContextWithOutgoingIAPAuth(context.Background(), fakeIAP()) + client := setupGomoteTest(t, context.Background()) + _ = mustCreateInstance(t, client, fakeIAP()) + if _, err := client.UploadFile(ctx, &protos.UploadFileRequest{}); err != nil { + t.Fatalf("client.UploadFile(ctx, req) = response, %s; want no error", err) + } +} + +func TestUploadFileError(t *testing.T) { + // This test will create a gomote instance and attempt to call UploadFile. + // If overrideID is set to true, the test will use a different gomoteID than the + // the one created for the test. + testCases := []struct { + desc string + ctx context.Context + overrideID bool + filename string + wantCode codes.Code + }{ + { + desc: "unauthenticated request", + ctx: context.Background(), + wantCode: codes.Unauthenticated, + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + client := setupGomoteTest(t, context.Background()) + _ = mustCreateInstance(t, client, fakeIAP()) + req := &protos.UploadFileRequest{} + got, err := client.UploadFile(tc.ctx, req) + if err != nil && status.Code(err) != tc.wantCode { + t.Fatalf("unexpected error: %s; want %s", err, tc.wantCode) + } + if err == nil { + t.Fatalf("client.UploadFile(ctx, %v) = %v, nil; want error", req, got) + } + }) + } +} + func TestWriteTGZFromURL(t *testing.T) { ctx := access.FakeContextWithOutgoingIAPAuth(context.Background(), fakeIAP()) client := setupGomoteTest(t, context.Background()) @@ -871,3 +919,17 @@ OfjWFhdu6e4JYiVfN7ZYAAAAE3Rlc3R1c2VyQGdvbGFuZy5vcmcBAg== // devCertCAPublic is a public SSH CA certificate to be used for development. devCertCAPublic = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJV3YUncNv+hXneJEO3VEuxxOfjWFhdu6e4JYiVfN7ZY testuser@golang.org` ) + +type fakeBucketHandler struct{ bucketName string } + +func (fbc *fakeBucketHandler) GenerateSignedPostPolicyV4(object string, opts *storage.PostPolicyV4Options) (*storage.PostPolicyV4, error) { + if object == "" || opts == nil { + return nil, errors.New("invalid arguments") + } + return &storage.PostPolicyV4{ + URL: fmt.Sprintf("https://localhost/%s/%s", fbc.bucketName, object), + Fields: map[string]string{ + "x-permission-to-post": "granted", + }, + }, nil +} diff --git a/internal/gomote/protos/gomote.pb.go b/internal/gomote/protos/gomote.pb.go index 611af7abce..75e5ad9aac 100644 --- a/internal/gomote/protos/gomote.pb.go +++ b/internal/gomote/protos/gomote.pb.go @@ -1194,15 +1194,15 @@ func (x *SignSSHKeyResponse) GetSignedPublicSshKey() []byte { return nil } -// WriteTGZRequest specifies the data needed to expand a tar and zipped file onto the file system of a gomote instance. -type WriteTGZRequest struct { +// UploadFileRequest specifies the data needed to create a request to upload an object to GCS. +type UploadFileRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *WriteTGZRequest) Reset() { - *x = WriteTGZRequest{} +func (x *UploadFileRequest) Reset() { + *x = UploadFileRequest{} if protoimpl.UnsafeEnabled { mi := &file_gomote_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1210,13 +1210,13 @@ func (x *WriteTGZRequest) Reset() { } } -func (x *WriteTGZRequest) String() string { +func (x *UploadFileRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*WriteTGZRequest) ProtoMessage() {} +func (*UploadFileRequest) ProtoMessage() {} -func (x *WriteTGZRequest) ProtoReflect() protoreflect.Message { +func (x *UploadFileRequest) ProtoReflect() protoreflect.Message { mi := &file_gomote_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1228,20 +1228,25 @@ func (x *WriteTGZRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use WriteTGZRequest.ProtoReflect.Descriptor instead. -func (*WriteTGZRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use UploadFileRequest.ProtoReflect.Descriptor instead. +func (*UploadFileRequest) Descriptor() ([]byte, []int) { return file_gomote_proto_rawDescGZIP(), []int{21} } -// WriteTGZResponse contains the results from expanding a tar and zipped file onto the file system of a gomote instance. -type WriteTGZResponse struct { +// UploadFileResponse contains the results from a request to upload an object to GCS. +type UploadFileResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // URL to post file to. + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + // Form fields used when http posting files to GCS. + Fields map[string]string `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } -func (x *WriteTGZResponse) Reset() { - *x = WriteTGZResponse{} +func (x *UploadFileResponse) Reset() { + *x = UploadFileResponse{} if protoimpl.UnsafeEnabled { mi := &file_gomote_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1249,13 +1254,13 @@ func (x *WriteTGZResponse) Reset() { } } -func (x *WriteTGZResponse) String() string { +func (x *UploadFileResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*WriteTGZResponse) ProtoMessage() {} +func (*UploadFileResponse) ProtoMessage() {} -func (x *WriteTGZResponse) ProtoReflect() protoreflect.Message { +func (x *UploadFileResponse) ProtoReflect() protoreflect.Message { mi := &file_gomote_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1267,11 +1272,25 @@ func (x *WriteTGZResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use WriteTGZResponse.ProtoReflect.Descriptor instead. -func (*WriteTGZResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use UploadFileResponse.ProtoReflect.Descriptor instead. +func (*UploadFileResponse) Descriptor() ([]byte, []int) { return file_gomote_proto_rawDescGZIP(), []int{22} } +func (x *UploadFileResponse) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *UploadFileResponse) GetFields() map[string]string { + if x != nil { + return x.Fields + } + return nil +} + // WriteTGZFromURLRequest specifies the data needed to retrieve a file and expand it onto the file system of a gomote instance. // It instructs the buildlet to download the tar.gz file from the url and write it to a directory, a relative directory from the workdir. // If the directory is empty, they're placed at the root of the buildlet's work directory. @@ -1479,80 +1498,90 @@ var file_gomote_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x53, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x22, 0x11, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x65, 0x0a, 0x16, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, - 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x6f, 0x6d, - 0x6f, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x6f, - 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, - 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xb6, 0x07, 0x0a, 0x0d, 0x47, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x53, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x73, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x73, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0e, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x4e, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x69, 0x76, - 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x61, 0x64, 0x54, 0x47, 0x5a, 0x12, 0x16, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x61, - 0x64, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x48, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, - 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0a, 0x53, 0x69, - 0x67, 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x73, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x53, 0x69, 0x67, - 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x41, 0x0a, 0x08, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x12, 0x17, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x28, 0x01, 0x12, 0x54, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, - 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x6f, - 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x6f, 0x6d, 0x6f, 0x74, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x53, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x22, 0x13, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, + 0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x3e, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x65, 0x0a, 0x16, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, + 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, + 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x67, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x32, 0xba, 0x07, 0x0a, 0x0d, 0x47, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x54, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x72, + 0x6f, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, + 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, + 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, + 0x69, 0x76, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x61, 0x64, 0x54, 0x47, 0x5a, 0x12, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x54, 0x47, 0x5a, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, + 0x65, 0x61, 0x64, 0x54, 0x47, 0x5a, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x48, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0a, + 0x53, 0x69, 0x67, 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x73, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x53, 0x53, 0x48, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, + 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0f, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x12, 0x1e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, + 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x54, 0x47, 0x5a, 0x46, + 0x72, 0x6f, 0x6d, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, + 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x67, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1568,7 +1597,7 @@ func file_gomote_proto_rawDescGZIP() []byte { } var file_gomote_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_gomote_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_gomote_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_gomote_proto_goTypes = []interface{}{ (CreateInstanceResponse_Status)(0), // 0: protos.CreateInstanceResponse.Status (*AuthenticateRequest)(nil), // 1: protos.AuthenticateRequest @@ -1592,44 +1621,46 @@ var file_gomote_proto_goTypes = []interface{}{ (*RemoveFilesResponse)(nil), // 19: protos.RemoveFilesResponse (*SignSSHKeyRequest)(nil), // 20: protos.SignSSHKeyRequest (*SignSSHKeyResponse)(nil), // 21: protos.SignSSHKeyResponse - (*WriteTGZRequest)(nil), // 22: protos.WriteTGZRequest - (*WriteTGZResponse)(nil), // 23: protos.WriteTGZResponse + (*UploadFileRequest)(nil), // 22: protos.UploadFileRequest + (*UploadFileResponse)(nil), // 23: protos.UploadFileResponse (*WriteTGZFromURLRequest)(nil), // 24: protos.WriteTGZFromURLRequest (*WriteTGZFromURLResponse)(nil), // 25: protos.WriteTGZFromURLResponse + nil, // 26: protos.UploadFileResponse.FieldsEntry } var file_gomote_proto_depIdxs = []int32{ 9, // 0: protos.CreateInstanceResponse.instance:type_name -> protos.Instance 0, // 1: protos.CreateInstanceResponse.status:type_name -> protos.CreateInstanceResponse.Status 9, // 2: protos.ListInstancesResponse.instances:type_name -> protos.Instance - 1, // 3: protos.GomoteService.Authenticate:input_type -> protos.AuthenticateRequest - 3, // 4: protos.GomoteService.CreateInstance:input_type -> protos.CreateInstanceRequest - 5, // 5: protos.GomoteService.DestroyInstance:input_type -> protos.DestroyInstanceRequest - 7, // 6: protos.GomoteService.ExecuteCommand:input_type -> protos.ExecuteCommandRequest - 10, // 7: protos.GomoteService.InstanceAlive:input_type -> protos.InstanceAliveRequest - 12, // 8: protos.GomoteService.ListDirectory:input_type -> protos.ListDirectoryRequest - 14, // 9: protos.GomoteService.ListInstances:input_type -> protos.ListInstancesRequest - 16, // 10: protos.GomoteService.ReadTGZ:input_type -> protos.ReadTGZRequest - 18, // 11: protos.GomoteService.RemoveFiles:input_type -> protos.RemoveFilesRequest - 20, // 12: protos.GomoteService.SignSSHKey:input_type -> protos.SignSSHKeyRequest - 22, // 13: protos.GomoteService.WriteTGZ:input_type -> protos.WriteTGZRequest - 24, // 14: protos.GomoteService.WriteTGZFromURL:input_type -> protos.WriteTGZFromURLRequest - 2, // 15: protos.GomoteService.Authenticate:output_type -> protos.AuthenticateResponse - 4, // 16: protos.GomoteService.CreateInstance:output_type -> protos.CreateInstanceResponse - 6, // 17: protos.GomoteService.DestroyInstance:output_type -> protos.DestroyInstanceResponse - 8, // 18: protos.GomoteService.ExecuteCommand:output_type -> protos.ExecuteCommandResponse - 11, // 19: protos.GomoteService.InstanceAlive:output_type -> protos.InstanceAliveResponse - 13, // 20: protos.GomoteService.ListDirectory:output_type -> protos.ListDirectoryResponse - 15, // 21: protos.GomoteService.ListInstances:output_type -> protos.ListInstancesResponse - 17, // 22: protos.GomoteService.ReadTGZ:output_type -> protos.ReadTGZResponse - 19, // 23: protos.GomoteService.RemoveFiles:output_type -> protos.RemoveFilesResponse - 21, // 24: protos.GomoteService.SignSSHKey:output_type -> protos.SignSSHKeyResponse - 23, // 25: protos.GomoteService.WriteTGZ:output_type -> protos.WriteTGZResponse - 25, // 26: protos.GomoteService.WriteTGZFromURL:output_type -> protos.WriteTGZFromURLResponse - 15, // [15:27] is the sub-list for method output_type - 3, // [3:15] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 26, // 3: protos.UploadFileResponse.fields:type_name -> protos.UploadFileResponse.FieldsEntry + 1, // 4: protos.GomoteService.Authenticate:input_type -> protos.AuthenticateRequest + 3, // 5: protos.GomoteService.CreateInstance:input_type -> protos.CreateInstanceRequest + 5, // 6: protos.GomoteService.DestroyInstance:input_type -> protos.DestroyInstanceRequest + 7, // 7: protos.GomoteService.ExecuteCommand:input_type -> protos.ExecuteCommandRequest + 10, // 8: protos.GomoteService.InstanceAlive:input_type -> protos.InstanceAliveRequest + 12, // 9: protos.GomoteService.ListDirectory:input_type -> protos.ListDirectoryRequest + 14, // 10: protos.GomoteService.ListInstances:input_type -> protos.ListInstancesRequest + 16, // 11: protos.GomoteService.ReadTGZ:input_type -> protos.ReadTGZRequest + 18, // 12: protos.GomoteService.RemoveFiles:input_type -> protos.RemoveFilesRequest + 20, // 13: protos.GomoteService.SignSSHKey:input_type -> protos.SignSSHKeyRequest + 22, // 14: protos.GomoteService.UploadFile:input_type -> protos.UploadFileRequest + 24, // 15: protos.GomoteService.WriteTGZFromURL:input_type -> protos.WriteTGZFromURLRequest + 2, // 16: protos.GomoteService.Authenticate:output_type -> protos.AuthenticateResponse + 4, // 17: protos.GomoteService.CreateInstance:output_type -> protos.CreateInstanceResponse + 6, // 18: protos.GomoteService.DestroyInstance:output_type -> protos.DestroyInstanceResponse + 8, // 19: protos.GomoteService.ExecuteCommand:output_type -> protos.ExecuteCommandResponse + 11, // 20: protos.GomoteService.InstanceAlive:output_type -> protos.InstanceAliveResponse + 13, // 21: protos.GomoteService.ListDirectory:output_type -> protos.ListDirectoryResponse + 15, // 22: protos.GomoteService.ListInstances:output_type -> protos.ListInstancesResponse + 17, // 23: protos.GomoteService.ReadTGZ:output_type -> protos.ReadTGZResponse + 19, // 24: protos.GomoteService.RemoveFiles:output_type -> protos.RemoveFilesResponse + 21, // 25: protos.GomoteService.SignSSHKey:output_type -> protos.SignSSHKeyResponse + 23, // 26: protos.GomoteService.UploadFile:output_type -> protos.UploadFileResponse + 25, // 27: protos.GomoteService.WriteTGZFromURL:output_type -> protos.WriteTGZFromURLResponse + 16, // [16:28] is the sub-list for method output_type + 4, // [4:16] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_gomote_proto_init() } @@ -1891,7 +1922,7 @@ func file_gomote_proto_init() { } } file_gomote_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WriteTGZRequest); i { + switch v := v.(*UploadFileRequest); i { case 0: return &v.state case 1: @@ -1903,7 +1934,7 @@ func file_gomote_proto_init() { } } file_gomote_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WriteTGZResponse); i { + switch v := v.(*UploadFileResponse); i { case 0: return &v.state case 1: @@ -1945,7 +1976,7 @@ func file_gomote_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gomote_proto_rawDesc, NumEnums: 1, - NumMessages: 25, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/gomote/protos/gomote.proto b/internal/gomote/protos/gomote.proto index 23f5936e9c..dbaa39d6eb 100644 --- a/internal/gomote/protos/gomote.proto +++ b/internal/gomote/protos/gomote.proto @@ -30,8 +30,9 @@ service GomoteService { rpc RemoveFiles (RemoveFilesRequest) returns (RemoveFilesResponse) {} // SignSSHKey signs an SSH public key which can be used to SSH into instances owned by the caller. rpc SignSSHKey (SignSSHKeyRequest) returns (SignSSHKeyResponse) {} - // WriteTGZ expands a tar and zipped file onto the file system of a gomote instance. - rpc WriteTGZ (stream WriteTGZRequest) returns (WriteTGZResponse) {} + // UploadFile generates a signed URL and associated fields to be used when uploading the object to GCS. Once uploaded + // the corresponding Write endpoint can be used to send the file to the gomote instance. + rpc UploadFile (UploadFileRequest) returns (UploadFileResponse) {} // WriteTGZFromURL retrieves a tar and zipped file from a URL and expands it onto the file system of a gomote instance. rpc WriteTGZFromURL (WriteTGZFromURLRequest) returns (WriteTGZFromURLResponse) {} } @@ -189,11 +190,16 @@ message SignSSHKeyResponse { bytes signed_public_ssh_key = 1; } -// WriteTGZRequest specifies the data needed to expand a tar and zipped file onto the file system of a gomote instance. -message WriteTGZRequest {} +// UploadFileRequest specifies the data needed to create a request to upload an object to GCS. +message UploadFileRequest {} -// WriteTGZResponse contains the results from expanding a tar and zipped file onto the file system of a gomote instance. -message WriteTGZResponse {} +// UploadFileResponse contains the results from a request to upload an object to GCS. +message UploadFileResponse { + // URL to post file to. + string url = 1; + // Form fields used when http posting files to GCS. + map fields = 2; +} // WriteTGZFromURLRequest specifies the data needed to retrieve a file and expand it onto the file system of a gomote instance. // It instructs the buildlet to download the tar.gz file from the url and write it to a directory, a relative directory from the workdir. diff --git a/internal/gomote/protos/gomote_grpc.pb.go b/internal/gomote/protos/gomote_grpc.pb.go index 010cbdb44c..1642d4b576 100644 --- a/internal/gomote/protos/gomote_grpc.pb.go +++ b/internal/gomote/protos/gomote_grpc.pb.go @@ -38,8 +38,9 @@ type GomoteServiceClient interface { RemoveFiles(ctx context.Context, in *RemoveFilesRequest, opts ...grpc.CallOption) (*RemoveFilesResponse, error) // SignSSHKey signs an SSH public key which can be used to SSH into instances owned by the caller. SignSSHKey(ctx context.Context, in *SignSSHKeyRequest, opts ...grpc.CallOption) (*SignSSHKeyResponse, error) - // WriteTGZ expands a tar and zipped file onto the file system of a gomote instance. - WriteTGZ(ctx context.Context, opts ...grpc.CallOption) (GomoteService_WriteTGZClient, error) + // UploadFile generates a signed URL and associated fields to be used when uploading the object to GCS. Once uploaded + // the corresponding Write endpoint can be used to send the file to the gomote instance. + UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileResponse, error) // WriteTGZFromURL retrieves a tar and zipped file from a URL and expands it onto the file system of a gomote instance. WriteTGZFromURL(ctx context.Context, in *WriteTGZFromURLRequest, opts ...grpc.CallOption) (*WriteTGZFromURLResponse, error) } @@ -211,38 +212,13 @@ func (c *gomoteServiceClient) SignSSHKey(ctx context.Context, in *SignSSHKeyRequ return out, nil } -func (c *gomoteServiceClient) WriteTGZ(ctx context.Context, opts ...grpc.CallOption) (GomoteService_WriteTGZClient, error) { - stream, err := c.cc.NewStream(ctx, &GomoteService_ServiceDesc.Streams[3], "/protos.GomoteService/WriteTGZ", opts...) +func (c *gomoteServiceClient) UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileResponse, error) { + out := new(UploadFileResponse) + err := c.cc.Invoke(ctx, "/protos.GomoteService/UploadFile", in, out, opts...) if err != nil { return nil, err } - x := &gomoteServiceWriteTGZClient{stream} - return x, nil -} - -type GomoteService_WriteTGZClient interface { - Send(*WriteTGZRequest) error - CloseAndRecv() (*WriteTGZResponse, error) - grpc.ClientStream -} - -type gomoteServiceWriteTGZClient struct { - grpc.ClientStream -} - -func (x *gomoteServiceWriteTGZClient) Send(m *WriteTGZRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *gomoteServiceWriteTGZClient) CloseAndRecv() (*WriteTGZResponse, error) { - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - m := new(WriteTGZResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil + return out, nil } func (c *gomoteServiceClient) WriteTGZFromURL(ctx context.Context, in *WriteTGZFromURLRequest, opts ...grpc.CallOption) (*WriteTGZFromURLResponse, error) { @@ -278,8 +254,9 @@ type GomoteServiceServer interface { RemoveFiles(context.Context, *RemoveFilesRequest) (*RemoveFilesResponse, error) // SignSSHKey signs an SSH public key which can be used to SSH into instances owned by the caller. SignSSHKey(context.Context, *SignSSHKeyRequest) (*SignSSHKeyResponse, error) - // WriteTGZ expands a tar and zipped file onto the file system of a gomote instance. - WriteTGZ(GomoteService_WriteTGZServer) error + // UploadFile generates a signed URL and associated fields to be used when uploading the object to GCS. Once uploaded + // the corresponding Write endpoint can be used to send the file to the gomote instance. + UploadFile(context.Context, *UploadFileRequest) (*UploadFileResponse, error) // WriteTGZFromURL retrieves a tar and zipped file from a URL and expands it onto the file system of a gomote instance. WriteTGZFromURL(context.Context, *WriteTGZFromURLRequest) (*WriteTGZFromURLResponse, error) mustEmbedUnimplementedGomoteServiceServer() @@ -319,8 +296,8 @@ func (UnimplementedGomoteServiceServer) RemoveFiles(context.Context, *RemoveFile func (UnimplementedGomoteServiceServer) SignSSHKey(context.Context, *SignSSHKeyRequest) (*SignSSHKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SignSSHKey not implemented") } -func (UnimplementedGomoteServiceServer) WriteTGZ(GomoteService_WriteTGZServer) error { - return status.Errorf(codes.Unimplemented, "method WriteTGZ not implemented") +func (UnimplementedGomoteServiceServer) UploadFile(context.Context, *UploadFileRequest) (*UploadFileResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadFile not implemented") } func (UnimplementedGomoteServiceServer) WriteTGZFromURL(context.Context, *WriteTGZFromURLRequest) (*WriteTGZFromURLResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method WriteTGZFromURL not implemented") @@ -527,30 +504,22 @@ func _GomoteService_SignSSHKey_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _GomoteService_WriteTGZ_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(GomoteServiceServer).WriteTGZ(&gomoteServiceWriteTGZServer{stream}) -} - -type GomoteService_WriteTGZServer interface { - SendAndClose(*WriteTGZResponse) error - Recv() (*WriteTGZRequest, error) - grpc.ServerStream -} - -type gomoteServiceWriteTGZServer struct { - grpc.ServerStream -} - -func (x *gomoteServiceWriteTGZServer) SendAndClose(m *WriteTGZResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *gomoteServiceWriteTGZServer) Recv() (*WriteTGZRequest, error) { - m := new(WriteTGZRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { +func _GomoteService_UploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UploadFileRequest) + if err := dec(in); err != nil { return nil, err } - return m, nil + if interceptor == nil { + return srv.(GomoteServiceServer).UploadFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/protos.GomoteService/UploadFile", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GomoteServiceServer).UploadFile(ctx, req.(*UploadFileRequest)) + } + return interceptor(ctx, in, info, handler) } func _GomoteService_WriteTGZFromURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -606,6 +575,10 @@ var GomoteService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SignSSHKey", Handler: _GomoteService_SignSSHKey_Handler, }, + { + MethodName: "UploadFile", + Handler: _GomoteService_UploadFile_Handler, + }, { MethodName: "WriteTGZFromURL", Handler: _GomoteService_WriteTGZFromURL_Handler, @@ -627,11 +600,6 @@ var GomoteService_ServiceDesc = grpc.ServiceDesc{ Handler: _GomoteService_ReadTGZ_Handler, ServerStreams: true, }, - { - StreamName: "WriteTGZ", - Handler: _GomoteService_WriteTGZ_Handler, - ClientStreams: true, - }, }, Metadata: "gomote.proto", }