From 425caf16c15f25ffdc61fdb77a84b18c02af062b Mon Sep 17 00:00:00 2001 From: Nick Petrovic <4001122+nickpetrovic@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:44:42 -0500 Subject: [PATCH] add local jfs gateway, fix edge cases, dynamic chunk size --- hack/k3d.yaml | 3 + .../juicefs/helm-chart-generator.yaml | 36 + .../components/juicefs/kustomization.yaml | 11 + .../overlays/cluster-dev/kustomization.yaml | 8 + pkg/abstractions/volume/volume.go | 30 + pkg/abstractions/volume/volume.proto | 10 + pkg/common/config.default.yaml | 6 +- proto/volume.pb.go | 630 +++++++++++------- proto/volume_grpc.pb.go | 37 + sdk/poetry.lock | 4 +- sdk/pyproject.toml | 2 +- sdk/src/beta9/cli/volume.py | 35 +- sdk/src/beta9/clients/volume/__init__.py | 19 + sdk/src/beta9/multipart.py | 102 ++- 14 files changed, 641 insertions(+), 292 deletions(-) diff --git a/hack/k3d.yaml b/hack/k3d.yaml index 84be69aae..41cf37969 100644 --- a/hack/k3d.yaml +++ b/hack/k3d.yaml @@ -19,6 +19,9 @@ ports: - port: 8008:8008 nodeFilters: - loadbalancer +- port: 9900:9900 + nodeFilters: + - loadbalancer volumes: - volume: $PWD/manifests/k3d:k3s-manifests-custom diff --git a/manifests/kustomize/components/juicefs/helm-chart-generator.yaml b/manifests/kustomize/components/juicefs/helm-chart-generator.yaml index 532b21569..c9a81974b 100644 --- a/manifests/kustomize/components/juicefs/helm-chart-generator.yaml +++ b/manifests/kustomize/components/juicefs/helm-chart-generator.yaml @@ -19,3 +19,39 @@ valuesInline: master: persistence: size: 1Gi +--- +apiVersion: builtin +kind: HelmChartInflationGenerator +metadata: + name: &name juicefs-s3-gateway +releaseName: *name +name: &name juicefs-s3-gateway +repo: https://juicedata.github.io/charts/ +version: 0.11.2 +namespace: beta9 +includeCRDs: true +skipTests: true +valuesInline: + nameOverride: *name + fullnameOverride: *name + port: 9900 + service: + type: LoadBalancer + secret: + name: beta9-fs + metaurl: redis://juicefs-redis-master:6379/0 + storage: s3 + accessKey: test + secretKey: test-test-test + bucket: http://localstack:4566/juicefs + + # -- JuiceFS format options. Separated by spaces + # Example: "--inodes=1000000 --block-size=4M" + # Ref: https://juicefs.com/docs/community/command_reference#format + formatOptions: "--block-size=4096 --no-update" + + # -- Gateway Options. Separated by spaces + # Example: "--get-timeout=60 --put-timeout=60" + # CE Ref: https://juicefs.com/docs/community/command_reference#gateway + # EE Ref: https://juicefs.com/docs/cloud/reference/command_reference/#gateway + options: "--buffer-size=300 --cache-size=0 --prefetch=-1 --no-usage-report" diff --git a/manifests/kustomize/components/juicefs/kustomization.yaml b/manifests/kustomize/components/juicefs/kustomization.yaml index 1cbf89403..f4cb30563 100644 --- a/manifests/kustomize/components/juicefs/kustomization.yaml +++ b/manifests/kustomize/components/juicefs/kustomization.yaml @@ -4,3 +4,14 @@ kind: Component generators: - helm-chart-generator.yaml + +patches: +- target: + kind: Deployment + name: juicefs-s3-gateway + patch: |- + - op: remove + path: /spec/template/spec/containers/0/env/0/valueFrom + - op: add + path: /spec/template/spec/containers/0/env/0/value + value: 0.0.0.0 diff --git a/manifests/kustomize/overlays/cluster-dev/kustomization.yaml b/manifests/kustomize/overlays/cluster-dev/kustomization.yaml index 176f58d2c..51df7f0db 100644 --- a/manifests/kustomize/overlays/cluster-dev/kustomization.yaml +++ b/manifests/kustomize/overlays/cluster-dev/kustomization.yaml @@ -61,3 +61,11 @@ patches: - op: replace path: /spec/replicas value: 0 +# Replace RollingUpdate with Recreate for all Deployments in this overlay +- target: + kind: Deployment + patch: | + - op: add + path: /spec/strategy + value: + type: Recreate diff --git a/pkg/abstractions/volume/volume.go b/pkg/abstractions/volume/volume.go index b34aea046..73ba3c24e 100644 --- a/pkg/abstractions/volume/volume.go +++ b/pkg/abstractions/volume/volume.go @@ -228,6 +228,36 @@ func (vs *GlobalVolumeService) MovePath(ctx context.Context, in *pb.MovePathRequ }, nil } +func (vs *GlobalVolumeService) StatPath(ctx context.Context, in *pb.StatPathRequest) (*pb.StatPathResponse, error) { + authInfo, _ := auth.AuthInfoFromContext(ctx) + + path, err := vs.getFilePath(ctx, in.Path, authInfo.Workspace) + if err != nil { + return &pb.StatPathResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + info, err := os.Stat(path) + if err != nil { + return &pb.StatPathResponse{ + Ok: true, + ErrMsg: "Path does not exist", + }, nil + } + + return &pb.StatPathResponse{ + Ok: true, + PathInfo: &pb.PathInfo{ + Path: in.Path, + Size: uint64(info.Size()), + ModTime: timestamppb.New(info.ModTime()), + IsDir: info.IsDir(), + }, + }, nil +} + // Volume business logic func (vs *GlobalVolumeService) getOrCreateVolume(ctx context.Context, workspace *types.Workspace, volumeName string) (*types.Volume, error) { volume, err := vs.backendRepo.GetOrCreateVolume(ctx, workspace.Id, volumeName) diff --git a/pkg/abstractions/volume/volume.proto b/pkg/abstractions/volume/volume.proto index 6a864b8c6..5bf3a39e7 100644 --- a/pkg/abstractions/volume/volume.proto +++ b/pkg/abstractions/volume/volume.proto @@ -13,6 +13,7 @@ service VolumeService { rpc DeletePath(DeletePathRequest) returns (DeletePathResponse) {} rpc CopyPathStream(stream CopyPathRequest) returns (CopyPathResponse) {} rpc MovePath(MovePathRequest) returns (MovePathResponse) {} + rpc StatPath(StatPathRequest) returns (StatPathResponse) {} // Multipart Upload rpc CreatePresignedURL(CreatePresignedURLRequest) returns (CreatePresignedURLResponse) {} @@ -107,6 +108,15 @@ message MovePathResponse { string new_path = 3; } +message StatPathRequest { + string path = 1; +} + +message StatPathResponse { + bool ok = 1; + string err_msg = 2; + PathInfo path_info = 3; +} message PresignedURLParams { string upload_id = 1; diff --git a/pkg/common/config.default.yaml b/pkg/common/config.default.yaml index 1637baf06..c9c5674a4 100644 --- a/pkg/common/config.default.yaml +++ b/pkg/common/config.default.yaml @@ -57,10 +57,10 @@ gateway: maxReplicas: 10 maxGpuCount: 2 fileService: - endpointUrl: https://data-stage-beam-cloud.fly.dev + endpointUrl: http://juicefs-s3-gateway.beta9.svc.cluster.local:9900 bucketName: beta9-fs - accessKey: - secretKey: + accessKey: test + secretKey: test-test-test region: imageService: localCacheEnabled: true diff --git a/proto/volume.pb.go b/proto/volume.pb.go index e0741c61c..c8db13478 100644 --- a/proto/volume.pb.go +++ b/proto/volume.pb.go @@ -1008,6 +1008,116 @@ func (x *MovePathResponse) GetNewPath() string { return "" } +type StatPathRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *StatPathRequest) Reset() { + *x = StatPathRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_volume_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatPathRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatPathRequest) ProtoMessage() {} + +func (x *StatPathRequest) ProtoReflect() protoreflect.Message { + mi := &file_volume_proto_msgTypes[16] + 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 StatPathRequest.ProtoReflect.Descriptor instead. +func (*StatPathRequest) Descriptor() ([]byte, []int) { + return file_volume_proto_rawDescGZIP(), []int{16} +} + +func (x *StatPathRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +type StatPathResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` + PathInfo *PathInfo `protobuf:"bytes,3,opt,name=path_info,json=pathInfo,proto3" json:"path_info,omitempty"` +} + +func (x *StatPathResponse) Reset() { + *x = StatPathResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_volume_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatPathResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatPathResponse) ProtoMessage() {} + +func (x *StatPathResponse) ProtoReflect() protoreflect.Message { + mi := &file_volume_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 StatPathResponse.ProtoReflect.Descriptor instead. +func (*StatPathResponse) Descriptor() ([]byte, []int) { + return file_volume_proto_rawDescGZIP(), []int{17} +} + +func (x *StatPathResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *StatPathResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + +func (x *StatPathResponse) GetPathInfo() *PathInfo { + if x != nil { + return x.PathInfo + } + return nil +} + type PresignedURLParams struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1022,7 +1132,7 @@ type PresignedURLParams struct { func (x *PresignedURLParams) Reset() { *x = PresignedURLParams{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[16] + mi := &file_volume_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1035,7 +1145,7 @@ func (x *PresignedURLParams) String() string { func (*PresignedURLParams) ProtoMessage() {} func (x *PresignedURLParams) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[16] + mi := &file_volume_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1048,7 +1158,7 @@ func (x *PresignedURLParams) ProtoReflect() protoreflect.Message { // Deprecated: Use PresignedURLParams.ProtoReflect.Descriptor instead. func (*PresignedURLParams) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{16} + return file_volume_proto_rawDescGZIP(), []int{18} } func (x *PresignedURLParams) GetUploadId() string { @@ -1094,7 +1204,7 @@ type CreatePresignedURLRequest struct { func (x *CreatePresignedURLRequest) Reset() { *x = CreatePresignedURLRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[17] + mi := &file_volume_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1107,7 +1217,7 @@ func (x *CreatePresignedURLRequest) String() string { func (*CreatePresignedURLRequest) ProtoMessage() {} func (x *CreatePresignedURLRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[17] + mi := &file_volume_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1120,7 +1230,7 @@ func (x *CreatePresignedURLRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePresignedURLRequest.ProtoReflect.Descriptor instead. func (*CreatePresignedURLRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{17} + return file_volume_proto_rawDescGZIP(), []int{19} } func (x *CreatePresignedURLRequest) GetVolumeName() string { @@ -1171,7 +1281,7 @@ type CreatePresignedURLResponse struct { func (x *CreatePresignedURLResponse) Reset() { *x = CreatePresignedURLResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[18] + mi := &file_volume_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1184,7 +1294,7 @@ func (x *CreatePresignedURLResponse) String() string { func (*CreatePresignedURLResponse) ProtoMessage() {} func (x *CreatePresignedURLResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[18] + mi := &file_volume_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1197,7 +1307,7 @@ func (x *CreatePresignedURLResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePresignedURLResponse.ProtoReflect.Descriptor instead. func (*CreatePresignedURLResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{18} + return file_volume_proto_rawDescGZIP(), []int{20} } func (x *CreatePresignedURLResponse) GetOk() bool { @@ -1235,7 +1345,7 @@ type CreateMultipartUploadRequest struct { func (x *CreateMultipartUploadRequest) Reset() { *x = CreateMultipartUploadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[19] + mi := &file_volume_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1248,7 +1358,7 @@ func (x *CreateMultipartUploadRequest) String() string { func (*CreateMultipartUploadRequest) ProtoMessage() {} func (x *CreateMultipartUploadRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[19] + mi := &file_volume_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1261,7 +1371,7 @@ func (x *CreateMultipartUploadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateMultipartUploadRequest.ProtoReflect.Descriptor instead. func (*CreateMultipartUploadRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{19} + return file_volume_proto_rawDescGZIP(), []int{21} } func (x *CreateMultipartUploadRequest) GetVolumeName() string { @@ -1306,7 +1416,7 @@ type FileUploadPart struct { func (x *FileUploadPart) Reset() { *x = FileUploadPart{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[20] + mi := &file_volume_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1319,7 +1429,7 @@ func (x *FileUploadPart) String() string { func (*FileUploadPart) ProtoMessage() {} func (x *FileUploadPart) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[20] + mi := &file_volume_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1332,7 +1442,7 @@ func (x *FileUploadPart) ProtoReflect() protoreflect.Message { // Deprecated: Use FileUploadPart.ProtoReflect.Descriptor instead. func (*FileUploadPart) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{20} + return file_volume_proto_rawDescGZIP(), []int{22} } func (x *FileUploadPart) GetNumber() uint32 { @@ -1377,7 +1487,7 @@ type CreateMultipartUploadResponse struct { func (x *CreateMultipartUploadResponse) Reset() { *x = CreateMultipartUploadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[21] + mi := &file_volume_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1390,7 +1500,7 @@ func (x *CreateMultipartUploadResponse) String() string { func (*CreateMultipartUploadResponse) ProtoMessage() {} func (x *CreateMultipartUploadResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[21] + mi := &file_volume_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1403,7 +1513,7 @@ func (x *CreateMultipartUploadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateMultipartUploadResponse.ProtoReflect.Descriptor instead. func (*CreateMultipartUploadResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{21} + return file_volume_proto_rawDescGZIP(), []int{23} } func (x *CreateMultipartUploadResponse) GetOk() bool { @@ -1446,7 +1556,7 @@ type CompletedPart struct { func (x *CompletedPart) Reset() { *x = CompletedPart{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[22] + mi := &file_volume_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1459,7 +1569,7 @@ func (x *CompletedPart) String() string { func (*CompletedPart) ProtoMessage() {} func (x *CompletedPart) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[22] + mi := &file_volume_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1472,7 +1582,7 @@ func (x *CompletedPart) ProtoReflect() protoreflect.Message { // Deprecated: Use CompletedPart.ProtoReflect.Descriptor instead. func (*CompletedPart) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{22} + return file_volume_proto_rawDescGZIP(), []int{24} } func (x *CompletedPart) GetNumber() uint32 { @@ -1503,7 +1613,7 @@ type CompleteMultipartUploadRequest struct { func (x *CompleteMultipartUploadRequest) Reset() { *x = CompleteMultipartUploadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[23] + mi := &file_volume_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1516,7 +1626,7 @@ func (x *CompleteMultipartUploadRequest) String() string { func (*CompleteMultipartUploadRequest) ProtoMessage() {} func (x *CompleteMultipartUploadRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[23] + mi := &file_volume_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1529,7 +1639,7 @@ func (x *CompleteMultipartUploadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteMultipartUploadRequest.ProtoReflect.Descriptor instead. func (*CompleteMultipartUploadRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{23} + return file_volume_proto_rawDescGZIP(), []int{25} } func (x *CompleteMultipartUploadRequest) GetUploadId() string { @@ -1572,7 +1682,7 @@ type CompleteMultipartUploadResponse struct { func (x *CompleteMultipartUploadResponse) Reset() { *x = CompleteMultipartUploadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[24] + mi := &file_volume_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1585,7 +1695,7 @@ func (x *CompleteMultipartUploadResponse) String() string { func (*CompleteMultipartUploadResponse) ProtoMessage() {} func (x *CompleteMultipartUploadResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[24] + mi := &file_volume_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1598,7 +1708,7 @@ func (x *CompleteMultipartUploadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteMultipartUploadResponse.ProtoReflect.Descriptor instead. func (*CompleteMultipartUploadResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{24} + return file_volume_proto_rawDescGZIP(), []int{26} } func (x *CompleteMultipartUploadResponse) GetOk() bool { @@ -1628,7 +1738,7 @@ type AbortMultipartUploadRequest struct { func (x *AbortMultipartUploadRequest) Reset() { *x = AbortMultipartUploadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[25] + mi := &file_volume_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1641,7 +1751,7 @@ func (x *AbortMultipartUploadRequest) String() string { func (*AbortMultipartUploadRequest) ProtoMessage() {} func (x *AbortMultipartUploadRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[25] + mi := &file_volume_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1654,7 +1764,7 @@ func (x *AbortMultipartUploadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AbortMultipartUploadRequest.ProtoReflect.Descriptor instead. func (*AbortMultipartUploadRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{25} + return file_volume_proto_rawDescGZIP(), []int{27} } func (x *AbortMultipartUploadRequest) GetUploadId() string { @@ -1690,7 +1800,7 @@ type AbortMultipartUploadResponse struct { func (x *AbortMultipartUploadResponse) Reset() { *x = AbortMultipartUploadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[26] + mi := &file_volume_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1703,7 +1813,7 @@ func (x *AbortMultipartUploadResponse) String() string { func (*AbortMultipartUploadResponse) ProtoMessage() {} func (x *AbortMultipartUploadResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[26] + mi := &file_volume_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1716,7 +1826,7 @@ func (x *AbortMultipartUploadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AbortMultipartUploadResponse.ProtoReflect.Descriptor instead. func (*AbortMultipartUploadResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{26} + return file_volume_proto_rawDescGZIP(), []int{28} } func (x *AbortMultipartUploadResponse) GetOk() bool { @@ -1827,164 +1937,177 @@ var file_volume_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x74, 0x68, 0x22, 0x9c, 0x01, 0x0a, - 0x12, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x19, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, - 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x78, - 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x50, - 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x32, 0x0a, 0x06, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, 0x75, - 0x6d, 0x65, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x57, 0x0a, - 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, - 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, - 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, - 0x72, 0x4d, 0x73, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x9c, 0x01, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, - 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x75, - 0x6e, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, - 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x66, 0x69, 0x6c, - 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x62, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xa9, 0x01, 0x0a, 0x1d, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, - 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, - 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, - 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, - 0x64, 0x12, 0x42, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x5f, 0x70, 0x61, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x50, 0x61, 0x72, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x50, 0x61, 0x72, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x74, - 0x61, 0x67, 0x22, 0xbf, 0x01, 0x0a, 0x1e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, - 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x3e, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x50, 0x61, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x50, - 0x61, 0x72, 0x74, 0x73, 0x22, 0x4a, 0x0a, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x74, 0x68, 0x22, 0x25, 0x0a, 0x0f, + 0x53, 0x74, 0x61, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x22, 0x6a, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, - 0x22, 0x7c, 0x0a, 0x1b, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, - 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x12, 0x2d, 0x0a, 0x09, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x50, 0x61, 0x74, + 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0x9c, 0x01, 0x0a, 0x12, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdf, + 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x47, - 0x0a, 0x1c, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, + 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x32, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, + 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x22, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, + 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x9c, 0x01, 0x0a, 0x1c, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, + 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x62, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xa9, 0x01, 0x0a, + 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x2a, 0x52, 0x0a, 0x12, 0x50, 0x72, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0d, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, - 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x48, - 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x10, 0x03, 0x32, 0xae, 0x07, 0x0a, 0x0d, - 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5a, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, - 0x6d, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4f, - 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x47, 0x65, - 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0c, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x1b, 0x2e, 0x76, 0x6f, 0x6c, 0x75, + 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x75, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x65, 0x74, 0x61, 0x67, 0x22, 0xbf, 0x01, 0x0a, 0x1e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, + 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3e, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x73, 0x22, 0x4a, 0x0a, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, + 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, + 0x4d, 0x73, 0x67, 0x22, 0x7c, 0x0a, 0x1b, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x12, + 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x22, 0x47, 0x0a, 0x1c, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, + 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x2a, 0x52, 0x0a, 0x12, 0x50, 0x72, + 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x12, 0x0d, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x00, 0x12, + 0x0d, 0x0a, 0x09, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x12, 0x0e, + 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x02, 0x12, 0x0e, + 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x61, 0x72, 0x74, 0x10, 0x03, 0x32, 0xef, + 0x07, 0x0a, 0x0d, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x5a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x47, + 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0c, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x1b, 0x2e, 0x76, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x3f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x17, 0x2e, 0x76, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x19, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0e, 0x43, 0x6f, 0x70, 0x79, - 0x50, 0x61, 0x74, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x17, 0x2e, 0x76, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x70, - 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, - 0x01, 0x12, 0x3f, 0x0a, 0x08, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x17, 0x2e, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x17, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x19, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, + 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0e, 0x43, + 0x6f, 0x70, 0x79, 0x50, 0x61, 0x74, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x17, 0x2e, + 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, - 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x12, 0x21, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, - 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x6f, - 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x66, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x24, 0x2e, 0x76, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, - 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x25, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x17, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, - 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x14, 0x41, 0x62, 0x6f, 0x72, 0x74, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x23, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, + 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x28, 0x01, 0x12, 0x3f, 0x0a, 0x08, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x17, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, + 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x74, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x17, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6f, 0x6c, + 0x75, 0x6d, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x12, 0x21, 0x2e, 0x76, + 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x24, + 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x41, 0x62, - 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x23, 0x5a, 0x21, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x65, 0x61, 0x6d, 0x2d, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, 0x74, 0x61, 0x39, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, + 0x17, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, + 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x27, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x14, 0x41, + 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x12, 0x23, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x41, 0x62, 0x6f, + 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x65, 0x61, 0x6d, 0x2d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, 0x74, 0x61, 0x39, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2000,7 +2123,7 @@ func file_volume_proto_rawDescGZIP() []byte { } var file_volume_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_volume_proto_msgTypes = make([]protoimpl.MessageInfo, 27) +var file_volume_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_volume_proto_goTypes = []interface{}{ (PresignedURLMethod)(0), // 0: volume.PresignedURLMethod (*VolumeInstance)(nil), // 1: volume.VolumeInstance @@ -2019,57 +2142,62 @@ var file_volume_proto_goTypes = []interface{}{ (*ListVolumesResponse)(nil), // 14: volume.ListVolumesResponse (*MovePathRequest)(nil), // 15: volume.MovePathRequest (*MovePathResponse)(nil), // 16: volume.MovePathResponse - (*PresignedURLParams)(nil), // 17: volume.PresignedURLParams - (*CreatePresignedURLRequest)(nil), // 18: volume.CreatePresignedURLRequest - (*CreatePresignedURLResponse)(nil), // 19: volume.CreatePresignedURLResponse - (*CreateMultipartUploadRequest)(nil), // 20: volume.CreateMultipartUploadRequest - (*FileUploadPart)(nil), // 21: volume.FileUploadPart - (*CreateMultipartUploadResponse)(nil), // 22: volume.CreateMultipartUploadResponse - (*CompletedPart)(nil), // 23: volume.CompletedPart - (*CompleteMultipartUploadRequest)(nil), // 24: volume.CompleteMultipartUploadRequest - (*CompleteMultipartUploadResponse)(nil), // 25: volume.CompleteMultipartUploadResponse - (*AbortMultipartUploadRequest)(nil), // 26: volume.AbortMultipartUploadRequest - (*AbortMultipartUploadResponse)(nil), // 27: volume.AbortMultipartUploadResponse - (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (*StatPathRequest)(nil), // 17: volume.StatPathRequest + (*StatPathResponse)(nil), // 18: volume.StatPathResponse + (*PresignedURLParams)(nil), // 19: volume.PresignedURLParams + (*CreatePresignedURLRequest)(nil), // 20: volume.CreatePresignedURLRequest + (*CreatePresignedURLResponse)(nil), // 21: volume.CreatePresignedURLResponse + (*CreateMultipartUploadRequest)(nil), // 22: volume.CreateMultipartUploadRequest + (*FileUploadPart)(nil), // 23: volume.FileUploadPart + (*CreateMultipartUploadResponse)(nil), // 24: volume.CreateMultipartUploadResponse + (*CompletedPart)(nil), // 25: volume.CompletedPart + (*CompleteMultipartUploadRequest)(nil), // 26: volume.CompleteMultipartUploadRequest + (*CompleteMultipartUploadResponse)(nil), // 27: volume.CompleteMultipartUploadResponse + (*AbortMultipartUploadRequest)(nil), // 28: volume.AbortMultipartUploadRequest + (*AbortMultipartUploadResponse)(nil), // 29: volume.AbortMultipartUploadResponse + (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp } var file_volume_proto_depIdxs = []int32{ - 28, // 0: volume.VolumeInstance.created_at:type_name -> google.protobuf.Timestamp - 28, // 1: volume.VolumeInstance.updated_at:type_name -> google.protobuf.Timestamp + 30, // 0: volume.VolumeInstance.created_at:type_name -> google.protobuf.Timestamp + 30, // 1: volume.VolumeInstance.updated_at:type_name -> google.protobuf.Timestamp 1, // 2: volume.GetOrCreateVolumeResponse.volume:type_name -> volume.VolumeInstance - 28, // 3: volume.PathInfo.mod_time:type_name -> google.protobuf.Timestamp + 30, // 3: volume.PathInfo.mod_time:type_name -> google.protobuf.Timestamp 6, // 4: volume.ListPathResponse.path_infos:type_name -> volume.PathInfo 1, // 5: volume.ListVolumesResponse.volumes:type_name -> volume.VolumeInstance - 0, // 6: volume.CreatePresignedURLRequest.method:type_name -> volume.PresignedURLMethod - 17, // 7: volume.CreatePresignedURLRequest.params:type_name -> volume.PresignedURLParams - 21, // 8: volume.CreateMultipartUploadResponse.file_upload_parts:type_name -> volume.FileUploadPart - 23, // 9: volume.CompleteMultipartUploadRequest.completed_parts:type_name -> volume.CompletedPart - 2, // 10: volume.VolumeService.GetOrCreateVolume:input_type -> volume.GetOrCreateVolumeRequest - 4, // 11: volume.VolumeService.DeleteVolume:input_type -> volume.DeleteVolumeRequest - 13, // 12: volume.VolumeService.ListVolumes:input_type -> volume.ListVolumesRequest - 7, // 13: volume.VolumeService.ListPath:input_type -> volume.ListPathRequest - 9, // 14: volume.VolumeService.DeletePath:input_type -> volume.DeletePathRequest - 11, // 15: volume.VolumeService.CopyPathStream:input_type -> volume.CopyPathRequest - 15, // 16: volume.VolumeService.MovePath:input_type -> volume.MovePathRequest - 18, // 17: volume.VolumeService.CreatePresignedURL:input_type -> volume.CreatePresignedURLRequest - 20, // 18: volume.VolumeService.CreateMultipartUpload:input_type -> volume.CreateMultipartUploadRequest - 24, // 19: volume.VolumeService.CompleteMultipartUpload:input_type -> volume.CompleteMultipartUploadRequest - 26, // 20: volume.VolumeService.AbortMultipartUpload:input_type -> volume.AbortMultipartUploadRequest - 3, // 21: volume.VolumeService.GetOrCreateVolume:output_type -> volume.GetOrCreateVolumeResponse - 5, // 22: volume.VolumeService.DeleteVolume:output_type -> volume.DeleteVolumeResponse - 14, // 23: volume.VolumeService.ListVolumes:output_type -> volume.ListVolumesResponse - 8, // 24: volume.VolumeService.ListPath:output_type -> volume.ListPathResponse - 10, // 25: volume.VolumeService.DeletePath:output_type -> volume.DeletePathResponse - 12, // 26: volume.VolumeService.CopyPathStream:output_type -> volume.CopyPathResponse - 16, // 27: volume.VolumeService.MovePath:output_type -> volume.MovePathResponse - 19, // 28: volume.VolumeService.CreatePresignedURL:output_type -> volume.CreatePresignedURLResponse - 22, // 29: volume.VolumeService.CreateMultipartUpload:output_type -> volume.CreateMultipartUploadResponse - 25, // 30: volume.VolumeService.CompleteMultipartUpload:output_type -> volume.CompleteMultipartUploadResponse - 27, // 31: volume.VolumeService.AbortMultipartUpload:output_type -> volume.AbortMultipartUploadResponse - 21, // [21:32] is the sub-list for method output_type - 10, // [10:21] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 6, // 6: volume.StatPathResponse.path_info:type_name -> volume.PathInfo + 0, // 7: volume.CreatePresignedURLRequest.method:type_name -> volume.PresignedURLMethod + 19, // 8: volume.CreatePresignedURLRequest.params:type_name -> volume.PresignedURLParams + 23, // 9: volume.CreateMultipartUploadResponse.file_upload_parts:type_name -> volume.FileUploadPart + 25, // 10: volume.CompleteMultipartUploadRequest.completed_parts:type_name -> volume.CompletedPart + 2, // 11: volume.VolumeService.GetOrCreateVolume:input_type -> volume.GetOrCreateVolumeRequest + 4, // 12: volume.VolumeService.DeleteVolume:input_type -> volume.DeleteVolumeRequest + 13, // 13: volume.VolumeService.ListVolumes:input_type -> volume.ListVolumesRequest + 7, // 14: volume.VolumeService.ListPath:input_type -> volume.ListPathRequest + 9, // 15: volume.VolumeService.DeletePath:input_type -> volume.DeletePathRequest + 11, // 16: volume.VolumeService.CopyPathStream:input_type -> volume.CopyPathRequest + 15, // 17: volume.VolumeService.MovePath:input_type -> volume.MovePathRequest + 17, // 18: volume.VolumeService.StatPath:input_type -> volume.StatPathRequest + 20, // 19: volume.VolumeService.CreatePresignedURL:input_type -> volume.CreatePresignedURLRequest + 22, // 20: volume.VolumeService.CreateMultipartUpload:input_type -> volume.CreateMultipartUploadRequest + 26, // 21: volume.VolumeService.CompleteMultipartUpload:input_type -> volume.CompleteMultipartUploadRequest + 28, // 22: volume.VolumeService.AbortMultipartUpload:input_type -> volume.AbortMultipartUploadRequest + 3, // 23: volume.VolumeService.GetOrCreateVolume:output_type -> volume.GetOrCreateVolumeResponse + 5, // 24: volume.VolumeService.DeleteVolume:output_type -> volume.DeleteVolumeResponse + 14, // 25: volume.VolumeService.ListVolumes:output_type -> volume.ListVolumesResponse + 8, // 26: volume.VolumeService.ListPath:output_type -> volume.ListPathResponse + 10, // 27: volume.VolumeService.DeletePath:output_type -> volume.DeletePathResponse + 12, // 28: volume.VolumeService.CopyPathStream:output_type -> volume.CopyPathResponse + 16, // 29: volume.VolumeService.MovePath:output_type -> volume.MovePathResponse + 18, // 30: volume.VolumeService.StatPath:output_type -> volume.StatPathResponse + 21, // 31: volume.VolumeService.CreatePresignedURL:output_type -> volume.CreatePresignedURLResponse + 24, // 32: volume.VolumeService.CreateMultipartUpload:output_type -> volume.CreateMultipartUploadResponse + 27, // 33: volume.VolumeService.CompleteMultipartUpload:output_type -> volume.CompleteMultipartUploadResponse + 29, // 34: volume.VolumeService.AbortMultipartUpload:output_type -> volume.AbortMultipartUploadResponse + 23, // [23:35] is the sub-list for method output_type + 11, // [11:23] 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 } func init() { file_volume_proto_init() } @@ -2271,7 +2399,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PresignedURLParams); i { + switch v := v.(*StatPathRequest); i { case 0: return &v.state case 1: @@ -2283,7 +2411,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePresignedURLRequest); i { + switch v := v.(*StatPathResponse); i { case 0: return &v.state case 1: @@ -2295,7 +2423,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePresignedURLResponse); i { + switch v := v.(*PresignedURLParams); i { case 0: return &v.state case 1: @@ -2307,7 +2435,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMultipartUploadRequest); i { + switch v := v.(*CreatePresignedURLRequest); i { case 0: return &v.state case 1: @@ -2319,7 +2447,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FileUploadPart); i { + switch v := v.(*CreatePresignedURLResponse); i { case 0: return &v.state case 1: @@ -2331,7 +2459,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMultipartUploadResponse); i { + switch v := v.(*CreateMultipartUploadRequest); i { case 0: return &v.state case 1: @@ -2343,7 +2471,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompletedPart); i { + switch v := v.(*FileUploadPart); i { case 0: return &v.state case 1: @@ -2355,7 +2483,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompleteMultipartUploadRequest); i { + switch v := v.(*CreateMultipartUploadResponse); i { case 0: return &v.state case 1: @@ -2367,7 +2495,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompleteMultipartUploadResponse); i { + switch v := v.(*CompletedPart); i { case 0: return &v.state case 1: @@ -2379,7 +2507,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AbortMultipartUploadRequest); i { + switch v := v.(*CompleteMultipartUploadRequest); i { case 0: return &v.state case 1: @@ -2391,6 +2519,30 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CompleteMultipartUploadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_volume_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AbortMultipartUploadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_volume_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AbortMultipartUploadResponse); i { case 0: return &v.state @@ -2409,7 +2561,7 @@ func file_volume_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_volume_proto_rawDesc, NumEnums: 1, - NumMessages: 27, + NumMessages: 29, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/volume_grpc.pb.go b/proto/volume_grpc.pb.go index 91ad02743..a7073e02a 100644 --- a/proto/volume_grpc.pb.go +++ b/proto/volume_grpc.pb.go @@ -26,6 +26,7 @@ const ( VolumeService_DeletePath_FullMethodName = "/volume.VolumeService/DeletePath" VolumeService_CopyPathStream_FullMethodName = "/volume.VolumeService/CopyPathStream" VolumeService_MovePath_FullMethodName = "/volume.VolumeService/MovePath" + VolumeService_StatPath_FullMethodName = "/volume.VolumeService/StatPath" VolumeService_CreatePresignedURL_FullMethodName = "/volume.VolumeService/CreatePresignedURL" VolumeService_CreateMultipartUpload_FullMethodName = "/volume.VolumeService/CreateMultipartUpload" VolumeService_CompleteMultipartUpload_FullMethodName = "/volume.VolumeService/CompleteMultipartUpload" @@ -43,6 +44,7 @@ type VolumeServiceClient interface { DeletePath(ctx context.Context, in *DeletePathRequest, opts ...grpc.CallOption) (*DeletePathResponse, error) CopyPathStream(ctx context.Context, opts ...grpc.CallOption) (VolumeService_CopyPathStreamClient, error) MovePath(ctx context.Context, in *MovePathRequest, opts ...grpc.CallOption) (*MovePathResponse, error) + StatPath(ctx context.Context, in *StatPathRequest, opts ...grpc.CallOption) (*StatPathResponse, error) // Multipart Upload CreatePresignedURL(ctx context.Context, in *CreatePresignedURLRequest, opts ...grpc.CallOption) (*CreatePresignedURLResponse, error) CreateMultipartUpload(ctx context.Context, in *CreateMultipartUploadRequest, opts ...grpc.CallOption) (*CreateMultipartUploadResponse, error) @@ -146,6 +148,15 @@ func (c *volumeServiceClient) MovePath(ctx context.Context, in *MovePathRequest, return out, nil } +func (c *volumeServiceClient) StatPath(ctx context.Context, in *StatPathRequest, opts ...grpc.CallOption) (*StatPathResponse, error) { + out := new(StatPathResponse) + err := c.cc.Invoke(ctx, VolumeService_StatPath_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *volumeServiceClient) CreatePresignedURL(ctx context.Context, in *CreatePresignedURLRequest, opts ...grpc.CallOption) (*CreatePresignedURLResponse, error) { out := new(CreatePresignedURLResponse) err := c.cc.Invoke(ctx, VolumeService_CreatePresignedURL_FullMethodName, in, out, opts...) @@ -193,6 +204,7 @@ type VolumeServiceServer interface { DeletePath(context.Context, *DeletePathRequest) (*DeletePathResponse, error) CopyPathStream(VolumeService_CopyPathStreamServer) error MovePath(context.Context, *MovePathRequest) (*MovePathResponse, error) + StatPath(context.Context, *StatPathRequest) (*StatPathResponse, error) // Multipart Upload CreatePresignedURL(context.Context, *CreatePresignedURLRequest) (*CreatePresignedURLResponse, error) CreateMultipartUpload(context.Context, *CreateMultipartUploadRequest) (*CreateMultipartUploadResponse, error) @@ -226,6 +238,9 @@ func (UnimplementedVolumeServiceServer) CopyPathStream(VolumeService_CopyPathStr func (UnimplementedVolumeServiceServer) MovePath(context.Context, *MovePathRequest) (*MovePathResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MovePath not implemented") } +func (UnimplementedVolumeServiceServer) StatPath(context.Context, *StatPathRequest) (*StatPathResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StatPath not implemented") +} func (UnimplementedVolumeServiceServer) CreatePresignedURL(context.Context, *CreatePresignedURLRequest) (*CreatePresignedURLResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreatePresignedURL not implemented") } @@ -385,6 +400,24 @@ func _VolumeService_MovePath_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _VolumeService_StatPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatPathRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VolumeServiceServer).StatPath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VolumeService_StatPath_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VolumeServiceServer).StatPath(ctx, req.(*StatPathRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _VolumeService_CreatePresignedURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreatePresignedURLRequest) if err := dec(in); err != nil { @@ -488,6 +521,10 @@ var VolumeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "MovePath", Handler: _VolumeService_MovePath_Handler, }, + { + MethodName: "StatPath", + Handler: _VolumeService_StatPath_Handler, + }, { MethodName: "CreatePresignedURL", Handler: _VolumeService_CreatePresignedURL_Handler, diff --git a/sdk/poetry.lock b/sdk/poetry.lock index 9477f5a37..1ea4512fd 100644 --- a/sdk/poetry.lock +++ b/sdk/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "annotated-types" @@ -1704,4 +1704,4 @@ test = ["websockets"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "1667031eb69e1901059f36bf0ab5c23c9686d9fb3fbcb23681d88f9fe09099c6" +content-hash = "21d26d27372bea2fa37d00c3b086e3ae232fb1f99f69ec4584d164a513a823bc" diff --git a/sdk/pyproject.toml b/sdk/pyproject.toml index 1b634c54f..5ce238123 100644 --- a/sdk/pyproject.toml +++ b/sdk/pyproject.toml @@ -16,7 +16,7 @@ grpclib = "^0.4.7" grpcio = "1.67.0" asgiref = "^3.8.1" cloudpickle = "^3.0.0" -rich = "^13.7.0" +rich = "^13.9.4" click = "^8.1.7" protobuf = "^4.25.1" fastapi = "^0.110.2" diff --git a/sdk/src/beta9/cli/volume.py b/sdk/src/beta9/cli/volume.py index 09d16f224..a90725a35 100644 --- a/sdk/src/beta9/cli/volume.py +++ b/sdk/src/beta9/cli/volume.py @@ -190,22 +190,35 @@ def read_with_progress( Version 2: - This version supports copying files and directories to and from a volume. + Upload and download files or directories between a volume and your system. Examples: - # Upload a file to a volume - {cli_name} cp file.txt {cli_name}://myvol/ - {cli_name} cp file.txt {cli_name}://myvol/file.txt - {cli_name} cp file.txt {cli_name}://myvol/file.new + # Upload a file + {cli_name} cp file.txt {cli_name}://myvol/ # ./file.txt => {cli_name}://myvol/file.txt + {cli_name} cp file.txt {cli_name}://myvol/file.txt # ./file.txt => {cli_name}://myvol/file.txt + {cli_name} cp file.txt {cli_name}://myvol/file.new # ./file.txt => {cli_name}://myvol/file.new + {cli_name} cp file.txt {cli_name}://myvol/hello # ./file.txt => {cli_name}://myvol/hello.txt (keeps the extension) - # Upload a directory to a volume - {cli_name} cp mydir {cli_name}://myvol/ - {cli_name} cp mydir {cli_name}://myvol/mydir - {cli_name} cp mydir {cli_name}://myvol/newdir + # Upload a directory + {cli_name} cp mydir {cli_name}://myvol # ./mydir/file.txt => {cli_name}://myvol/file.txt + {cli_name} cp mydir {cli_name}://myvol/mydir # ./mydir/file.txt => {cli_name}://myvol/mydir/file.txt + {cli_name} cp mydir {cli_name}://myvol/newdir # ./mydir/file.txt => {cli_name}://myvol/newdir/file.txt - # Copy a file from a volume to the local filesystem - {cli_name} cp {cli_name}://myvol/file.txt . + # Upload a directory (with trailing slash) + {cli_name} cp mydir {cli_name}://myvol/ # ./mydir/file.txt => {cli_name}://myvol/mydir/file.txt + {cli_name} cp mydir {cli_name}://myvol/newdir/ # ./mydir/file.txt => {cli_name}://myvol/newdir/mydir/file.txt + {cli_name} cp . {cli_name}://myvol/ # ./file.txt => {cli_name}://myvol/file.txt + + # Download a file + {cli_name} cp {cli_name}://myvol/file.txt . # {cli_name}://myvol/file.txt => ./file.txt + {cli_name} cp {cli_name}://myvol/file.txt file.new # {cli_name}://myvol/file.txt => ./file.new + + # Download a directory + {cli_name} cp {cli_name}://myvol/mydir . # {cli_name}://myvol/mydir/file.txt => ./file.txt + + # Download a directory (with trailing slash) + {cli_name} cp {cli_name}://myvol/mydir/ . # {cli_name}://myvol/mydir/file.txt => ./mydir/file.txt \b """, ) diff --git a/sdk/src/beta9/clients/volume/__init__.py b/sdk/src/beta9/clients/volume/__init__.py index 2e52f9a46..e0c622aa2 100644 --- a/sdk/src/beta9/clients/volume/__init__.py +++ b/sdk/src/beta9/clients/volume/__init__.py @@ -140,6 +140,18 @@ class MovePathResponse(betterproto.Message): new_path: str = betterproto.string_field(3) +@dataclass(eq=False, repr=False) +class StatPathRequest(betterproto.Message): + path: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class StatPathResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + path_info: "PathInfo" = betterproto.message_field(3) + + @dataclass(eq=False, repr=False) class PresignedUrlParams(betterproto.Message): upload_id: str = betterproto.string_field(1) @@ -285,6 +297,13 @@ def move_path(self, move_path_request: "MovePathRequest") -> "MovePathResponse": MovePathResponse, )(move_path_request) + def stat_path(self, stat_path_request: "StatPathRequest") -> "StatPathResponse": + return self._unary_unary( + "/volume.VolumeService/StatPath", + StatPathRequest, + StatPathResponse, + )(stat_path_request) + def create_presigned_url( self, create_presigned_url_request: "CreatePresignedUrlRequest" ) -> "CreatePresignedUrlResponse": diff --git a/sdk/src/beta9/multipart.py b/sdk/src/beta9/multipart.py index 7af5d0c2a..92b600b96 100644 --- a/sdk/src/beta9/multipart.py +++ b/sdk/src/beta9/multipart.py @@ -44,6 +44,7 @@ FileUploadPart, ListPathRequest, PresignedUrlMethod, + StatPathRequest, VolumeServiceStub, ) from .env import try_env @@ -60,10 +61,11 @@ _PROCESS_LOCAL: Final[local] = local() _MAX_WORKERS: Final[int] = try_env("MULTIPART_MAX_WORKERS", 3) -_REQUEST_TIMEOUT: Final[int] = try_env("MULTIPART_REQUEST_TIMEOUT", 3) +_REQUEST_TIMEOUT: Final[float] = try_env("MULTIPART_REQUEST_TIMEOUT", 0.5) -UPLOAD_CHUNK_SIZE: Final[int] = try_env("MULTIPART_UPLOAD_CHUNK_SIZE", 4 * 1024 * 1024) -DOWNLOAD_CHUNK_SIZE: Final[int] = try_env("MULTIPART_DOWNLOAD_CHUNK_SIZE", 32 * 1024 * 1024) +# Value of 0 means the chunk size is calculated based on the file size +UPLOAD_CHUNK_SIZE: Final[int] = try_env("MULTIPART_UPLOAD_CHUNK_SIZE", 0) +DOWNLOAD_CHUNK_SIZE: Final[int] = try_env("MULTIPART_DOWNLOAD_CHUNK_SIZE", 0) class ProgressCallbackType(Protocol): @@ -195,14 +197,12 @@ def _upload_part(file_path: Path, file_part: FileUploadPart, queue: Queue) -> Co Information about the completed part. """ session = _get_session() - chunk = _get_file_chunk(file_path, file_part.start, file_part.end) - chunk_size = len(chunk) class QueueBuffer(io.BytesIO): def read(self, size: Optional[int] = -1) -> bytes: b = super().read(size) - queue.put(len(b), block=False) + queue.put_nowait(len(b)) return b try: @@ -210,8 +210,9 @@ def read(self, size: Optional[int] = -1) -> bytes: url=file_part.url, data=QueueBuffer(chunk), headers={ - "Content-Length": str(chunk_size), + "Content-Length": str(len(chunk)), }, + timeout=_REQUEST_TIMEOUT, ) response.raise_for_status() etag = response.headers["ETag"].replace('"', "") @@ -246,7 +247,7 @@ def beta9_upload( bytes processed. Defaults to None. completion_callback: A context manager that wraps the completion of the upload. Defaults to None. - chunk_size: Size of each chunk in bytes. Defaults to 4 MiB. + chunk_size: Size of each chunk in bytes. Raises: CreateMultipartUploadError: If initializing the upload fails. @@ -256,6 +257,7 @@ def beta9_upload( """ # Initialize multipart upload file_size = file_path.stat().st_size + chunk_size = chunk_size or _calculate_chunk_size(file_size) initial = retry(times=3, delay=1.0)(service.create_multipart_upload)( CreateMultipartUploadRequest( volume_name=remote_path.volume_name, @@ -271,7 +273,9 @@ def beta9_upload( try: with ExitStack() as stack: manager = stack.enter_context(Manager()) - executor = stack.enter_context(ProcessPoolExecutor(_MAX_WORKERS, initializer=_init)) + + max_workers = min(_MAX_WORKERS, len(initial.file_upload_parts)) + executor = stack.enter_context(ProcessPoolExecutor(max_workers, initializer=_init)) queue = manager.Queue() stack.enter_context(_progress_updater(file_size, queue, progress_callback)) @@ -358,6 +362,34 @@ def _calculate_file_ranges(file_size: int, chunk_size: int) -> List[FileRange]: ] +def clamp(value: int, min_value: int, max_value: int) -> int: + """ + Clamp the value between min_value and max_value. + """ + return max(min_value, min(value, max_value)) + + +def _calculate_chunk_size( + file_size: int, + optimal_chunk_size: int = 2 * 1024 * 1024, # 2 MB + min_chunks: int = 1, + max_chunks: int = 200, +) -> int: + """ + Calculates an optimal chunk size based on the file size. + """ + # Calculate desired number of chunks based on optimal chunk size + desired_chunks = math.ceil(file_size / optimal_chunk_size) + + # Clamp the desired_chunks within min_chunks and max_chunks + desired_chunks = clamp(desired_chunks, min_chunks, max_chunks) + + # Calculate the chunk size based on the clamped desired_chunks + chunk_size = math.ceil(file_size / desired_chunks) + + return chunk_size + + @retry(times=10) def _download_chunk( url: str, @@ -390,7 +422,7 @@ def _download_chunk( path = output_dir / f"data_{file_range.number}" with open(path, "wb") as file: for chunk in response.iter_content(chunk_size=1024 * 1024): - queue.put(file.write(chunk), block=False) + queue.put_nowait(file.write(chunk)) except Exception as e: raise DownloadChunkError(file_range.number, file_range.start, file_range.end, str(e)) @@ -423,7 +455,7 @@ def beta9_download( remote_path: Path to the file on the volume. file_path: Path to save the file. callback: A callback that receives the total size and the number of bytes processed. Defaults to None. - chunk_size: Size of each chunk in bytes. Defaults to 32 MiB. + chunk_size: Size of each chunk in bytes. Raises: CreatePresignedUrlError: If a presigned URL cannot be created. @@ -443,6 +475,7 @@ def beta9_download( raise CreatePresignedUrlError(presigned.err_msg) file_size = _get_file_size(presigned.url) + chunk_size = chunk_size or _calculate_chunk_size(file_size) file_ranges = _calculate_file_ranges(file_size, chunk_size) # Download and merge file ranges @@ -460,7 +493,9 @@ def beta9_download( with ExitStack() as stack: manager = stack.enter_context(Manager()) temp_dir = stack.enter_context(tempfile.TemporaryDirectory()) - executor = stack.enter_context(ProcessPoolExecutor(_MAX_WORKERS, initializer=_init)) + + max_workers = min(_MAX_WORKERS, len(file_ranges)) + executor = stack.enter_context(ProcessPoolExecutor(max_workers, initializer=_init)) queue = manager.Queue() stack.enter_context(_progress_updater(file_size, queue, callback)) @@ -476,10 +511,6 @@ def beta9_download( class RemotePath: - scheme: str - volume_name: str - is_dir: Optional[bool] = None - def __init__( self, scheme: str, volume_name: str, volume_path: str, is_dir: Optional[bool] = None ): @@ -531,6 +562,8 @@ def name(self) -> str: @property def path(self) -> str: + if self.volume_path == "": + return self.volume_name + "/" return os.path.join(self.volume_name, self.volume_path) @@ -596,18 +629,18 @@ def is_dir(self, remote_path: RemotePath) -> bool: if remote_path.volume_path == "": return True - res = self.service.list_path(ListPathRequest(path=remote_path.path)) + res = self.service.stat_path(StatPathRequest(path=remote_path.path)) if not res.ok: raise RuntimeError(f"{remote_path} ({res.err_msg})") - return any(p for p in res.path_infos if p.is_dir and p.path == remote_path.volume_path) + return res.path_info.is_dir if not res.err_msg else False def upload(self, local_path: Path, remote_path: RemotePath) -> None: # Recursively upload directories if local_path.is_dir(): for item in local_path.iterdir(): if remote_path.volume_path.endswith("/"): - volume_path = f"{remote_path.volume_path}/{local_path.name}/{item.name}" + volume_path = f"{remote_path.volume_path}{local_path.name}/{item.name}" else: volume_path = f"{remote_path.volume_path}/{item.name}" @@ -621,22 +654,15 @@ def upload(self, local_path: Path, remote_path: RemotePath) -> None: else: # Adjust remote_path for single-file upload if remote_path.volume_path.endswith("/"): - volume_path = remote_path.volume_path.rstrip("/") - volume_path = f"{volume_path}/{local_path.name}" - - remote_path = RemotePath( - scheme=remote_path.scheme, - volume_name=remote_path.volume_name, - volume_path=volume_path, - ) + volume_path = f"{remote_path.volume_path}{local_path.name}".lstrip("/") + remote_path.volume_path = volume_path elif self.is_dir(remote_path): volume_path = f"{remote_path.volume_path}/{local_path.name}".lstrip("/") - - remote_path = RemotePath( - scheme=remote_path.scheme, - volume_name=remote_path.volume_name, - volume_path=volume_path, - ) + remote_path.volume_path = volume_path + elif local_path.suffix and "." not in remote_path.volume_path: + ext = ".".join(local_path.suffixes) + volume_path = f"{remote_path.volume_path}{ext}".lstrip("/") + remote_path.volume_path = volume_path progress_callback, completion_callback = self._setup_callbacks(remote_path) beta9_upload( @@ -651,9 +677,13 @@ def download(self, remote_path: RemotePath, local_path: Path) -> None: # Recursively download directories if self.is_dir(remote_path): local_path.mkdir(parents=True, exist_ok=True) - for item in self.list_dir(remote_path): - rel_path = Path(item.volume_path).relative_to(remote_path.volume_path) - self.download(item, local_path / rel_path) + + for rpath in self.list_dir(remote_path): + lpath = local_path / rpath.volume_path + if not remote_path.volume_path.endswith("/"): + lpath = local_path / rpath.name + + self.download(rpath, lpath) else: # Adjust local_path for single-file download if local_path.is_dir():