diff --git a/internal/abstractions/volume/volume.go b/internal/abstractions/volume/volume.go index 1a751e3d8..2c47d51c1 100644 --- a/internal/abstractions/volume/volume.go +++ b/internal/abstractions/volume/volume.go @@ -13,6 +13,7 @@ import ( "github.com/beam-cloud/beta9/internal/repository" "github.com/beam-cloud/beta9/internal/types" pb "github.com/beam-cloud/beta9/proto" + "google.golang.org/protobuf/types/known/timestamppb" ) type VolumeService interface { @@ -36,18 +37,55 @@ func NewGlobalVolumeService(backendRepo repository.BackendRepository) (VolumeSer func (vs *GlobalVolumeService) GetOrCreateVolume(ctx context.Context, in *pb.GetOrCreateVolumeRequest) (*pb.GetOrCreateVolumeResponse, error) { authInfo, _ := auth.AuthInfoFromContext(ctx) - workspaceId := authInfo.Workspace.Id - volume, err := vs.backendRepo.GetOrCreateVolume(ctx, workspaceId, in.Name) + volume, err := vs.getOrCreateVolume(ctx, authInfo.Workspace, in.Name) if err != nil { return &pb.GetOrCreateVolumeResponse{ - Ok: false, + Ok: false, + ErrMsg: "Unable to get or create volume", }, nil } return &pb.GetOrCreateVolumeResponse{ - VolumeId: volume.ExternalId, - Ok: true, + Ok: true, + Volume: &pb.VolumeInstance{ + Id: volume.ExternalId, + Name: volume.Name, + CreatedAt: timestamppb.New(volume.CreatedAt), + UpdatedAt: timestamppb.New(volume.UpdatedAt), + WorkspaceId: authInfo.Workspace.ExternalId, + WorkspaceName: authInfo.Workspace.Name, + }, + }, nil +} + +func (vs *GlobalVolumeService) ListVolumes(ctx context.Context, in *pb.ListVolumesRequest) (*pb.ListVolumesResponse, error) { + authInfo, _ := auth.AuthInfoFromContext(ctx) + + volumes, err := vs.listVolumes(ctx, authInfo.Workspace) + if err != nil { + return &pb.ListVolumesResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + vols := make([]*pb.VolumeInstance, len(volumes)) + for i, v := range volumes { + vols[i] = &pb.VolumeInstance{ + Id: v.ExternalId, + Name: v.Name, + Size: v.Size, + CreatedAt: timestamppb.New(v.CreatedAt), + UpdatedAt: timestamppb.New(v.UpdatedAt), + WorkspaceId: v.Workspace.ExternalId, + WorkspaceName: v.Workspace.Name, + } + } + + return &pb.ListVolumesResponse{ + Ok: true, + Volumes: vols, }, nil } @@ -95,8 +133,8 @@ func (vs *GlobalVolumeService) CopyPathStream(stream pb.VolumeService_CopyPathSt if err := vs.copyPathStream(ctx, ch, authInfo.Workspace); err != nil { return stream.SendAndClose(&pb.CopyPathResponse{ - Ok: false, - ErrorMsg: err.Error(), + Ok: false, + ErrMsg: err.Error(), }) } @@ -122,6 +160,40 @@ func (vs *GlobalVolumeService) DeletePath(ctx context.Context, in *pb.DeletePath // 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) + if err != nil { + return nil, err + } + + volumePath := JoinVolumePath(workspace.Name, volume.ExternalId) + if _, err := os.Stat(volumePath); os.IsNotExist(err) { + os.MkdirAll(volumePath, os.FileMode(0755)) + } + + return volume, nil +} + +func (vs *GlobalVolumeService) listVolumes(ctx context.Context, workspace *types.Workspace) ([]types.VolumeWithRelated, error) { + volumes, err := vs.backendRepo.ListVolumesWithRelated(ctx, workspace.Id) + if err != nil { + return nil, err + } + + for i, v := range volumes { + path := JoinVolumePath(workspace.Name, v.ExternalId) + + size, err := CalculateDirSize(path) + if err != nil { + size = 0 + } + + volumes[i].Size = size + } + + return volumes, nil +} + type CopyPathContent struct { Path string Content []byte @@ -281,3 +353,14 @@ func GetVolumePaths(workspaceName string, volumeExternalId string, volumePath st func JoinVolumePath(workspaceName, volumeExternalId string, subPaths ...string) string { return path.Join(append([]string{types.DefaultVolumesPath, workspaceName, volumeExternalId}, subPaths...)...) } + +func CalculateDirSize(path string) (uint64, error) { + var size uint64 + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if !info.IsDir() { + size += uint64(info.Size()) + } + return err + }) + return size, err +} diff --git a/internal/abstractions/volume/volume.proto b/internal/abstractions/volume/volume.proto index da8b80395..cc50b2b1e 100644 --- a/internal/abstractions/volume/volume.proto +++ b/internal/abstractions/volume/volume.proto @@ -1,23 +1,36 @@ syntax = "proto3"; option go_package = "github.com/beam-cloud/beta9/proto"; +import "google/protobuf/timestamp.proto"; package volume; service VolumeService { rpc GetOrCreateVolume(GetOrCreateVolumeRequest) returns (GetOrCreateVolumeResponse) {} + rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse) {} rpc ListPath(ListPathRequest) returns (ListPathResponse) {} rpc DeletePath(DeletePathRequest) returns (DeletePathResponse) {} rpc CopyPathStream(stream CopyPathRequest) returns (CopyPathResponse) {} } +message VolumeInstance { + string id = 1; + string name = 2; + uint64 size = 3; + google.protobuf.Timestamp created_at = 4; + google.protobuf.Timestamp updated_at = 5; + string workspace_id = 6; + string workspace_name = 7; +} + message GetOrCreateVolumeRequest { string name = 1; } message GetOrCreateVolumeResponse { bool ok = 1; - string volume_id = 2; + string err_msg = 2; + VolumeInstance volume = 3; } message ListPathRequest { @@ -49,5 +62,13 @@ message CopyPathRequest { message CopyPathResponse { bool ok = 1; string object_id = 2; - string error_msg = 3; + string err_msg = 3; +} + +message ListVolumesRequest {} + +message ListVolumesResponse { + bool ok = 1; + string err_msg = 2; + repeated VolumeInstance volumes = 3; } diff --git a/internal/repository/backend_postgres.go b/internal/repository/backend_postgres.go index 22517ddf0..2e9b95576 100644 --- a/internal/repository/backend_postgres.go +++ b/internal/repository/backend_postgres.go @@ -650,10 +650,12 @@ func (r *PostgresBackendRepository) GetStubByExternalId(ctx context.Context, ext return &stub, nil } +// Volume + func (c *PostgresBackendRepository) GetVolume(ctx context.Context, workspaceId uint, name string) (*types.Volume, error) { var volume types.Volume - queryGet := `SELECT id, external_id, name, workspace_id, created_at FROM volume WHERE name = $1 AND workspace_id = $2;` + queryGet := `SELECT id, external_id, name, workspace_id, created_at, updated_at FROM volume WHERE name = $1 AND workspace_id = $2;` if err := c.client.GetContext(ctx, &volume, queryGet, name, workspaceId); err != nil { return nil, err @@ -663,22 +665,37 @@ func (c *PostgresBackendRepository) GetVolume(ctx context.Context, workspaceId u } func (c *PostgresBackendRepository) GetOrCreateVolume(ctx context.Context, workspaceId uint, name string) (*types.Volume, error) { - var volume *types.Volume - var err error - - volume, err = c.GetVolume(ctx, workspaceId, name) + v, err := c.GetVolume(ctx, workspaceId, name) if err == nil { - return volume, nil + return v, nil } - queryCreate := `INSERT INTO volume (name, workspace_id) VALUES ($1, $2) RETURNING id, external_id, name, workspace_id, created_at;` + queryCreate := `INSERT INTO volume (name, workspace_id) VALUES ($1, $2) RETURNING id, external_id, name, workspace_id, created_at, updated_at;` + var volume types.Volume err = c.client.GetContext(ctx, &volume, queryCreate, name, workspaceId) if err != nil { - return &types.Volume{}, err + return nil, err + } + + return &volume, nil +} + +func (c *PostgresBackendRepository) ListVolumesWithRelated(ctx context.Context, workspaceId uint) ([]types.VolumeWithRelated, error) { + var volumes []types.VolumeWithRelated + query := ` + SELECT v.id, v.external_id, v.name, v.workspace_id, v.created_at, v.updated_at, w.name as "workspace.name" + FROM volume v + JOIN workspace w ON v.workspace_id = w.id + WHERE v.workspace_id = $1; + ` + + err := c.client.SelectContext(ctx, &volumes, query, workspaceId) + if err != nil { + return nil, err } - return volume, nil + return volumes, nil } // Deployment diff --git a/internal/repository/base.go b/internal/repository/base.go index c352046ed..24ad0c33b 100644 --- a/internal/repository/base.go +++ b/internal/repository/base.go @@ -70,6 +70,7 @@ type BackendRepository interface { GetStubByExternalId(ctx context.Context, externalId string) (*types.StubWithRelated, error) GetVolume(ctx context.Context, workspaceId uint, name string) (*types.Volume, error) GetOrCreateVolume(ctx context.Context, workspaceId uint, name string) (*types.Volume, error) + ListVolumesWithRelated(ctx context.Context, workspaceId uint) ([]types.VolumeWithRelated, error) ListDeployments(ctx context.Context, filters types.DeploymentFilter) ([]types.DeploymentWithRelated, error) ListDeploymentsPaginated(ctx context.Context, filters types.DeploymentFilter) (common.CursorPaginationInfo[types.DeploymentWithRelated], error) GetLatestDeploymentByName(ctx context.Context, workspaceId uint, name string, stubType string) (*types.Deployment, error) diff --git a/internal/types/backend.go b/internal/types/backend.go index 8e5dfdb7a..6a00f72c3 100644 --- a/internal/types/backend.go +++ b/internal/types/backend.go @@ -39,8 +39,15 @@ type Volume struct { Id uint `db:"id"` ExternalId string `db:"external_id"` Name string `db:"name"` + Size uint64 // Populated by volume abstraction WorkspaceId uint `db:"workspace_id"` // Foreign key to Workspace CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` +} + +type VolumeWithRelated struct { + Volume + Workspace Workspace `db:"workspace" json:"workspace"` } type Deployment struct { diff --git a/proto/volume.pb.go b/proto/volume.pb.go index b7aeef83e..f7af13a78 100644 --- a/proto/volume.pb.go +++ b/proto/volume.pb.go @@ -9,6 +9,7 @@ package proto import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -20,6 +21,101 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type VolumeInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Size uint64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + WorkspaceId string `protobuf:"bytes,6,opt,name=workspace_id,json=workspaceId,proto3" json:"workspace_id,omitempty"` + WorkspaceName string `protobuf:"bytes,7,opt,name=workspace_name,json=workspaceName,proto3" json:"workspace_name,omitempty"` +} + +func (x *VolumeInstance) Reset() { + *x = VolumeInstance{} + if protoimpl.UnsafeEnabled { + mi := &file_volume_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VolumeInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VolumeInstance) ProtoMessage() {} + +func (x *VolumeInstance) ProtoReflect() protoreflect.Message { + mi := &file_volume_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VolumeInstance.ProtoReflect.Descriptor instead. +func (*VolumeInstance) Descriptor() ([]byte, []int) { + return file_volume_proto_rawDescGZIP(), []int{0} +} + +func (x *VolumeInstance) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *VolumeInstance) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *VolumeInstance) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *VolumeInstance) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *VolumeInstance) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *VolumeInstance) GetWorkspaceId() string { + if x != nil { + return x.WorkspaceId + } + return "" +} + +func (x *VolumeInstance) GetWorkspaceName() string { + if x != nil { + return x.WorkspaceName + } + return "" +} + type GetOrCreateVolumeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -31,7 +127,7 @@ type GetOrCreateVolumeRequest struct { func (x *GetOrCreateVolumeRequest) Reset() { *x = GetOrCreateVolumeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[0] + mi := &file_volume_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -44,7 +140,7 @@ func (x *GetOrCreateVolumeRequest) String() string { func (*GetOrCreateVolumeRequest) ProtoMessage() {} func (x *GetOrCreateVolumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[0] + mi := &file_volume_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -57,7 +153,7 @@ func (x *GetOrCreateVolumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOrCreateVolumeRequest.ProtoReflect.Descriptor instead. func (*GetOrCreateVolumeRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{0} + return file_volume_proto_rawDescGZIP(), []int{1} } func (x *GetOrCreateVolumeRequest) GetName() string { @@ -72,14 +168,15 @@ type GetOrCreateVolumeResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` - VolumeId string `protobuf:"bytes,2,opt,name=volume_id,json=volumeId,proto3" json:"volume_id,omitempty"` + 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"` + Volume *VolumeInstance `protobuf:"bytes,3,opt,name=volume,proto3" json:"volume,omitempty"` } func (x *GetOrCreateVolumeResponse) Reset() { *x = GetOrCreateVolumeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[1] + mi := &file_volume_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -92,7 +189,7 @@ func (x *GetOrCreateVolumeResponse) String() string { func (*GetOrCreateVolumeResponse) ProtoMessage() {} func (x *GetOrCreateVolumeResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[1] + mi := &file_volume_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -105,7 +202,7 @@ func (x *GetOrCreateVolumeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOrCreateVolumeResponse.ProtoReflect.Descriptor instead. func (*GetOrCreateVolumeResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{1} + return file_volume_proto_rawDescGZIP(), []int{2} } func (x *GetOrCreateVolumeResponse) GetOk() bool { @@ -115,13 +212,20 @@ func (x *GetOrCreateVolumeResponse) GetOk() bool { return false } -func (x *GetOrCreateVolumeResponse) GetVolumeId() string { +func (x *GetOrCreateVolumeResponse) GetErrMsg() string { if x != nil { - return x.VolumeId + return x.ErrMsg } return "" } +func (x *GetOrCreateVolumeResponse) GetVolume() *VolumeInstance { + if x != nil { + return x.Volume + } + return nil +} + type ListPathRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -134,7 +238,7 @@ type ListPathRequest struct { func (x *ListPathRequest) Reset() { *x = ListPathRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[2] + mi := &file_volume_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -147,7 +251,7 @@ func (x *ListPathRequest) String() string { func (*ListPathRequest) ProtoMessage() {} func (x *ListPathRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[2] + mi := &file_volume_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -160,7 +264,7 @@ func (x *ListPathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPathRequest.ProtoReflect.Descriptor instead. func (*ListPathRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{2} + return file_volume_proto_rawDescGZIP(), []int{3} } func (x *ListPathRequest) GetPath() string { @@ -190,7 +294,7 @@ type ListPathResponse struct { func (x *ListPathResponse) Reset() { *x = ListPathResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[3] + mi := &file_volume_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -203,7 +307,7 @@ func (x *ListPathResponse) String() string { func (*ListPathResponse) ProtoMessage() {} func (x *ListPathResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[3] + mi := &file_volume_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -216,7 +320,7 @@ func (x *ListPathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPathResponse.ProtoReflect.Descriptor instead. func (*ListPathResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{3} + return file_volume_proto_rawDescGZIP(), []int{4} } func (x *ListPathResponse) GetOk() bool { @@ -251,7 +355,7 @@ type DeletePathRequest struct { func (x *DeletePathRequest) Reset() { *x = DeletePathRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[4] + mi := &file_volume_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -264,7 +368,7 @@ func (x *DeletePathRequest) String() string { func (*DeletePathRequest) ProtoMessage() {} func (x *DeletePathRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[4] + mi := &file_volume_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -277,7 +381,7 @@ func (x *DeletePathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeletePathRequest.ProtoReflect.Descriptor instead. func (*DeletePathRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{4} + return file_volume_proto_rawDescGZIP(), []int{5} } func (x *DeletePathRequest) GetPath() string { @@ -300,7 +404,7 @@ type DeletePathResponse struct { func (x *DeletePathResponse) Reset() { *x = DeletePathResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[5] + mi := &file_volume_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -313,7 +417,7 @@ func (x *DeletePathResponse) String() string { func (*DeletePathResponse) ProtoMessage() {} func (x *DeletePathResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[5] + mi := &file_volume_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -326,7 +430,7 @@ func (x *DeletePathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeletePathResponse.ProtoReflect.Descriptor instead. func (*DeletePathResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{5} + return file_volume_proto_rawDescGZIP(), []int{6} } func (x *DeletePathResponse) GetOk() bool { @@ -362,7 +466,7 @@ type CopyPathRequest struct { func (x *CopyPathRequest) Reset() { *x = CopyPathRequest{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[6] + mi := &file_volume_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -375,7 +479,7 @@ func (x *CopyPathRequest) String() string { func (*CopyPathRequest) ProtoMessage() {} func (x *CopyPathRequest) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[6] + mi := &file_volume_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -388,7 +492,7 @@ func (x *CopyPathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CopyPathRequest.ProtoReflect.Descriptor instead. func (*CopyPathRequest) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{6} + return file_volume_proto_rawDescGZIP(), []int{7} } func (x *CopyPathRequest) GetPath() string { @@ -412,13 +516,13 @@ type CopyPathResponse struct { Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` ObjectId string `protobuf:"bytes,2,opt,name=object_id,json=objectId,proto3" json:"object_id,omitempty"` - ErrorMsg string `protobuf:"bytes,3,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` + ErrMsg string `protobuf:"bytes,3,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` } func (x *CopyPathResponse) Reset() { *x = CopyPathResponse{} if protoimpl.UnsafeEnabled { - mi := &file_volume_proto_msgTypes[7] + mi := &file_volume_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -431,7 +535,7 @@ func (x *CopyPathResponse) String() string { func (*CopyPathResponse) ProtoMessage() {} func (x *CopyPathResponse) ProtoReflect() protoreflect.Message { - mi := &file_volume_proto_msgTypes[7] + mi := &file_volume_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -444,7 +548,7 @@ func (x *CopyPathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CopyPathResponse.ProtoReflect.Descriptor instead. func (*CopyPathResponse) Descriptor() ([]byte, []int) { - return file_volume_proto_rawDescGZIP(), []int{7} + return file_volume_proto_rawDescGZIP(), []int{8} } func (x *CopyPathResponse) GetOk() bool { @@ -461,76 +565,211 @@ func (x *CopyPathResponse) GetObjectId() string { return "" } -func (x *CopyPathResponse) GetErrorMsg() string { +func (x *CopyPathResponse) GetErrMsg() string { if x != nil { - return x.ErrorMsg + return x.ErrMsg } return "" } +type ListVolumesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListVolumesRequest) Reset() { + *x = ListVolumesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_volume_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVolumesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVolumesRequest) ProtoMessage() {} + +func (x *ListVolumesRequest) ProtoReflect() protoreflect.Message { + mi := &file_volume_proto_msgTypes[9] + 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 ListVolumesRequest.ProtoReflect.Descriptor instead. +func (*ListVolumesRequest) Descriptor() ([]byte, []int) { + return file_volume_proto_rawDescGZIP(), []int{9} +} + +type ListVolumesResponse 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"` + Volumes []*VolumeInstance `protobuf:"bytes,3,rep,name=volumes,proto3" json:"volumes,omitempty"` +} + +func (x *ListVolumesResponse) Reset() { + *x = ListVolumesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_volume_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVolumesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVolumesResponse) ProtoMessage() {} + +func (x *ListVolumesResponse) ProtoReflect() protoreflect.Message { + mi := &file_volume_proto_msgTypes[10] + 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 ListVolumesResponse.ProtoReflect.Descriptor instead. +func (*ListVolumesResponse) Descriptor() ([]byte, []int) { + return file_volume_proto_rawDescGZIP(), []int{10} +} + +func (x *ListVolumesResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *ListVolumesResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + +func (x *ListVolumesResponse) GetVolumes() []*VolumeInstance { + if x != nil { + return x.Volumes + } + return nil +} + var File_volume_proto protoreflect.FileDescriptor var file_volume_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, - 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x48, 0x0a, 0x19, 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, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x02, 0x6f, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x49, 0x64, - 0x22, 0x46, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 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, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6c, 0x6f, - 0x6e, 0x67, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x51, 0x0a, 0x10, 0x4c, 0x69, 0x73, 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, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, 0x27, 0x0a, 0x11, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 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, 0x57, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x3f, 0x0a, - 0x0f, 0x43, 0x6f, 0x70, 0x79, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x5c, - 0x0a, 0x10, 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, 0x0a, 0x0e, 0x56, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x74, 0x0a, 0x19, 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, 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, 0x2e, 0x0a, 0x06, 0x76, 0x6f, 0x6c, 0x75, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x22, 0x46, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 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, 0x12, + 0x1f, 0x0a, 0x0b, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x22, 0x51, 0x0a, 0x10, 0x4c, 0x69, 0x73, 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, 0x12, 0x14, 0x0a, + 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, + 0x74, 0x68, 0x73, 0x22, 0x27, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 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, 0x57, 0x0a, 0x12, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 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, 0x1b, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, - 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x32, 0xbc, 0x02, 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, 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, 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, + 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, 0x18, 0x0a, 0x07, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x3f, 0x0a, 0x0f, 0x43, 0x6f, 0x70, 0x79, 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, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x58, 0x0a, 0x10, 0x43, 0x6f, 0x70, 0x79, 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, 0x1b, 0x0a, 0x09, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, + 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, + 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x70, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x6f, + 0x6c, 0x75, 0x6d, 0x65, 0x73, 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, 0x30, 0x0a, 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, + 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, + 0x07, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x73, 0x32, 0x86, 0x03, 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, 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, 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 ( @@ -545,31 +784,41 @@ func file_volume_proto_rawDescGZIP() []byte { return file_volume_proto_rawDescData } -var file_volume_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_volume_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_volume_proto_goTypes = []interface{}{ - (*GetOrCreateVolumeRequest)(nil), // 0: volume.GetOrCreateVolumeRequest - (*GetOrCreateVolumeResponse)(nil), // 1: volume.GetOrCreateVolumeResponse - (*ListPathRequest)(nil), // 2: volume.ListPathRequest - (*ListPathResponse)(nil), // 3: volume.ListPathResponse - (*DeletePathRequest)(nil), // 4: volume.DeletePathRequest - (*DeletePathResponse)(nil), // 5: volume.DeletePathResponse - (*CopyPathRequest)(nil), // 6: volume.CopyPathRequest - (*CopyPathResponse)(nil), // 7: volume.CopyPathResponse + (*VolumeInstance)(nil), // 0: volume.VolumeInstance + (*GetOrCreateVolumeRequest)(nil), // 1: volume.GetOrCreateVolumeRequest + (*GetOrCreateVolumeResponse)(nil), // 2: volume.GetOrCreateVolumeResponse + (*ListPathRequest)(nil), // 3: volume.ListPathRequest + (*ListPathResponse)(nil), // 4: volume.ListPathResponse + (*DeletePathRequest)(nil), // 5: volume.DeletePathRequest + (*DeletePathResponse)(nil), // 6: volume.DeletePathResponse + (*CopyPathRequest)(nil), // 7: volume.CopyPathRequest + (*CopyPathResponse)(nil), // 8: volume.CopyPathResponse + (*ListVolumesRequest)(nil), // 9: volume.ListVolumesRequest + (*ListVolumesResponse)(nil), // 10: volume.ListVolumesResponse + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp } var file_volume_proto_depIdxs = []int32{ - 0, // 0: volume.VolumeService.GetOrCreateVolume:input_type -> volume.GetOrCreateVolumeRequest - 2, // 1: volume.VolumeService.ListPath:input_type -> volume.ListPathRequest - 4, // 2: volume.VolumeService.DeletePath:input_type -> volume.DeletePathRequest - 6, // 3: volume.VolumeService.CopyPathStream:input_type -> volume.CopyPathRequest - 1, // 4: volume.VolumeService.GetOrCreateVolume:output_type -> volume.GetOrCreateVolumeResponse - 3, // 5: volume.VolumeService.ListPath:output_type -> volume.ListPathResponse - 5, // 6: volume.VolumeService.DeletePath:output_type -> volume.DeletePathResponse - 7, // 7: volume.VolumeService.CopyPathStream:output_type -> volume.CopyPathResponse - 4, // [4:8] is the sub-list for method output_type - 0, // [0:4] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 11, // 0: volume.VolumeInstance.created_at:type_name -> google.protobuf.Timestamp + 11, // 1: volume.VolumeInstance.updated_at:type_name -> google.protobuf.Timestamp + 0, // 2: volume.GetOrCreateVolumeResponse.volume:type_name -> volume.VolumeInstance + 0, // 3: volume.ListVolumesResponse.volumes:type_name -> volume.VolumeInstance + 1, // 4: volume.VolumeService.GetOrCreateVolume:input_type -> volume.GetOrCreateVolumeRequest + 9, // 5: volume.VolumeService.ListVolumes:input_type -> volume.ListVolumesRequest + 3, // 6: volume.VolumeService.ListPath:input_type -> volume.ListPathRequest + 5, // 7: volume.VolumeService.DeletePath:input_type -> volume.DeletePathRequest + 7, // 8: volume.VolumeService.CopyPathStream:input_type -> volume.CopyPathRequest + 2, // 9: volume.VolumeService.GetOrCreateVolume:output_type -> volume.GetOrCreateVolumeResponse + 10, // 10: volume.VolumeService.ListVolumes:output_type -> volume.ListVolumesResponse + 4, // 11: volume.VolumeService.ListPath:output_type -> volume.ListPathResponse + 6, // 12: volume.VolumeService.DeletePath:output_type -> volume.DeletePathResponse + 8, // 13: volume.VolumeService.CopyPathStream:output_type -> volume.CopyPathResponse + 9, // [9:14] is the sub-list for method output_type + 4, // [4:9] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_volume_proto_init() } @@ -579,7 +828,7 @@ func file_volume_proto_init() { } if !protoimpl.UnsafeEnabled { file_volume_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOrCreateVolumeRequest); i { + switch v := v.(*VolumeInstance); i { case 0: return &v.state case 1: @@ -591,7 +840,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOrCreateVolumeResponse); i { + switch v := v.(*GetOrCreateVolumeRequest); i { case 0: return &v.state case 1: @@ -603,7 +852,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPathRequest); i { + switch v := v.(*GetOrCreateVolumeResponse); i { case 0: return &v.state case 1: @@ -615,7 +864,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPathResponse); i { + switch v := v.(*ListPathRequest); i { case 0: return &v.state case 1: @@ -627,7 +876,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePathRequest); i { + switch v := v.(*ListPathResponse); i { case 0: return &v.state case 1: @@ -639,7 +888,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePathResponse); i { + switch v := v.(*DeletePathRequest); i { case 0: return &v.state case 1: @@ -651,7 +900,7 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CopyPathRequest); i { + switch v := v.(*DeletePathResponse); i { case 0: return &v.state case 1: @@ -663,6 +912,18 @@ func file_volume_proto_init() { } } file_volume_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CopyPathRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_volume_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CopyPathResponse); i { case 0: return &v.state @@ -674,6 +935,30 @@ func file_volume_proto_init() { return nil } } + file_volume_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVolumesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_volume_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVolumesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -681,7 +966,7 @@ func file_volume_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_volume_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/volume_grpc.pb.go b/proto/volume_grpc.pb.go index 5d3d85597..dc49096ea 100644 --- a/proto/volume_grpc.pb.go +++ b/proto/volume_grpc.pb.go @@ -20,6 +20,7 @@ const _ = grpc.SupportPackageIsVersion7 const ( VolumeService_GetOrCreateVolume_FullMethodName = "/volume.VolumeService/GetOrCreateVolume" + VolumeService_ListVolumes_FullMethodName = "/volume.VolumeService/ListVolumes" VolumeService_ListPath_FullMethodName = "/volume.VolumeService/ListPath" VolumeService_DeletePath_FullMethodName = "/volume.VolumeService/DeletePath" VolumeService_CopyPathStream_FullMethodName = "/volume.VolumeService/CopyPathStream" @@ -30,6 +31,7 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type VolumeServiceClient interface { GetOrCreateVolume(ctx context.Context, in *GetOrCreateVolumeRequest, opts ...grpc.CallOption) (*GetOrCreateVolumeResponse, error) + ListVolumes(ctx context.Context, in *ListVolumesRequest, opts ...grpc.CallOption) (*ListVolumesResponse, error) ListPath(ctx context.Context, in *ListPathRequest, opts ...grpc.CallOption) (*ListPathResponse, error) DeletePath(ctx context.Context, in *DeletePathRequest, opts ...grpc.CallOption) (*DeletePathResponse, error) CopyPathStream(ctx context.Context, opts ...grpc.CallOption) (VolumeService_CopyPathStreamClient, error) @@ -52,6 +54,15 @@ func (c *volumeServiceClient) GetOrCreateVolume(ctx context.Context, in *GetOrCr return out, nil } +func (c *volumeServiceClient) ListVolumes(ctx context.Context, in *ListVolumesRequest, opts ...grpc.CallOption) (*ListVolumesResponse, error) { + out := new(ListVolumesResponse) + err := c.cc.Invoke(ctx, VolumeService_ListVolumes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *volumeServiceClient) ListPath(ctx context.Context, in *ListPathRequest, opts ...grpc.CallOption) (*ListPathResponse, error) { out := new(ListPathResponse) err := c.cc.Invoke(ctx, VolumeService_ListPath_FullMethodName, in, out, opts...) @@ -109,6 +120,7 @@ func (x *volumeServiceCopyPathStreamClient) CloseAndRecv() (*CopyPathResponse, e // for forward compatibility type VolumeServiceServer interface { GetOrCreateVolume(context.Context, *GetOrCreateVolumeRequest) (*GetOrCreateVolumeResponse, error) + ListVolumes(context.Context, *ListVolumesRequest) (*ListVolumesResponse, error) ListPath(context.Context, *ListPathRequest) (*ListPathResponse, error) DeletePath(context.Context, *DeletePathRequest) (*DeletePathResponse, error) CopyPathStream(VolumeService_CopyPathStreamServer) error @@ -122,6 +134,9 @@ type UnimplementedVolumeServiceServer struct { func (UnimplementedVolumeServiceServer) GetOrCreateVolume(context.Context, *GetOrCreateVolumeRequest) (*GetOrCreateVolumeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOrCreateVolume not implemented") } +func (UnimplementedVolumeServiceServer) ListVolumes(context.Context, *ListVolumesRequest) (*ListVolumesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVolumes not implemented") +} func (UnimplementedVolumeServiceServer) ListPath(context.Context, *ListPathRequest) (*ListPathResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPath not implemented") } @@ -162,6 +177,24 @@ func _VolumeService_GetOrCreateVolume_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _VolumeService_ListVolumes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListVolumesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VolumeServiceServer).ListVolumes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VolumeService_ListVolumes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VolumeServiceServer).ListVolumes(ctx, req.(*ListVolumesRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _VolumeService_ListPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListPathRequest) if err := dec(in); err != nil { @@ -235,6 +268,10 @@ var VolumeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetOrCreateVolume", Handler: _VolumeService_GetOrCreateVolume_Handler, }, + { + MethodName: "ListVolumes", + Handler: _VolumeService_ListVolumes_Handler, + }, { MethodName: "ListPath", Handler: _VolumeService_ListPath_Handler, diff --git a/sdk/src/beta9/abstractions/volume.py b/sdk/src/beta9/abstractions/volume.py index e26452a55..1ea951ed6 100644 --- a/sdk/src/beta9/abstractions/volume.py +++ b/sdk/src/beta9/abstractions/volume.py @@ -1,6 +1,6 @@ from ..abstractions.base import BaseAbstraction from ..clients.gateway import Volume as VolumeConfig -from ..clients.volume import GetOrCreateVolumeRequest, VolumeServiceStub +from ..clients.volume import GetOrCreateVolumeRequest, GetOrCreateVolumeResponse, VolumeServiceStub class Volume(BaseAbstraction): @@ -34,13 +34,14 @@ def __init__(self, name: str, mount_path: str) -> None: self.stub: VolumeServiceStub = VolumeServiceStub(self.channel) def get_or_create(self) -> bool: + resp: GetOrCreateVolumeResponse resp = self.run_sync( self.stub.get_or_create_volume(GetOrCreateVolumeRequest(name=self.name)) ) if resp.ok: self.ready = True - self.volume_id = resp.volume_id + self.volume_id = resp.volume.id return True return False diff --git a/sdk/src/beta9/cli/deployment.py b/sdk/src/beta9/cli/deployment.py index b0250a961..634b18681 100644 --- a/sdk/src/beta9/cli/deployment.py +++ b/sdk/src/beta9/cli/deployment.py @@ -1,6 +1,7 @@ import importlib import os import sys +from pathlib import Path import click @@ -18,12 +19,26 @@ def common(ctx: click.Context): @common.command( name="deploy", - help="Deploy a new function.", + help=""" + Deploy a new function. + + ENTRYPOINT is in the format of "file:function". + """, +) +@click.option( + "--name", + type=click.STRING, + help="The name the deployment.", + required=True, ) -@click.pass_obj -def deploy(service: ServiceClient): - # todo: implement a quicker/shorter version of create_deployment() - pass +@click.argument( + "entrypoint", + nargs=1, + required=True, +) +@click.pass_context +def deploy(ctx: click.Context, name: str, entrypoint: str): + ctx.invoke(create_deployment, name=name, entrypoint=entrypoint) @click.group( @@ -41,16 +56,25 @@ def management(ctx: click.Context): help="Create a new deployment.", ) @click.option("--name", help="The name the deployment.", required=True) -@click.option("--function", help="The name the entry point and function.", required=True) -def create_deployment(name: str, function: str): +@click.option("--entrypoint", help='The name the entrypoint e.g. "file:function".', required=True) +def create_deployment(name: str, entrypoint: str): current_dir = os.getcwd() if current_dir not in sys.path: sys.path.insert(0, current_dir) - module_path, func_name = function.split(":") + module_path, func_name, *_ = entrypoint.split(":") if ":" in entrypoint else (entrypoint, "") module_name = module_path.replace(".py", "").replace(os.path.sep, ".") + + if not Path(module_path).exists(): + terminal.error(f"Unable to find file '{module_path}'") + if not func_name: + terminal.error(f"Unable to parse function '{func_name}'") + module = importlib.import_module(module_name) - func = getattr(module, func_name) + func = getattr(module, func_name, None) + if func is None: + terminal.error(f"Unable to find function '{func_name}'") + if not func.deploy(name=name): terminal.error("Deployment failed ☠️") diff --git a/sdk/src/beta9/cli/task.py b/sdk/src/beta9/cli/task.py index 9e3da0828..4999c0330 100644 --- a/sdk/src/beta9/cli/task.py +++ b/sdk/src/beta9/cli/task.py @@ -84,15 +84,14 @@ def parse_filter_values( ) @click.pass_obj def list_tasks(service: ServiceClient, limit: int, format: str, filter: Dict[str, StringList]): - response: ListTasksResponse = aio.run_sync( - service.gateway.list_tasks(ListTasksRequest(filters=filter, limit=limit)) - ) + res: ListTasksResponse + res = aio.run_sync(service.gateway.list_tasks(ListTasksRequest(filters=filter, limit=limit))) - if not response.ok: - terminal.error(response.err_msg) + if not res.ok: + terminal.error(res.err_msg) if format == "json": - tasks = [task.to_dict(casing=Casing.SNAKE) for task in response.tasks] + tasks = [task.to_dict(casing=Casing.SNAKE) for task in res.tasks] terminal.print_json(tasks) return @@ -107,7 +106,7 @@ def list_tasks(service: ServiceClient, limit: int, format: str, filter: Dict[str box=box.SIMPLE, ) - for task in response.tasks: + for task in res.tasks: table.add_row( task.id, ( @@ -123,7 +122,7 @@ def list_tasks(service: ServiceClient, limit: int, format: str, filter: Dict[str ) table.add_section() - table.add_row(f"[bold]Total: {response.total}") + table.add_row(f"[bold]Total: {res.total}") terminal.print(table) @@ -137,9 +136,9 @@ def list_tasks(service: ServiceClient, limit: int, format: str, filter: Dict[str ) @click.pass_obj def stop_task(service: GatewayServiceStub, task_id: str): - response: StopTaskResponse = aio.run_sync(service.stop_task(StopTaskRequest(task_id=task_id))) + res: StopTaskResponse = aio.run_sync(service.stop_task(StopTaskRequest(task_id=task_id))) - if response.ok: + if res.ok: terminal.detail(f"Stopped task {task_id}", dim=False) else: - terminal.error(f"{response.err_msg}\nFailed to stop task {task_id}") + terminal.error(f"{res.err_msg}\nFailed to stop task {task_id}") diff --git a/sdk/src/beta9/cli/volume.py b/sdk/src/beta9/cli/volume.py index 9139d7a17..e9660f3bc 100644 --- a/sdk/src/beta9/cli/volume.py +++ b/sdk/src/beta9/cli/volume.py @@ -3,6 +3,7 @@ from typing import Iterable, Union import click +from rich.table import Column, Table, box from beta9 import aio, terminal from beta9.cli.contexts import ServiceClient @@ -11,8 +12,12 @@ CopyPathRequest, CopyPathResponse, DeletePathRequest, + GetOrCreateVolumeRequest, + GetOrCreateVolumeResponse, ListPathRequest, ListPathResponse, + ListVolumesRequest, + ListVolumesResponse, ) from beta9.terminal import pluralize @@ -137,7 +142,7 @@ def cp(service: ServiceClient, local_path: str, remote_path: str) -> None: res: CopyPathResponse = aio.run_sync(service.volume.copy_path_stream(req)) if not res.ok: - terminal.error(f"{dst} ({res.error_msg})") + terminal.error(f"{dst} ({res.err_msg})") def read_with_progress( @@ -198,17 +203,80 @@ def management(ctx: click.Context): ctx.obj = ctx.with_resource(ServiceClient()) -@management.command(name="list") +@management.command( + name="list", + help="List available volumes.", +) @click.pass_obj def list_volumes(service: ServiceClient): - pass + res: ListVolumesResponse + res = aio.run_sync(service.volume.list_volumes(ListVolumesRequest())) + if not res.ok: + terminal.error(res.err_msg) + + table = Table( + Column("Name"), + Column("Size"), + Column("Created At"), + Column("Updated At"), + Column("Workspace Name"), + box=box.SIMPLE, + ) + + for volume in res.volumes: + table.add_row( + volume.name, + terminal.humanize_memory(volume.size), + terminal.humanize_date(volume.created_at), + terminal.humanize_date(volume.updated_at), + volume.workspace_name, + ) + + table.add_section() + table.add_row(f"[bold]Total: {len(res.volumes)}") + terminal.print(table) -@management.command(name="create") -def create_volume(): - pass +@management.command( + name="create", + help="Create a new volume.", +) +@click.option( + "--name", + "-n", + type=click.STRING, + required=True, +) +@click.pass_obj +def create_volume(service: ServiceClient, name: str): + res: GetOrCreateVolumeResponse + res = aio.run_sync(service.volume.get_or_create_volume(GetOrCreateVolumeRequest(name=name))) -@management.command(name="delete") + if not res.ok: + terminal.print(res.volume) + terminal.error(res.err_msg) + + table = Table( + Column("Name"), + Column("Created At"), + Column("Updated At"), + Column("Workspace Name"), + box=box.SIMPLE, + ) + + table.add_row( + res.volume.name, + terminal.humanize_date(res.volume.created_at), + terminal.humanize_date(res.volume.updated_at), + res.volume.workspace_name, + ) + terminal.print(table) + + +@management.command( + name="delete", + help="Delete a volume.", +) def delete_volume(): pass diff --git a/sdk/src/beta9/clients/volume/__init__.py b/sdk/src/beta9/clients/volume/__init__.py index 9b0177d2c..97a809c4b 100644 --- a/sdk/src/beta9/clients/volume/__init__.py +++ b/sdk/src/beta9/clients/volume/__init__.py @@ -4,6 +4,7 @@ # This file has been @generated from dataclasses import dataclass +from datetime import datetime from typing import ( TYPE_CHECKING, AsyncIterable, @@ -26,6 +27,17 @@ from grpclib.metadata import Deadline +@dataclass(eq=False, repr=False) +class VolumeInstance(betterproto.Message): + id: str = betterproto.string_field(1) + name: str = betterproto.string_field(2) + size: int = betterproto.uint64_field(3) + created_at: datetime = betterproto.message_field(4) + updated_at: datetime = betterproto.message_field(5) + workspace_id: str = betterproto.string_field(6) + workspace_name: str = betterproto.string_field(7) + + @dataclass(eq=False, repr=False) class GetOrCreateVolumeRequest(betterproto.Message): name: str = betterproto.string_field(1) @@ -34,7 +46,8 @@ class GetOrCreateVolumeRequest(betterproto.Message): @dataclass(eq=False, repr=False) class GetOrCreateVolumeResponse(betterproto.Message): ok: bool = betterproto.bool_field(1) - volume_id: str = betterproto.string_field(2) + err_msg: str = betterproto.string_field(2) + volume: "VolumeInstance" = betterproto.message_field(3) @dataclass(eq=False, repr=False) @@ -72,7 +85,19 @@ class CopyPathRequest(betterproto.Message): class CopyPathResponse(betterproto.Message): ok: bool = betterproto.bool_field(1) object_id: str = betterproto.string_field(2) - error_msg: str = betterproto.string_field(3) + err_msg: str = betterproto.string_field(3) + + +@dataclass(eq=False, repr=False) +class ListVolumesRequest(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class ListVolumesResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + volumes: List["VolumeInstance"] = betterproto.message_field(3) class VolumeServiceStub(betterproto.ServiceStub): @@ -93,6 +118,23 @@ async def get_or_create_volume( metadata=metadata, ) + async def list_volumes( + self, + list_volumes_request: "ListVolumesRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "ListVolumesResponse": + return await self._unary_unary( + "/volume.VolumeService/ListVolumes", + list_volumes_request, + ListVolumesResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + async def list_path( self, list_path_request: "ListPathRequest", @@ -155,6 +197,11 @@ async def get_or_create_volume( ) -> "GetOrCreateVolumeResponse": raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def list_volumes( + self, list_volumes_request: "ListVolumesRequest" + ) -> "ListVolumesResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def list_path( self, list_path_request: "ListPathRequest" ) -> "ListPathResponse": @@ -178,6 +225,13 @@ async def __rpc_get_or_create_volume( response = await self.get_or_create_volume(request) await stream.send_message(response) + async def __rpc_list_volumes( + self, stream: "grpclib.server.Stream[ListVolumesRequest, ListVolumesResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.list_volumes(request) + await stream.send_message(response) + async def __rpc_list_path( self, stream: "grpclib.server.Stream[ListPathRequest, ListPathResponse]" ) -> None: @@ -207,6 +261,12 @@ def __mapping__(self) -> Dict[str, grpclib.const.Handler]: GetOrCreateVolumeRequest, GetOrCreateVolumeResponse, ), + "/volume.VolumeService/ListVolumes": grpclib.const.Handler( + self.__rpc_list_volumes, + grpclib.const.Cardinality.UNARY_UNARY, + ListVolumesRequest, + ListVolumesResponse, + ), "/volume.VolumeService/ListPath": grpclib.const.Handler( self.__rpc_list_path, grpclib.const.Cardinality.UNARY_UNARY, diff --git a/sdk/src/beta9/terminal.py b/sdk/src/beta9/terminal.py index 9cb3a9996..4b94512e5 100644 --- a/sdk/src/beta9/terminal.py +++ b/sdk/src/beta9/terminal.py @@ -101,6 +101,15 @@ def humanize_date(d: datetime.datetime) -> str: return f"{s // 3600} hours ago" +def humanize_memory(m: float) -> str: + units = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"] + index = 0 + while m >= 1024 and index < len(units) - 1: + m /= 1024 + index += 1 + return f"{m:.2f} {units[index]}" + + def pluralize(seq: Sequence, suffix: str = "s") -> Tuple[int, str]: n = len(seq) return n, "s" if n != 1 else "" diff --git a/sdk/tests/test_volumes.py b/sdk/tests/test_volumes.py index 9fdc48d4a..61c83d0eb 100644 --- a/sdk/tests/test_volumes.py +++ b/sdk/tests/test_volumes.py @@ -2,7 +2,7 @@ from unittest.mock import MagicMock from beta9.abstractions.volume import Volume -from beta9.clients.volume import GetOrCreateVolumeResponse +from beta9.clients.volume import GetOrCreateVolumeResponse, VolumeInstance from .utils import mock_coroutine_with_result @@ -16,7 +16,7 @@ def test_get_or_create(self): # Test that a valid grpc response sets the volume id and ready flag mock_stub.get_or_create_volume = mock_coroutine_with_result( - GetOrCreateVolumeResponse(ok=True, volume_id="1234") + GetOrCreateVolumeResponse(ok=True, volume=VolumeInstance(id="1234")) ) volume = Volume(name="test", mount_path="/test") @@ -29,7 +29,7 @@ def test_get_or_create(self): # Test that an invalid grpc response does not set the volume id or ready flag mock_stub.get_or_create_volume = mock_coroutine_with_result( - GetOrCreateVolumeResponse(ok=False, volume_id="") + GetOrCreateVolumeResponse(ok=False, volume=VolumeInstance(id="")) ) volume = Volume(name="test", mount_path="/test")