From 6230388176eae12179a677a21f7a3c8ad44437ad Mon Sep 17 00:00:00 2001 From: Alex Angelini Date: Tue, 19 Mar 2024 12:09:30 +0100 Subject: [PATCH] Staged Update --- Makefile | 25 +- cmd/fuzz-test/main.go | 2 +- internal/db/update.go | 145 +++-- internal/key/key.go | 1 + internal/pb/fs.pb.go | 698 ++++++++++++++--------- internal/pb/fs.proto | 13 + internal/pb/fs_grpc.pb.go | 37 ++ migrations/000007_staged_update.down.sql | 1 + migrations/000007_staged_update.up.sql | 19 + pkg/api/fs.go | 90 ++- pkg/cli/client.go | 1 + pkg/cli/commit.go | 39 ++ pkg/cli/update.go | 8 +- pkg/client/client.go | 24 +- test/client_update_test.go | 2 +- test/shared_test.go | 2 +- 16 files changed, 777 insertions(+), 330 deletions(-) create mode 100644 migrations/000007_staged_update.down.sql create mode 100644 migrations/000007_staged_update.up.sql create mode 100644 pkg/cli/commit.go diff --git a/Makefile b/Makefile index 2d3088b..7b33d5e 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,8 @@ PROTO_FILES := $(shell find internal/pb/ -type f -name '*.proto') MIGRATE_DIR := ./migrations SERVICE := $(PROJECT).server +export DL_SKIP_SSL_VERIFICATION := 1 + .PHONY: install migrate migrate-create clean build lint release .PHONY: test test-one test-fuzz test-js lint-js build-js .PHONY: reset-db setup-local server server-profile install-js @@ -107,12 +109,11 @@ else endif test-fuzz: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -test-fuzz: export DL_SKIP_SSL_VERIFICATION=1 test-fuzz: reset-db go run cmd/fuzz-test/main.go --host $(GRPC_HOST) --iterations 1000 --projects 5 reset-db: migrate - psql $(DB_URI) -c "truncate dl.objects; truncate dl.contents; truncate dl.projects; truncate dl.cache_versions;" + psql $(DB_URI) -c "truncate dl.objects; truncate dl.contents; truncate dl.projects; truncate dl.cache_versions; truncate dl.staged_objects" setup-local: reset-db psql $(DB_URI) -c "insert into dl.projects (id, latest_version, pack_patterns) values (1, 0, '{\"node_modules/.*/\"}');" @@ -126,7 +127,6 @@ server-profile: internal/pb/fs.pb.go internal/pb/fs_grpc.pb.go go run cmd/server/main.go --dburi $(DB_URI) --port $(GRPC_PORT) --profile cpu.prof --log-level info client-update: export DL_TOKEN=$(DEV_TOKEN_PROJECT_1) -client-update: export DL_SKIP_SSL_VERIFICATION=1 client-update: development/scripts/simple_input.sh 1 go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/simple @@ -136,7 +136,6 @@ client-update: go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/simple client-large-update: export DL_TOKEN=$(DEV_TOKEN_PROJECT_1) -client-large-update: export DL_SKIP_SSL_VERIFICATION=1 client-large-update: development/scripts/complex_input.sh 1 go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/complex @@ -145,8 +144,18 @@ client-large-update: development/scripts/complex_input.sh 3 go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/complex +client-staged-update: export DL_TOKEN=$(DEV_TOKEN_PROJECT_1) +client-staged-update: + development/scripts/simple_input.sh 1 + go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/simple + development/scripts/simple_input.sh 2 + go run cmd/client/main.go update --host $(GRPC_HOST) --project 1 --dir input/simple --staged + +client-commit: export DL_TOKEN=$(DEV_TOKEN_PROJECT_1) +client-commit: + go run cmd/client/main.go commit --host $(GRPC_HOST) --project 1 --version 2 + client-get: export DL_TOKEN=$(DEV_TOKEN_PROJECT_1) -client-get: export DL_SKIP_SSL_VERIFICATION=1 client-get: ifndef to_version go run cmd/client/main.go get --host $(GRPC_HOST) --project 1 --prefix "$(prefix)" @@ -155,7 +164,6 @@ else endif client-rebuild: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-rebuild: export DL_SKIP_SSL_VERIFICATION=1 client-rebuild: ifndef to_version go run cmd/client/main.go rebuild --host $(GRPC_HOST) --project 1 --prefix "$(prefix)" --dir $(dir) @@ -164,27 +172,22 @@ else endif client-rebuild-with-cache: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-rebuild-with-cache: export DL_SKIP_SSL_VERIFICATION=1 client-rebuild-with-cache: go run cmd/client/main.go rebuild --host $(GRPC_HOST) --project 1 --prefix "$(prefix)" --dir $(dir) --cachedir input/cache client-getcache: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-getcache: export DL_SKIP_SSL_VERIFICATION=1 client-getcache: go run cmd/client/main.go getcache --host $(GRPC_HOST) --path input/cache client-gc-contents: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-gc-contents: export DL_SKIP_SSL_VERIFICATION=1 client-gc-contents: go run cmd/client/main.go gc --host $(GRPC_HOST) --mode contents --sample 25 client-gc-project: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-gc-project: export DL_SKIP_SSL_VERIFICATION=1 client-gc-project: go run cmd/client/main.go gc --host $(GRPC_HOST) --mode project --project 1 --keep 1 client-gc-random-projects: export DL_TOKEN=$(DEV_TOKEN_ADMIN) -client-gc-random-projects: export DL_SKIP_SSL_VERIFICATION=1 client-gc-random-projects: go run cmd/client/main.go gc --host $(GRPC_HOST) --mode random-projects --sample 25 --keep 1 diff --git a/cmd/fuzz-test/main.go b/cmd/fuzz-test/main.go index 28754d6..8e543c2 100644 --- a/cmd/fuzz-test/main.go +++ b/cmd/fuzz-test/main.go @@ -403,7 +403,7 @@ func runIteration(ctx context.Context, client *dlc.Client, project int64, operat return -1, fmt.Errorf("failed to apply operation %s: %w", operation.String(), err) } - version, _, err := client.Update(ctx, project, dirs.Base(project)) + version, _, err := client.Update(ctx, project, dirs.Base(project), false) if err != nil { return -1, fmt.Errorf("failed to update project %d: %w", project, err) } diff --git a/internal/db/update.go b/internal/db/update.go index bf53f1c..33c75d8 100644 --- a/internal/db/update.go +++ b/internal/db/update.go @@ -23,7 +23,19 @@ func UpdateLatestVersion(ctx context.Context, tx pgx.Tx, project int64, version return nil } -func DeleteObject(ctx context.Context, tx pgx.Tx, project int64, version int64, path string) error { +func DeleteObject(ctx context.Context, tx pgx.Tx, project int64, version int64, path string, isStaged bool) error { + if isStaged { + _, err := tx.Exec(ctx, ` + INSERT INTO dl.staged_objects (project, start_version, stop_version, path, hash, mode, size, packed) + VALUES ($1, NULL, $2, $3, NULL, NULL, NULL, NULL) + `, project, version, path) + if err != nil { + return fmt.Errorf("delete staged object, project %v, version %v, path %v: %w", project, version, path, err) + } + + return nil + } + _, err := tx.Exec(ctx, ` UPDATE dl.objects SET stop_version = $1 @@ -39,7 +51,7 @@ func DeleteObject(ctx context.Context, tx pgx.Tx, project int64, version int64, } // UpdateObject returns true if content changed, false otherwise -func UpdateObject(ctx context.Context, tx pgx.Tx, conn DbConnector, encoder *ContentEncoder, project int64, version int64, object *pb.Object) (bool, error) { +func UpdateObject(ctx context.Context, tx pgx.Tx, conn DbConnector, encoder *ContentEncoder, project int64, version int64, object *pb.Object, isStaged bool) (bool, error) { content := object.Content if content == nil { content = []byte("") @@ -61,13 +73,18 @@ func UpdateObject(ctx context.Context, tx pgx.Tx, conn DbConnector, encoder *Con return false, fmt.Errorf("insert objects content, hash %x-%x: %w", hash.H1, hash.H2, err) } - rows, err := tx.Query(ctx, ` - INSERT INTO dl.objects (project, start_version, stop_version, path, hash, mode, size, packed) + objectTable := "dl.objects" + if isStaged { + objectTable = "dl.staged_objects" + } + + rows, err := tx.Query(ctx, fmt.Sprintf(` + INSERT INTO %s (project, start_version, stop_version, path, hash, mode, size, packed) VALUES ($1, $2, NULL, $3, ($4, $5), $6, $7, $8) ON CONFLICT DO NOTHING RETURNING project - `, project, version, object.Path, hash.H1, hash.H2, object.Mode, object.Size, false) + `, objectTable), project, version, object.Path, hash.H1, hash.H2, object.Mode, object.Size, false) if err != nil { return false, fmt.Errorf("insert new object, project %v, version %v, path %v: %w", project, version, object.Path, err) } @@ -79,30 +96,31 @@ func UpdateObject(ctx context.Context, tx pgx.Tx, conn DbConnector, encoder *Con return false, nil } - previousPaths := []string{object.Path} - pathChunks := strings.Split(object.Path, "/") - - for i := 1; i < len(pathChunks); i++ { - previousPaths = append(previousPaths, fmt.Sprintf("%s/", strings.Join(pathChunks[:i], "/"))) - } + if !isStaged { + previousPaths := []string{object.Path} + pathChunks := strings.Split(object.Path, "/") - _, err = tx.Exec(ctx, ` - UPDATE dl.objects SET stop_version = $1 - WHERE project = $2 - AND path = ANY($3) - AND stop_version IS NULL - AND start_version != $4 - `, version, project, previousPaths, version) + for i := 1; i < len(pathChunks); i++ { + previousPaths = append(previousPaths, fmt.Sprintf("%s/", strings.Join(pathChunks[:i], "/"))) + } - if err != nil { - return false, fmt.Errorf("update previous object, project %v, version %v, path %v: %w", project, version, object.Path, err) + _, err = tx.Exec(ctx, ` + UPDATE dl.objects SET stop_version = $1 + WHERE project = $2 + AND path = ANY($3) + AND stop_version IS NULL + AND start_version != $4 + `, version, project, previousPaths, version) + if err != nil { + return false, fmt.Errorf("update previous object, project %v, version %v, path %v: %w", project, version, object.Path, err) + } } return true, nil } // UpdatePackedObjects returns true if content changed, false otherwise -func UpdatePackedObjects(ctx context.Context, tx pgx.Tx, conn DbConnector, project int64, version int64, parent string, updates []*pb.Object) (bool, error) { +func UpdatePackedObjects(ctx context.Context, tx pgx.Tx, conn DbConnector, project int64, version int64, parent string, updates []*pb.Object, isStaged bool) (bool, error) { var hash Hash var content []byte @@ -146,30 +164,43 @@ func UpdatePackedObjects(ctx context.Context, tx pgx.Tx, conn DbConnector, proje batch := &pgx.Batch{} - batch.Queue(` - UPDATE dl.objects SET stop_version = $1 - WHERE project = $2 - AND path = $3 - AND packed IS true - AND stop_version IS NULL - `, version, project, parent) + if isStaged { + batch.Queue(` + INSERT INTO dl.staged_objects (project, start_version, stop_version, path, hash, mode, size, packed) + VALUES ($1, NULL, $2, $3, NULL, NULL, NULL, NULL) + `, project, version, parent) + } else { + batch.Queue(` + UPDATE dl.objects SET stop_version = $1 + WHERE project = $2 + AND path = $3 + AND packed IS true + AND stop_version IS NULL + `, version, project, parent) + } if shouldInsert { // insert the content outside the transaction to avoid deadlocks and to keep smaller transactions _, err = conn.Exec(ctx, ` INSERT INTO dl.contents (hash, bytes) VALUES (($1, $2), $3) - ON CONFLICT DO NOTHING + ON CONFLICT + DO NOTHING `, newHash.H1, newHash.H2, updated) if err != nil { return false, fmt.Errorf("insert packed content, hash %x-%x: %w", newHash.H1, newHash.H2, err) } - batch.Queue(` - INSERT INTO dl.objects (project, start_version, stop_version, path, hash, mode, size, packed) + objectTable := "dl.objects" + if isStaged { + objectTable = "dl.staged_objects" + } + + batch.Queue(fmt.Sprintf(` + INSERT INTO %s (project, start_version, stop_version, path, hash, mode, size, packed) VALUES ($1, $2, NULL, $3, ($4, $5), $6, $7, $8) - `, project, version, parent, newHash.H1, newHash.H2, 0, len(updated), true) + `, objectTable), project, version, parent, newHash.H1, newHash.H2, 0, len(updated), true) } results := tx.SendBatch(ctx, batch) @@ -190,3 +221,53 @@ func UpdatePackedObjects(ctx context.Context, tx pgx.Tx, conn DbConnector, proje // content did change return true, nil } + +func CommitStagedObjects(ctx context.Context, tx pgx.Tx, project int64, version int64) error { + batch := &pgx.Batch{} + + batch.Queue(` + INSERT INTO dl.objects (project, start_version, stop_version, path, hash, mode, size, packed) + SELECT project, start_version, NULL, path, hash, mode, size, packed + FROM dl.staged_objects + WHERE project = $1 + AND start_version = $2 + AND stop_version IS NULL + `, project, version) + + batch.Queue(` + UPDATE dl.objects SET stop_version = $2 + FROM ( + SELECT project, path + FROM dl.staged_objects + WHERE project = $1 + AND stop_version = $2 + AND start_version IS NULL + ) staged + WHERE staged.project = dl.objects.project + AND staged.path = dl.objects.path + `, project, version) + + batch.Queue(` + DELETE FROM dl.staged_objects + WHERE project = $1 + AND (start_version = $2 OR stop_version = $2) + `, project, version) + + results := tx.SendBatch(ctx, batch) + defer results.Close() + + _, err := results.Exec() + if err != nil { + return fmt.Errorf("commit new objects, project %v, version %v: %w", project, version, err) + } + _, err = results.Exec() + if err != nil { + return fmt.Errorf("commit deleted objects, project %v, version %v: %w", project, version, err) + } + _, err = results.Exec() + if err != nil { + return fmt.Errorf("deleted staged objects, project %v, version %v: %w", project, version, err) + } + + return nil +} diff --git a/internal/key/key.go b/internal/key/key.go index 3d3a1d9..5ccf551 100644 --- a/internal/key/key.go +++ b/internal/key/key.go @@ -13,6 +13,7 @@ const ( Directory = StringKey("dl.directory") Environment = StringKey("dl.environment") FromVersion = Int64pKey("dl.from_version") + IsStaged = BoolKey("dl.is_staged") KeepVersions = Int64Key("dl.keep_versions") LatestVersion = Int64Key("dl.latest_version") LiveObjectsCount = Int64Key("dl.live_objects_count") diff --git a/internal/pb/fs.pb.go b/internal/pb/fs.pb.go index e9c8be8..2eff21b 100644 --- a/internal/pb/fs.pb.go +++ b/internal/pb/fs.pb.go @@ -103,7 +103,7 @@ func (x GetCacheResponse_Format) Number() protoreflect.EnumNumber { // Deprecated: Use GetCacheResponse_Format.Descriptor instead. func (GetCacheResponse_Format) EnumDescriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{34, 0} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{36, 0} } type NewProjectRequest struct { @@ -982,8 +982,9 @@ type UpdateRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Project int64 `protobuf:"varint,1,opt,name=project,proto3" json:"project,omitempty"` - Object *Objekt `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` + Project int64 `protobuf:"varint,1,opt,name=project,proto3" json:"project,omitempty"` + Object *Objekt `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` + IsStaged bool `protobuf:"varint,3,opt,name=is_staged,json=isStaged,proto3" json:"is_staged,omitempty"` } func (x *UpdateRequest) Reset() { @@ -1032,12 +1033,20 @@ func (x *UpdateRequest) GetObject() *Objekt { return nil } +func (x *UpdateRequest) GetIsStaged() bool { + if x != nil { + return x.IsStaged + } + return false +} + type UpdateResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + IsStaged bool `protobuf:"varint,2,opt,name=is_staged,json=isStaged,proto3" json:"is_staged,omitempty"` } func (x *UpdateResponse) Reset() { @@ -1079,6 +1088,115 @@ func (x *UpdateResponse) GetVersion() int64 { return 0 } +func (x *UpdateResponse) GetIsStaged() bool { + if x != nil { + return x.IsStaged + } + return false +} + +type CommitUpdateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Project int64 `protobuf:"varint,1,opt,name=project,proto3" json:"project,omitempty"` + Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *CommitUpdateRequest) Reset() { + *x = CommitUpdateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_pb_fs_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitUpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitUpdateRequest) ProtoMessage() {} + +func (x *CommitUpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_internal_pb_fs_proto_msgTypes[17] + 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 CommitUpdateRequest.ProtoReflect.Descriptor instead. +func (*CommitUpdateRequest) Descriptor() ([]byte, []int) { + return file_internal_pb_fs_proto_rawDescGZIP(), []int{17} +} + +func (x *CommitUpdateRequest) GetProject() int64 { + if x != nil { + return x.Project + } + return 0 +} + +func (x *CommitUpdateRequest) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +type CommitUpdateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *CommitUpdateResponse) Reset() { + *x = CommitUpdateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_pb_fs_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitUpdateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitUpdateResponse) ProtoMessage() {} + +func (x *CommitUpdateResponse) ProtoReflect() protoreflect.Message { + mi := &file_internal_pb_fs_proto_msgTypes[18] + 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 CommitUpdateResponse.ProtoReflect.Descriptor instead. +func (*CommitUpdateResponse) Descriptor() ([]byte, []int) { + return file_internal_pb_fs_proto_rawDescGZIP(), []int{18} +} + +func (x *CommitUpdateResponse) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + type RollbackRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1091,7 +1209,7 @@ type RollbackRequest struct { func (x *RollbackRequest) Reset() { *x = RollbackRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[17] + mi := &file_internal_pb_fs_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1104,7 +1222,7 @@ func (x *RollbackRequest) String() string { func (*RollbackRequest) ProtoMessage() {} func (x *RollbackRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[17] + mi := &file_internal_pb_fs_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1117,7 +1235,7 @@ func (x *RollbackRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RollbackRequest.ProtoReflect.Descriptor instead. func (*RollbackRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{17} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{19} } func (x *RollbackRequest) GetProject() int64 { @@ -1143,7 +1261,7 @@ type RollbackResponse struct { func (x *RollbackResponse) Reset() { *x = RollbackResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[18] + mi := &file_internal_pb_fs_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1156,7 +1274,7 @@ func (x *RollbackResponse) String() string { func (*RollbackResponse) ProtoMessage() {} func (x *RollbackResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[18] + mi := &file_internal_pb_fs_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1169,7 +1287,7 @@ func (x *RollbackResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RollbackResponse.ProtoReflect.Descriptor instead. func (*RollbackResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{18} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{20} } type InspectRequest struct { @@ -1183,7 +1301,7 @@ type InspectRequest struct { func (x *InspectRequest) Reset() { *x = InspectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[19] + mi := &file_internal_pb_fs_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1196,7 +1314,7 @@ func (x *InspectRequest) String() string { func (*InspectRequest) ProtoMessage() {} func (x *InspectRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[19] + mi := &file_internal_pb_fs_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1209,7 +1327,7 @@ func (x *InspectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InspectRequest.ProtoReflect.Descriptor instead. func (*InspectRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{19} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{21} } func (x *InspectRequest) GetProject() int64 { @@ -1233,7 +1351,7 @@ type InspectResponse struct { func (x *InspectResponse) Reset() { *x = InspectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[20] + mi := &file_internal_pb_fs_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1246,7 +1364,7 @@ func (x *InspectResponse) String() string { func (*InspectResponse) ProtoMessage() {} func (x *InspectResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[20] + mi := &file_internal_pb_fs_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1259,7 +1377,7 @@ func (x *InspectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InspectResponse.ProtoReflect.Descriptor instead. func (*InspectResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{20} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{22} } func (x *InspectResponse) GetProject() int64 { @@ -1299,7 +1417,7 @@ type SnapshotRequest struct { func (x *SnapshotRequest) Reset() { *x = SnapshotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[21] + mi := &file_internal_pb_fs_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1312,7 +1430,7 @@ func (x *SnapshotRequest) String() string { func (*SnapshotRequest) ProtoMessage() {} func (x *SnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[21] + mi := &file_internal_pb_fs_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1325,7 +1443,7 @@ func (x *SnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotRequest.ProtoReflect.Descriptor instead. func (*SnapshotRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{21} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{23} } type SnapshotResponse struct { @@ -1339,7 +1457,7 @@ type SnapshotResponse struct { func (x *SnapshotResponse) Reset() { *x = SnapshotResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[22] + mi := &file_internal_pb_fs_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1352,7 +1470,7 @@ func (x *SnapshotResponse) String() string { func (*SnapshotResponse) ProtoMessage() {} func (x *SnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[22] + mi := &file_internal_pb_fs_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1365,7 +1483,7 @@ func (x *SnapshotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotResponse.ProtoReflect.Descriptor instead. func (*SnapshotResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{22} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{24} } func (x *SnapshotResponse) GetProjects() []*Project { @@ -1386,7 +1504,7 @@ type ResetRequest struct { func (x *ResetRequest) Reset() { *x = ResetRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[23] + mi := &file_internal_pb_fs_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1399,7 +1517,7 @@ func (x *ResetRequest) String() string { func (*ResetRequest) ProtoMessage() {} func (x *ResetRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[23] + mi := &file_internal_pb_fs_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1412,7 +1530,7 @@ func (x *ResetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetRequest.ProtoReflect.Descriptor instead. func (*ResetRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{23} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{25} } func (x *ResetRequest) GetProjects() []*Project { @@ -1431,7 +1549,7 @@ type ResetResponse struct { func (x *ResetResponse) Reset() { *x = ResetResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[24] + mi := &file_internal_pb_fs_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1444,7 +1562,7 @@ func (x *ResetResponse) String() string { func (*ResetResponse) ProtoMessage() {} func (x *ResetResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[24] + mi := &file_internal_pb_fs_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1457,7 +1575,7 @@ func (x *ResetResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetResponse.ProtoReflect.Descriptor instead. func (*ResetResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{24} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{26} } type GcProjectRequest struct { @@ -1473,7 +1591,7 @@ type GcProjectRequest struct { func (x *GcProjectRequest) Reset() { *x = GcProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[25] + mi := &file_internal_pb_fs_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1486,7 +1604,7 @@ func (x *GcProjectRequest) String() string { func (*GcProjectRequest) ProtoMessage() {} func (x *GcProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[25] + mi := &file_internal_pb_fs_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1499,7 +1617,7 @@ func (x *GcProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GcProjectRequest.ProtoReflect.Descriptor instead. func (*GcProjectRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{25} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{27} } func (x *GcProjectRequest) GetProject() int64 { @@ -1535,7 +1653,7 @@ type GcProjectResponse struct { func (x *GcProjectResponse) Reset() { *x = GcProjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[26] + mi := &file_internal_pb_fs_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1548,7 +1666,7 @@ func (x *GcProjectResponse) String() string { func (*GcProjectResponse) ProtoMessage() {} func (x *GcProjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[26] + mi := &file_internal_pb_fs_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1561,7 +1679,7 @@ func (x *GcProjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GcProjectResponse.ProtoReflect.Descriptor instead. func (*GcProjectResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{26} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{28} } func (x *GcProjectResponse) GetCount() int64 { @@ -1591,7 +1709,7 @@ type GcRandomProjectsRequest struct { func (x *GcRandomProjectsRequest) Reset() { *x = GcRandomProjectsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[27] + mi := &file_internal_pb_fs_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1604,7 +1722,7 @@ func (x *GcRandomProjectsRequest) String() string { func (*GcRandomProjectsRequest) ProtoMessage() {} func (x *GcRandomProjectsRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[27] + mi := &file_internal_pb_fs_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1617,7 +1735,7 @@ func (x *GcRandomProjectsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GcRandomProjectsRequest.ProtoReflect.Descriptor instead. func (*GcRandomProjectsRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{27} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{29} } func (x *GcRandomProjectsRequest) GetSample() float32 { @@ -1653,7 +1771,7 @@ type GcRandomProjectsResponse struct { func (x *GcRandomProjectsResponse) Reset() { *x = GcRandomProjectsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[28] + mi := &file_internal_pb_fs_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1666,7 +1784,7 @@ func (x *GcRandomProjectsResponse) String() string { func (*GcRandomProjectsResponse) ProtoMessage() {} func (x *GcRandomProjectsResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[28] + mi := &file_internal_pb_fs_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1679,7 +1797,7 @@ func (x *GcRandomProjectsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GcRandomProjectsResponse.ProtoReflect.Descriptor instead. func (*GcRandomProjectsResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{28} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{30} } func (x *GcRandomProjectsResponse) GetCount() int64 { @@ -1707,7 +1825,7 @@ type GcContentsRequest struct { func (x *GcContentsRequest) Reset() { *x = GcContentsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[29] + mi := &file_internal_pb_fs_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1720,7 +1838,7 @@ func (x *GcContentsRequest) String() string { func (*GcContentsRequest) ProtoMessage() {} func (x *GcContentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[29] + mi := &file_internal_pb_fs_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1733,7 +1851,7 @@ func (x *GcContentsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GcContentsRequest.ProtoReflect.Descriptor instead. func (*GcContentsRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{29} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{31} } func (x *GcContentsRequest) GetSample() float32 { @@ -1754,7 +1872,7 @@ type GcContentsResponse struct { func (x *GcContentsResponse) Reset() { *x = GcContentsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[30] + mi := &file_internal_pb_fs_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1767,7 +1885,7 @@ func (x *GcContentsResponse) String() string { func (*GcContentsResponse) ProtoMessage() {} func (x *GcContentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[30] + mi := &file_internal_pb_fs_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1780,7 +1898,7 @@ func (x *GcContentsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GcContentsResponse.ProtoReflect.Descriptor instead. func (*GcContentsResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{30} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{32} } func (x *GcContentsResponse) GetCount() int64 { @@ -1803,7 +1921,7 @@ type CloneToProjectRequest struct { func (x *CloneToProjectRequest) Reset() { *x = CloneToProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[31] + mi := &file_internal_pb_fs_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1816,7 +1934,7 @@ func (x *CloneToProjectRequest) String() string { func (*CloneToProjectRequest) ProtoMessage() {} func (x *CloneToProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[31] + mi := &file_internal_pb_fs_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1829,7 +1947,7 @@ func (x *CloneToProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CloneToProjectRequest.ProtoReflect.Descriptor instead. func (*CloneToProjectRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{31} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{33} } func (x *CloneToProjectRequest) GetSource() int64 { @@ -1864,7 +1982,7 @@ type CloneToProjectResponse struct { func (x *CloneToProjectResponse) Reset() { *x = CloneToProjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[32] + mi := &file_internal_pb_fs_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1877,7 +1995,7 @@ func (x *CloneToProjectResponse) String() string { func (*CloneToProjectResponse) ProtoMessage() {} func (x *CloneToProjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[32] + mi := &file_internal_pb_fs_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1890,7 +2008,7 @@ func (x *CloneToProjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CloneToProjectResponse.ProtoReflect.Descriptor instead. func (*CloneToProjectResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{32} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{34} } func (x *CloneToProjectResponse) GetLatestVersion() int64 { @@ -1909,7 +2027,7 @@ type GetCacheRequest struct { func (x *GetCacheRequest) Reset() { *x = GetCacheRequest{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[33] + mi := &file_internal_pb_fs_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1922,7 +2040,7 @@ func (x *GetCacheRequest) String() string { func (*GetCacheRequest) ProtoMessage() {} func (x *GetCacheRequest) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[33] + mi := &file_internal_pb_fs_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1935,7 +2053,7 @@ func (x *GetCacheRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCacheRequest.ProtoReflect.Descriptor instead. func (*GetCacheRequest) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{33} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{35} } type GetCacheResponse struct { @@ -1952,7 +2070,7 @@ type GetCacheResponse struct { func (x *GetCacheResponse) Reset() { *x = GetCacheResponse{} if protoimpl.UnsafeEnabled { - mi := &file_internal_pb_fs_proto_msgTypes[34] + mi := &file_internal_pb_fs_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1965,7 +2083,7 @@ func (x *GetCacheResponse) String() string { func (*GetCacheResponse) ProtoMessage() {} func (x *GetCacheResponse) ProtoReflect() protoreflect.Message { - mi := &file_internal_pb_fs_proto_msgTypes[34] + mi := &file_internal_pb_fs_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1978,7 +2096,7 @@ func (x *GetCacheResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCacheResponse.ProtoReflect.Descriptor instead. func (*GetCacheResponse) Descriptor() ([]byte, []int) { - return file_internal_pb_fs_proto_rawDescGZIP(), []int{34} + return file_internal_pb_fs_proto_rawDescGZIP(), []int{36} } func (x *GetCacheResponse) GetVersion() int64 { @@ -2114,161 +2232,177 @@ var file_internal_pb_fs_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x6b, 0x74, 0x52, - 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x6b, 0x74, 0x52, - 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2a, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x6f, - 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, - 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xb0, 0x01, 0x0a, 0x0f, 0x49, - 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x2c, 0x0a, 0x12, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6c, 0x69, 0x76, - 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, - 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x11, 0x0a, - 0x0f, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x3b, 0x0a, 0x10, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x73, 0x74, + 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x53, 0x74, + 0x61, 0x67, 0x65, 0x64, 0x22, 0x47, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, 0x22, 0x49, 0x0a, + 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0f, 0x52, 0x6f, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x22, 0xb0, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x10, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x10, 0x53, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x22, 0x37, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x37, 0x0a, - 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, 0x01, 0x0a, 0x10, 0x47, 0x63, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6b, - 0x65, 0x65, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x66, - 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x48, 0x00, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x43, 0x0a, 0x11, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x17, 0x47, 0x63, - 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x23, 0x0a, + 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x0f, 0x0a, + 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, + 0x01, 0x0a, 0x10, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x66, - 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x18, 0x47, - 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x2b, 0x0a, 0x11, 0x47, 0x63, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0x2a, 0x0a, 0x12, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x61, 0x0a, 0x15, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3f, 0x0a, 0x16, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, - 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x14, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x32, 0x5f, 0x54, 0x41, 0x52, 0x10, 0x00, 0x32, 0xb8, 0x07, - 0x0a, 0x02, 0x46, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x4e, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4e, - 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, - 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x03, 0x47, 0x65, - 0x74, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x12, 0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x61, - 0x72, 0x79, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, - 0x55, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, - 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, - 0x12, 0x35, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x70, - 0x62, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x70, 0x65, - 0x63, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, - 0x62, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x10, 0x2e, 0x70, 0x62, - 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, - 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x38, 0x0a, 0x09, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x2e, - 0x70, 0x62, 0x2e, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x47, 0x63, - 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1b, - 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x47, 0x63, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, - 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, - 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x37, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x13, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2d, 0x69, 0x6e, - 0x63, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x69, 0x6c, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x43, 0x0a, 0x11, 0x47, + 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x22, 0x8f, 0x01, 0x0a, 0x17, 0x47, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6b, 0x65, 0x65, + 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x66, 0x72, 0x6f, + 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, + 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x18, 0x47, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x22, 0x2b, 0x0a, 0x11, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0x2a, 0x0a, + 0x12, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x61, 0x0a, 0x15, 0x43, 0x6c, 0x6f, + 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3f, 0x0a, 0x16, + 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x11, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x33, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x14, + 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x32, 0x5f, 0x54, + 0x41, 0x52, 0x10, 0x00, 0x32, 0xfb, 0x07, 0x0a, 0x02, 0x46, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x4e, + 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, + 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x17, + 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x28, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x40, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x35, 0x0a, + 0x08, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x11, + 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x41, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x52, 0x6f, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, + 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x32, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x12, 0x2e, 0x70, + 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x47, 0x63, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, + 0x70, 0x62, 0x2e, 0x47, 0x63, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x47, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, + 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x52, 0x61, 0x6e, + 0x64, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x63, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x47, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, + 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x54, 0x6f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x47, 0x65, 0x74, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x30, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x2d, 0x69, 0x6e, 0x63, 0x2f, 0x64, 0x61, 0x74, 0x65, + 0x69, 0x6c, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2284,7 +2418,7 @@ func file_internal_pb_fs_proto_rawDescGZIP() []byte { } var file_internal_pb_fs_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_internal_pb_fs_proto_msgTypes = make([]protoimpl.MessageInfo, 35) +var file_internal_pb_fs_proto_msgTypes = make([]protoimpl.MessageInfo, 37) var file_internal_pb_fs_proto_goTypes = []interface{}{ (GetCompressResponse_Format)(0), // 0: pb.GetCompressResponse.Format (GetCacheResponse_Format)(0), // 1: pb.GetCacheResponse.Format @@ -2305,24 +2439,26 @@ var file_internal_pb_fs_proto_goTypes = []interface{}{ (*GetUnaryResponse)(nil), // 16: pb.GetUnaryResponse (*UpdateRequest)(nil), // 17: pb.UpdateRequest (*UpdateResponse)(nil), // 18: pb.UpdateResponse - (*RollbackRequest)(nil), // 19: pb.RollbackRequest - (*RollbackResponse)(nil), // 20: pb.RollbackResponse - (*InspectRequest)(nil), // 21: pb.InspectRequest - (*InspectResponse)(nil), // 22: pb.InspectResponse - (*SnapshotRequest)(nil), // 23: pb.SnapshotRequest - (*SnapshotResponse)(nil), // 24: pb.SnapshotResponse - (*ResetRequest)(nil), // 25: pb.ResetRequest - (*ResetResponse)(nil), // 26: pb.ResetResponse - (*GcProjectRequest)(nil), // 27: pb.GcProjectRequest - (*GcProjectResponse)(nil), // 28: pb.GcProjectResponse - (*GcRandomProjectsRequest)(nil), // 29: pb.GcRandomProjectsRequest - (*GcRandomProjectsResponse)(nil), // 30: pb.GcRandomProjectsResponse - (*GcContentsRequest)(nil), // 31: pb.GcContentsRequest - (*GcContentsResponse)(nil), // 32: pb.GcContentsResponse - (*CloneToProjectRequest)(nil), // 33: pb.CloneToProjectRequest - (*CloneToProjectResponse)(nil), // 34: pb.CloneToProjectResponse - (*GetCacheRequest)(nil), // 35: pb.GetCacheRequest - (*GetCacheResponse)(nil), // 36: pb.GetCacheResponse + (*CommitUpdateRequest)(nil), // 19: pb.CommitUpdateRequest + (*CommitUpdateResponse)(nil), // 20: pb.CommitUpdateResponse + (*RollbackRequest)(nil), // 21: pb.RollbackRequest + (*RollbackResponse)(nil), // 22: pb.RollbackResponse + (*InspectRequest)(nil), // 23: pb.InspectRequest + (*InspectResponse)(nil), // 24: pb.InspectResponse + (*SnapshotRequest)(nil), // 25: pb.SnapshotRequest + (*SnapshotResponse)(nil), // 26: pb.SnapshotResponse + (*ResetRequest)(nil), // 27: pb.ResetRequest + (*ResetResponse)(nil), // 28: pb.ResetResponse + (*GcProjectRequest)(nil), // 29: pb.GcProjectRequest + (*GcProjectResponse)(nil), // 30: pb.GcProjectResponse + (*GcRandomProjectsRequest)(nil), // 31: pb.GcRandomProjectsRequest + (*GcRandomProjectsResponse)(nil), // 32: pb.GcRandomProjectsResponse + (*GcContentsRequest)(nil), // 33: pb.GcContentsRequest + (*GcContentsResponse)(nil), // 34: pb.GcContentsResponse + (*CloneToProjectRequest)(nil), // 35: pb.CloneToProjectRequest + (*CloneToProjectResponse)(nil), // 36: pb.CloneToProjectResponse + (*GetCacheRequest)(nil), // 37: pb.GetCacheRequest + (*GetCacheResponse)(nil), // 38: pb.GetCacheResponse } var file_internal_pb_fs_proto_depIdxs = []int32{ 6, // 0: pb.ListProjectsResponse.projects:type_name -> pb.Project @@ -2343,33 +2479,35 @@ var file_internal_pb_fs_proto_depIdxs = []int32{ 13, // 15: pb.Fs.GetCompress:input_type -> pb.GetCompressRequest 15, // 16: pb.Fs.GetUnary:input_type -> pb.GetUnaryRequest 17, // 17: pb.Fs.Update:input_type -> pb.UpdateRequest - 19, // 18: pb.Fs.Rollback:input_type -> pb.RollbackRequest - 21, // 19: pb.Fs.Inspect:input_type -> pb.InspectRequest - 23, // 20: pb.Fs.Snapshot:input_type -> pb.SnapshotRequest - 25, // 21: pb.Fs.Reset:input_type -> pb.ResetRequest - 27, // 22: pb.Fs.GcProject:input_type -> pb.GcProjectRequest - 29, // 23: pb.Fs.GcRandomProjects:input_type -> pb.GcRandomProjectsRequest - 31, // 24: pb.Fs.GcContents:input_type -> pb.GcContentsRequest - 33, // 25: pb.Fs.CloneToProject:input_type -> pb.CloneToProjectRequest - 35, // 26: pb.Fs.GetCache:input_type -> pb.GetCacheRequest - 3, // 27: pb.Fs.NewProject:output_type -> pb.NewProjectResponse - 5, // 28: pb.Fs.DeleteProject:output_type -> pb.DeleteProjectResponse - 8, // 29: pb.Fs.ListProjects:output_type -> pb.ListProjectsResponse - 12, // 30: pb.Fs.Get:output_type -> pb.GetResponse - 14, // 31: pb.Fs.GetCompress:output_type -> pb.GetCompressResponse - 16, // 32: pb.Fs.GetUnary:output_type -> pb.GetUnaryResponse - 18, // 33: pb.Fs.Update:output_type -> pb.UpdateResponse - 20, // 34: pb.Fs.Rollback:output_type -> pb.RollbackResponse - 22, // 35: pb.Fs.Inspect:output_type -> pb.InspectResponse - 24, // 36: pb.Fs.Snapshot:output_type -> pb.SnapshotResponse - 26, // 37: pb.Fs.Reset:output_type -> pb.ResetResponse - 28, // 38: pb.Fs.GcProject:output_type -> pb.GcProjectResponse - 30, // 39: pb.Fs.GcRandomProjects:output_type -> pb.GcRandomProjectsResponse - 32, // 40: pb.Fs.GcContents:output_type -> pb.GcContentsResponse - 34, // 41: pb.Fs.CloneToProject:output_type -> pb.CloneToProjectResponse - 36, // 42: pb.Fs.GetCache:output_type -> pb.GetCacheResponse - 27, // [27:43] is the sub-list for method output_type - 11, // [11:27] is the sub-list for method input_type + 19, // 18: pb.Fs.CommitUpdate:input_type -> pb.CommitUpdateRequest + 21, // 19: pb.Fs.Rollback:input_type -> pb.RollbackRequest + 23, // 20: pb.Fs.Inspect:input_type -> pb.InspectRequest + 25, // 21: pb.Fs.Snapshot:input_type -> pb.SnapshotRequest + 27, // 22: pb.Fs.Reset:input_type -> pb.ResetRequest + 29, // 23: pb.Fs.GcProject:input_type -> pb.GcProjectRequest + 31, // 24: pb.Fs.GcRandomProjects:input_type -> pb.GcRandomProjectsRequest + 33, // 25: pb.Fs.GcContents:input_type -> pb.GcContentsRequest + 35, // 26: pb.Fs.CloneToProject:input_type -> pb.CloneToProjectRequest + 37, // 27: pb.Fs.GetCache:input_type -> pb.GetCacheRequest + 3, // 28: pb.Fs.NewProject:output_type -> pb.NewProjectResponse + 5, // 29: pb.Fs.DeleteProject:output_type -> pb.DeleteProjectResponse + 8, // 30: pb.Fs.ListProjects:output_type -> pb.ListProjectsResponse + 12, // 31: pb.Fs.Get:output_type -> pb.GetResponse + 14, // 32: pb.Fs.GetCompress:output_type -> pb.GetCompressResponse + 16, // 33: pb.Fs.GetUnary:output_type -> pb.GetUnaryResponse + 18, // 34: pb.Fs.Update:output_type -> pb.UpdateResponse + 20, // 35: pb.Fs.CommitUpdate:output_type -> pb.CommitUpdateResponse + 22, // 36: pb.Fs.Rollback:output_type -> pb.RollbackResponse + 24, // 37: pb.Fs.Inspect:output_type -> pb.InspectResponse + 26, // 38: pb.Fs.Snapshot:output_type -> pb.SnapshotResponse + 28, // 39: pb.Fs.Reset:output_type -> pb.ResetResponse + 30, // 40: pb.Fs.GcProject:output_type -> pb.GcProjectResponse + 32, // 41: pb.Fs.GcRandomProjects:output_type -> pb.GcRandomProjectsResponse + 34, // 42: pb.Fs.GcContents:output_type -> pb.GcContentsResponse + 36, // 43: pb.Fs.CloneToProject:output_type -> pb.CloneToProjectResponse + 38, // 44: pb.Fs.GetCache:output_type -> pb.GetCacheResponse + 28, // [28:45] is the sub-list for method output_type + 11, // [11:28] is the sub-list for method input_type 11, // [11:11] is the sub-list for extension type_name 11, // [11:11] is the sub-list for extension extendee 0, // [0:11] is the sub-list for field type_name @@ -2586,7 +2724,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RollbackRequest); i { + switch v := v.(*CommitUpdateRequest); i { case 0: return &v.state case 1: @@ -2598,7 +2736,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RollbackResponse); i { + switch v := v.(*CommitUpdateResponse); i { case 0: return &v.state case 1: @@ -2610,7 +2748,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InspectRequest); i { + switch v := v.(*RollbackRequest); i { case 0: return &v.state case 1: @@ -2622,7 +2760,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InspectResponse); i { + switch v := v.(*RollbackResponse); i { case 0: return &v.state case 1: @@ -2634,7 +2772,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SnapshotRequest); i { + switch v := v.(*InspectRequest); i { case 0: return &v.state case 1: @@ -2646,7 +2784,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SnapshotResponse); i { + switch v := v.(*InspectResponse); i { case 0: return &v.state case 1: @@ -2658,7 +2796,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResetRequest); i { + switch v := v.(*SnapshotRequest); i { case 0: return &v.state case 1: @@ -2670,7 +2808,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResetResponse); i { + switch v := v.(*SnapshotResponse); i { case 0: return &v.state case 1: @@ -2682,7 +2820,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcProjectRequest); i { + switch v := v.(*ResetRequest); i { case 0: return &v.state case 1: @@ -2694,7 +2832,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcProjectResponse); i { + switch v := v.(*ResetResponse); i { case 0: return &v.state case 1: @@ -2706,7 +2844,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcRandomProjectsRequest); i { + switch v := v.(*GcProjectRequest); i { case 0: return &v.state case 1: @@ -2718,7 +2856,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcRandomProjectsResponse); i { + switch v := v.(*GcProjectResponse); i { case 0: return &v.state case 1: @@ -2730,7 +2868,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcContentsRequest); i { + switch v := v.(*GcRandomProjectsRequest); i { case 0: return &v.state case 1: @@ -2742,7 +2880,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GcContentsResponse); i { + switch v := v.(*GcRandomProjectsResponse); i { case 0: return &v.state case 1: @@ -2754,7 +2892,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CloneToProjectRequest); i { + switch v := v.(*GcContentsRequest); i { case 0: return &v.state case 1: @@ -2766,7 +2904,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CloneToProjectResponse); i { + switch v := v.(*GcContentsResponse); i { case 0: return &v.state case 1: @@ -2778,7 +2916,7 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCacheRequest); i { + switch v := v.(*CloneToProjectRequest); i { case 0: return &v.state case 1: @@ -2790,6 +2928,30 @@ func file_internal_pb_fs_proto_init() { } } file_internal_pb_fs_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloneToProjectResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_pb_fs_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetCacheRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_pb_fs_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetCacheResponse); i { case 0: return &v.state @@ -2808,15 +2970,15 @@ func file_internal_pb_fs_proto_init() { file_internal_pb_fs_proto_msgTypes[11].OneofWrappers = []interface{}{} file_internal_pb_fs_proto_msgTypes[12].OneofWrappers = []interface{}{} file_internal_pb_fs_proto_msgTypes[13].OneofWrappers = []interface{}{} - file_internal_pb_fs_proto_msgTypes[25].OneofWrappers = []interface{}{} file_internal_pb_fs_proto_msgTypes[27].OneofWrappers = []interface{}{} + file_internal_pb_fs_proto_msgTypes[29].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_internal_pb_fs_proto_rawDesc, NumEnums: 2, - NumMessages: 35, + NumMessages: 37, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/pb/fs.proto b/internal/pb/fs.proto index 5e7be91..ed69ed9 100644 --- a/internal/pb/fs.proto +++ b/internal/pb/fs.proto @@ -19,6 +19,8 @@ service Fs { rpc Update(stream UpdateRequest) returns (UpdateResponse); + rpc CommitUpdate(CommitUpdateRequest) returns (CommitUpdateResponse); + rpc Rollback(RollbackRequest) returns (RollbackResponse); rpc Inspect(InspectRequest) returns (InspectResponse); @@ -128,10 +130,21 @@ message GetUnaryResponse { message UpdateRequest { int64 project = 1; Objekt object = 2; + bool is_staged = 3; } message UpdateResponse { int64 version = 1; + bool is_staged = 2; +} + +message CommitUpdateRequest { + int64 project = 1; + int64 version = 2; +} + +message CommitUpdateResponse { + int64 version = 1; } message RollbackRequest { diff --git a/internal/pb/fs_grpc.pb.go b/internal/pb/fs_grpc.pb.go index 8fc9088..fa40a4b 100644 --- a/internal/pb/fs_grpc.pb.go +++ b/internal/pb/fs_grpc.pb.go @@ -26,6 +26,7 @@ const ( Fs_GetCompress_FullMethodName = "/pb.Fs/GetCompress" Fs_GetUnary_FullMethodName = "/pb.Fs/GetUnary" Fs_Update_FullMethodName = "/pb.Fs/Update" + Fs_CommitUpdate_FullMethodName = "/pb.Fs/CommitUpdate" Fs_Rollback_FullMethodName = "/pb.Fs/Rollback" Fs_Inspect_FullMethodName = "/pb.Fs/Inspect" Fs_Snapshot_FullMethodName = "/pb.Fs/Snapshot" @@ -48,6 +49,7 @@ type FsClient interface { GetCompress(ctx context.Context, in *GetCompressRequest, opts ...grpc.CallOption) (Fs_GetCompressClient, error) GetUnary(ctx context.Context, in *GetUnaryRequest, opts ...grpc.CallOption) (*GetUnaryResponse, error) Update(ctx context.Context, opts ...grpc.CallOption) (Fs_UpdateClient, error) + CommitUpdate(ctx context.Context, in *CommitUpdateRequest, opts ...grpc.CallOption) (*CommitUpdateResponse, error) Rollback(ctx context.Context, in *RollbackRequest, opts ...grpc.CallOption) (*RollbackResponse, error) Inspect(ctx context.Context, in *InspectRequest, opts ...grpc.CallOption) (*InspectResponse, error) Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (*SnapshotResponse, error) @@ -201,6 +203,15 @@ func (x *fsUpdateClient) CloseAndRecv() (*UpdateResponse, error) { return m, nil } +func (c *fsClient) CommitUpdate(ctx context.Context, in *CommitUpdateRequest, opts ...grpc.CallOption) (*CommitUpdateResponse, error) { + out := new(CommitUpdateResponse) + err := c.cc.Invoke(ctx, Fs_CommitUpdate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *fsClient) Rollback(ctx context.Context, in *RollbackRequest, opts ...grpc.CallOption) (*RollbackResponse, error) { out := new(RollbackResponse) err := c.cc.Invoke(ctx, Fs_Rollback_FullMethodName, in, out, opts...) @@ -316,6 +327,7 @@ type FsServer interface { GetCompress(*GetCompressRequest, Fs_GetCompressServer) error GetUnary(context.Context, *GetUnaryRequest) (*GetUnaryResponse, error) Update(Fs_UpdateServer) error + CommitUpdate(context.Context, *CommitUpdateRequest) (*CommitUpdateResponse, error) Rollback(context.Context, *RollbackRequest) (*RollbackResponse, error) Inspect(context.Context, *InspectRequest) (*InspectResponse, error) Snapshot(context.Context, *SnapshotRequest) (*SnapshotResponse, error) @@ -353,6 +365,9 @@ func (UnimplementedFsServer) GetUnary(context.Context, *GetUnaryRequest) (*GetUn func (UnimplementedFsServer) Update(Fs_UpdateServer) error { return status.Errorf(codes.Unimplemented, "method Update not implemented") } +func (UnimplementedFsServer) CommitUpdate(context.Context, *CommitUpdateRequest) (*CommitUpdateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CommitUpdate not implemented") +} func (UnimplementedFsServer) Rollback(context.Context, *RollbackRequest) (*RollbackResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Rollback not implemented") } @@ -533,6 +548,24 @@ func (x *fsUpdateServer) Recv() (*UpdateRequest, error) { return m, nil } +func _Fs_CommitUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CommitUpdateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FsServer).CommitUpdate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Fs_CommitUpdate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FsServer).CommitUpdate(ctx, req.(*CommitUpdateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Fs_Rollback_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RollbackRequest) if err := dec(in); err != nil { @@ -721,6 +754,10 @@ var Fs_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetUnary", Handler: _Fs_GetUnary_Handler, }, + { + MethodName: "CommitUpdate", + Handler: _Fs_CommitUpdate_Handler, + }, { MethodName: "Rollback", Handler: _Fs_Rollback_Handler, diff --git a/migrations/000007_staged_update.down.sql b/migrations/000007_staged_update.down.sql new file mode 100644 index 0000000..c76a168 --- /dev/null +++ b/migrations/000007_staged_update.down.sql @@ -0,0 +1 @@ +DROP TABLE dl.staged_objects; diff --git a/migrations/000007_staged_update.up.sql b/migrations/000007_staged_update.up.sql new file mode 100644 index 0000000..144dd6d --- /dev/null +++ b/migrations/000007_staged_update.up.sql @@ -0,0 +1,19 @@ +CREATE TABLE dl.staged_objects ( + project bigint NOT NULL, + start_version bigint, + stop_version bigint, + path text NOT NULL, + hash hash, + mode bigint, + size bigint, + packed boolean +); + +CREATE UNIQUE INDEX staged_objects_idx ON dl.staged_objects + (project, start_version, stop_version, path text_pattern_ops); + +CREATE UNIQUE INDEX staged_objects_latest_idx ON dl.staged_objects + (project, stop_version, path text_pattern_ops); + +CREATE UNIQUE INDEX identical_staged_objects_idx ON dl.staged_objects + (project, (stop_version IS NULL), path, hash, mode) WHERE stop_version IS NULL; diff --git a/pkg/api/fs.go b/pkg/api/fs.go index c15f29a..8aef1e2 100644 --- a/pkg/api/fs.go +++ b/pkg/api/fs.go @@ -20,6 +20,7 @@ import ( var ( ErrMultipleProjectsPerUpdate = errors.New("multiple objects in one update") + ErrMixedIsStagedPerUpdate = errors.New("mixed is_staged values in one update") ) func requireAdminAuth(ctx context.Context) error { @@ -505,6 +506,8 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { var packManager *db.PackManager + isStaged := false + var objectBuffer []*pb.Object packedBuffer := make(map[string][]*pb.Object) @@ -545,6 +548,12 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { continue } + if req.IsStaged { + isStaged = true + } else if isStaged { + return status.Errorf(codes.InvalidArgument, "invalid is_staged: %v", ErrMixedIsStagedPerUpdate) + } + objectBuffer = append(objectBuffer, req.Object) } @@ -574,21 +583,22 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { } nextVersion = latestVersion + 1 - logger.Info(ctx, "FS.Update[Init]", key.Project.Field(project), key.Version.Field(nextVersion)) + logger.Info(ctx, "FS.Update[Init]", key.Project.Field(project), key.Version.Field(nextVersion), key.IsStaged.Field(isStaged)) for _, object := range objectBuffer { logger.Debug(ctx, "FS.Update[Object]", key.Project.Field(project), key.Version.Field(nextVersion), key.ObjectPath.Field(object.Path), + key.IsStaged.Field(isStaged), ) if object.Deleted { - err = db.DeleteObject(ctx, tx, project, nextVersion, object.Path) + err = db.DeleteObject(ctx, tx, project, nextVersion, object.Path, isStaged) shouldUpdateVersion = true } else { var contentChanged bool - contentChanged, err = db.UpdateObject(ctx, tx, f.DbConn, contentEncoder, project, nextVersion, object) + contentChanged, err = db.UpdateObject(ctx, tx, f.DbConn, contentEncoder, project, nextVersion, object, isStaged) if contentChanged { shouldUpdateVersion = true @@ -613,9 +623,10 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { key.Version.Field(nextVersion), key.ObjectsParent.Field(parent), key.ObjectsCount.Field(len(objects)), + key.IsStaged.Field(isStaged), ) - contentChanged, err := db.UpdatePackedObjects(ctx, tx, f.DbConn, project, nextVersion, parent, objects) + contentChanged, err := db.UpdatePackedObjects(ctx, tx, f.DbConn, project, nextVersion, parent, objects, isStaged) if err != nil { return status.Errorf(codes.Internal, "FS update packed objects for %v: %v", parent, err) } @@ -632,12 +643,14 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { } if !shouldUpdateVersion { - return stream.SendAndClose(&pb.UpdateResponse{Version: latestVersion}) + return stream.SendAndClose(&pb.UpdateResponse{Version: latestVersion, IsStaged: isStaged}) } - err = db.UpdateLatestVersion(ctx, tx, project, nextVersion) - if err != nil { - return status.Errorf(codes.Internal, "FS update latest version: %v", err) + if !isStaged { + err = db.UpdateLatestVersion(ctx, tx, project, nextVersion) + if err != nil { + return status.Errorf(codes.Internal, "FS update latest version: %v", err) + } } err = tx.Commit(ctx) @@ -645,9 +658,66 @@ func (f *Fs) Update(stream pb.Fs_UpdateServer) error { return status.Errorf(codes.Internal, "FS update commit tx: %v", err) } - logger.Debug(ctx, "FS.Update[Commit]", key.Project.Field(project), key.Version.Field(nextVersion)) + logger.Debug(ctx, "FS.Update[Commit]", key.Project.Field(project), key.Version.Field(nextVersion), key.IsStaged.Field(isStaged)) + + return stream.SendAndClose(&pb.UpdateResponse{Version: nextVersion, IsStaged: isStaged}) +} + +func (f *Fs) CommitUpdate(ctx context.Context, req *pb.CommitUpdateRequest) (*pb.CommitUpdateResponse, error) { + trace.SpanFromContext(ctx).SetAttributes( + key.Project.Attribute(req.Project), + ) + + project, err := requireProjectAuth(ctx) + if err != nil { + return nil, err + } + + if project > -1 && req.Project != project { + return nil, status.Errorf(codes.PermissionDenied, "Mismatch project authorization and request") + } + + tx, close, err := f.DbConn.Connect(ctx) + if err != nil { + return nil, status.Errorf(codes.Unavailable, "FS db connection unavailable: %v", err) + } + defer close(ctx) + + latestVersion, err := db.LockLatestVersion(ctx, tx, req.Project) + if errors.Is(err, db.ErrNotFound) { + return nil, status.Errorf(codes.NotFound, "FS commit missing latest version: %v", err) + } + if err != nil { + return nil, status.Errorf(codes.Internal, "FS commit lock latest version: %v", err) + } + + nextVersion := latestVersion + 1 + if nextVersion != req.Version { + return nil, status.Errorf(codes.InvalidArgument, "FS commit invalid, latest version %v is greater than or equal to the commit version %v", latestVersion, req.Version) + } + + logger.Info(ctx, "FS.Commit[Init]", key.Project.Field(req.Project), key.Version.Field(nextVersion)) + + err = telemetry.Trace(ctx, "commit-staged-objects", func(ctx context.Context, span trace.Span) error { + return db.CommitStagedObjects(ctx, tx, req.Project, nextVersion) + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "FS commit staged objects: %v", err) + } + + err = db.UpdateLatestVersion(ctx, tx, req.Project, nextVersion) + if err != nil { + return nil, status.Errorf(codes.Internal, "FS commit latest version: %v", err) + } + + err = tx.Commit(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "FS commit commit tx: %v", err) + } + + logger.Debug(ctx, "FS.Commit[Commit]", key.Project.Field(project), key.Version.Field(nextVersion)) - return stream.SendAndClose(&pb.UpdateResponse{Version: nextVersion}) + return &pb.CommitUpdateResponse{}, nil } func (f *Fs) Rollback(ctx context.Context, req *pb.RollbackRequest) (*pb.RollbackResponse, error) { diff --git a/pkg/cli/client.go b/pkg/cli/client.go index 7da1125..7169594 100644 --- a/pkg/cli/client.go +++ b/pkg/cli/client.go @@ -125,6 +125,7 @@ func NewClientCommand() *cobra.Command { cmd.AddCommand(NewCmdReset()) cmd.AddCommand(NewCmdSnapshot()) cmd.AddCommand(NewCmdUpdate()) + cmd.AddCommand(NewCmdCommit()) cmd.AddCommand(NewCmdGc()) cmd.AddCommand(NewCmdGetCache()) diff --git a/pkg/cli/commit.go b/pkg/cli/commit.go new file mode 100644 index 0000000..2368833 --- /dev/null +++ b/pkg/cli/commit.go @@ -0,0 +1,39 @@ +package cli + +import ( + "fmt" + + "github.com/gadget-inc/dateilager/pkg/client" + "github.com/spf13/cobra" +) + +func NewCmdCommit() *cobra.Command { + var ( + project int64 + version int64 + ) + + cmd := &cobra.Command{ + Use: "commit", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + client := client.FromContext(ctx) + + err := client.CommitUpdate(ctx, project, version) + if err != nil { + return fmt.Errorf("commit objects: %w", err) + } + + return nil + }, + } + + cmd.Flags().Int64Var(&project, "project", -1, "Project ID (required)") + cmd.Flags().Int64Var(&version, "version", -1, "Staged version to commit") + + _ = cmd.MarkFlagRequired("project") + _ = cmd.MarkFlagRequired("version") + + return cmd +} diff --git a/pkg/cli/update.go b/pkg/cli/update.go index 62921ce..ee1eb88 100644 --- a/pkg/cli/update.go +++ b/pkg/cli/update.go @@ -11,8 +11,9 @@ import ( func NewCmdUpdate() *cobra.Command { var ( - project int64 - dir string + project int64 + dir string + isStaged bool ) cmd := &cobra.Command{ @@ -22,7 +23,7 @@ func NewCmdUpdate() *cobra.Command { client := client.FromContext(ctx) - version, count, err := client.Update(ctx, project, dir) + version, count, err := client.Update(ctx, project, dir, isStaged) if err != nil { return fmt.Errorf("update objects: %w", err) } @@ -40,6 +41,7 @@ func NewCmdUpdate() *cobra.Command { cmd.Flags().Int64Var(&project, "project", -1, "Project ID (required)") cmd.Flags().StringVar(&dir, "dir", "", "Directory containing updated files") + cmd.Flags().BoolVar(&isStaged, "staged", false, "Stage the update without committing it") _ = cmd.MarkFlagRequired("project") diff --git a/pkg/client/client.go b/pkg/client/client.go index c741e41..3904980 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -480,7 +480,7 @@ func (c *Client) Rebuild(ctx context.Context, project int64, prefix string, toVe return result, nil } -func (c *Client) Update(rootCtx context.Context, project int64, dir string) (int64, uint32, error) { +func (c *Client) Update(rootCtx context.Context, project int64, dir string, isStaged bool) (int64, uint32, error) { rootCtx, span := telemetry.Start(rootCtx, "client.update", trace.WithAttributes( key.Project.Attribute(project), key.Directory.Attribute(dir), @@ -589,8 +589,9 @@ func (c *Client) Update(rootCtx context.Context, project int64, dir string) (int count += 1 err := stream.Send(&pb.UpdateRequest{ - Project: project, - Object: object, + Project: project, + Object: object, + IsStaged: isStaged, }) if err != nil { cancel() @@ -629,6 +630,23 @@ func (c *Client) Update(rootCtx context.Context, project int64, dir string) (int return toVersion, updateCount, nil } +func (c *Client) CommitUpdate(ctx context.Context, project, version int64) error { + ctx, span := telemetry.Start(ctx, "client.commit", trace.WithAttributes( + key.Project.Attribute(project), + )) + defer span.End() + + _, err := c.fs.CommitUpdate(ctx, &pb.CommitUpdateRequest{ + Project: project, + Version: version, + }) + if err != nil { + return fmt.Errorf("commit update, project %v, version %v: %w", project, version, err) + } + + return nil +} + func (c *Client) Inspect(ctx context.Context, project int64) (*pb.InspectResponse, error) { ctx, span := telemetry.Start(ctx, "client.inspect", trace.WithAttributes( key.Project.Attribute(project), diff --git a/test/client_update_test.go b/test/client_update_test.go index 468813d..a72b3ec 100644 --- a/test/client_update_test.go +++ b/test/client_update_test.go @@ -220,7 +220,7 @@ func TestUpdateFailsWithTooLargeObject(t *testing.T) { } writeFile(t, tmpDir, "a", sb.String()) - _, _, err := c.Update(tc.Context(), 1, tmpDir) + _, _, err := c.Update(tc.Context(), 1, tmpDir, false) assert.Error(tc.T(), err) } diff --git a/test/shared_test.go b/test/shared_test.go index 83834a3..b6ffcca 100644 --- a/test/shared_test.go +++ b/test/shared_test.go @@ -415,7 +415,7 @@ func rebuildWithMatcher(tc util.TestCtx, c *client.Client, project int64, toVers } func update(tc util.TestCtx, c *client.Client, project int64, dir string, expected expectedResponse) { - version, count, err := c.Update(tc.Context(), project, dir) + version, count, err := c.Update(tc.Context(), project, dir, false) require.NoError(tc.T(), err, "client.Update") assert.Equal(tc.T(), expected.version, version, "mismatch update version")