mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix(region): cephfs set quota (#21482)
This commit is contained in:
@@ -28,4 +28,5 @@ func init() {
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
cmd.Create(&compute.FileSystemCreateOptions{})
|
||||
cmd.Perform("syncstatus", &compute.FileSystemIdOption{})
|
||||
cmd.Perform("set-quota", &compute.FileSystemSetQuotaOption{})
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ require (
|
||||
k8s.io/cri-api v0.22.17
|
||||
k8s.io/klog/v2 v2.20.0
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241025091252-df8c7dbcd484
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241028100353-47c8a5c40d6b
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
|
||||
yunion.io/x/jsonutils v1.0.1-0.20240930100528-1671a2d0d22f
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
|
||||
@@ -1376,8 +1376,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241025091252-df8c7dbcd484 h1:f1TeDeLNujbvNf936juI/aqmEGEm7Xu89DlT1R0SX7E=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241025091252-df8c7dbcd484/go.mod h1:rj/pb3DitJlQaQD8UW1oxx/KD+PzDZqoywzqRJaFE9A=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241028100353-47c8a5c40d6b h1:FcXznm3YP5ThT+nrti3umbmYgbOqlWGq+Xxb7tLDBK0=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241028100353-47c8a5c40d6b/go.mod h1:rj/pb3DitJlQaQD8UW1oxx/KD+PzDZqoywzqRJaFE9A=
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
|
||||
@@ -114,3 +114,8 @@ type FileSystemRemoteUpdateInput struct {
|
||||
// 是否覆盖替换所有标签
|
||||
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
|
||||
}
|
||||
|
||||
type FileSystemSetQuotaInput struct {
|
||||
MaxGb *int64
|
||||
MaxFiles *int64
|
||||
}
|
||||
|
||||
@@ -589,6 +589,33 @@ func (fileSystem *SFileSystem) StartSyncstatus(ctx context.Context, userCred mcc
|
||||
return StartResourceSyncStatusTask(ctx, userCred, fileSystem, "FileSystemSyncstatusTask", parentTaskId)
|
||||
}
|
||||
|
||||
// 设置容量大小(CephFS)
|
||||
func (fileSystem *SFileSystem) PerformSetQuota(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.FileSystemSetQuotaInput) (jsonutils.JSONObject, error) {
|
||||
if input.MaxFiles == nil || input.MaxGb == nil {
|
||||
return nil, httperrors.NewMissingParameterError("max_gb")
|
||||
}
|
||||
var openTask = true
|
||||
count, err := taskman.TaskManager.QueryTasksOfObject(fileSystem, time.Now().Add(-3*time.Minute), &openTask).CountWithError()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil, httperrors.NewBadRequestError("Nas has %d task active, can't sync status", count)
|
||||
}
|
||||
|
||||
return nil, fileSystem.StartSetQuotaTask(ctx, userCred, input)
|
||||
}
|
||||
|
||||
func (fileSystem *SFileSystem) StartSetQuotaTask(ctx context.Context, userCred mcclient.TokenCredential, input *api.FileSystemSetQuotaInput) error {
|
||||
params := jsonutils.Marshal(input).(*jsonutils.JSONDict)
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "FileSystemSetQuotaTask", fileSystem, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileSystem.SetStatus(ctx, userCred, api.NAS_STATUS_EXTENDING, "set quota")
|
||||
return task.ScheduleRun(nil)
|
||||
}
|
||||
|
||||
func (fileSystem *SFileSystem) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
|
||||
provider, err := fileSystem.GetDriver(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -43,6 +43,5 @@ func StartResourceSyncStatusTask(ctx context.Context, userCred mcclient.TokenCre
|
||||
return err
|
||||
}
|
||||
obj.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "perform_syncstatus")
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
return task.ScheduleRun(nil)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type FileSystemSetQuotaTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(FileSystemSetQuotaTask{})
|
||||
}
|
||||
|
||||
func (self *FileSystemSetQuotaTask) taskFail(ctx context.Context, fs *models.SFileSystem, err error) {
|
||||
fs.SetStatus(ctx, self.UserCred, api.NAS_STATUS_AVAILABLE, err.Error())
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (self *FileSystemSetQuotaTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
fs := obj.(*models.SFileSystem)
|
||||
|
||||
iFs, err := fs.GetICloudFileSystem(ctx)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, fs, errors.Wrapf(err, "GetICloudFileSystem"))
|
||||
return
|
||||
}
|
||||
|
||||
input := &cloudprovider.SFileSystemSetQuotaInput{}
|
||||
err = self.GetParams().Unmarshal(input)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, fs, errors.Wrapf(err, "Params.Unmarshal"))
|
||||
return
|
||||
}
|
||||
|
||||
err = iFs.SetQuota(input)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, fs, errors.Wrapf(err, "SetQuota"))
|
||||
return
|
||||
}
|
||||
|
||||
err = iFs.Refresh()
|
||||
if err != nil {
|
||||
self.taskFail(ctx, fs, errors.Wrapf(err, "Refresh"))
|
||||
return
|
||||
}
|
||||
|
||||
err = fs.SyncWithCloudFileSystem(ctx, self.GetUserCred(), iFs)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, fs, errors.Wrapf(err, "SyncWithCloudFileSystem"))
|
||||
return
|
||||
}
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -54,3 +54,13 @@ type FileSystemCreateOptions struct {
|
||||
func (opts *FileSystemCreateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
type FileSystemSetQuotaOption struct {
|
||||
FileSystemIdOption
|
||||
MaxGb int64
|
||||
MaxFiles int64
|
||||
}
|
||||
|
||||
func (opts *FileSystemSetQuotaOption) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1785,7 +1785,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
|
||||
# sigs.k8s.io/yaml v1.2.0
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241025091252-df8c7dbcd484
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241028100353-47c8a5c40d6b
|
||||
## explicit; go 1.21
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
|
||||
+5
@@ -21,3 +21,8 @@ type SMountTargetCreateOptions struct {
|
||||
NetworkId string
|
||||
FileSystemId string
|
||||
}
|
||||
|
||||
type SFileSystemSetQuotaInput struct {
|
||||
MaxFiles int64
|
||||
MaxGb int64
|
||||
}
|
||||
|
||||
+2
@@ -1402,6 +1402,8 @@ type ICloudFileSystem interface {
|
||||
GetMountTargets() ([]ICloudMountTarget, error)
|
||||
CreateMountTarget(opts *SMountTargetCreateOptions) (ICloudMountTarget, error)
|
||||
|
||||
SetQuota(input *SFileSystemSetQuotaInput) error
|
||||
|
||||
Delete() error
|
||||
}
|
||||
|
||||
|
||||
+37
-14
@@ -22,12 +22,12 @@ import (
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SCephFsDir struct {
|
||||
multicloud.SVirtualResourceBase
|
||||
multicloud.SBillingBase
|
||||
multicloud.SNasBase
|
||||
multicloud.STagBase
|
||||
client *SCephFSClient
|
||||
|
||||
@@ -96,6 +96,37 @@ func (dir *SCephFsDir) Delete() error {
|
||||
return dir.client.DeleteDir(dir.client.fsId, dir.Path)
|
||||
}
|
||||
|
||||
func (dir *SCephFsDir) Refresh() error {
|
||||
dirs, err := dir.client.GetCephDirs(dir.client.fsId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range dirs {
|
||||
if dirs[i].GetGlobalId() == dir.GetGlobalId() {
|
||||
return jsonutils.Update(dir, &dirs[i])
|
||||
}
|
||||
}
|
||||
return errors.Wrapf(cloudprovider.ErrNotFound, dir.Path)
|
||||
}
|
||||
|
||||
func (dir *SCephFsDir) SetQuota(input *cloudprovider.SFileSystemSetQuotaInput) error {
|
||||
return dir.client.SetQuota(dir.client.fsId, dir.Path, input.MaxGb, input.MaxFiles)
|
||||
}
|
||||
|
||||
func (cli *SCephFSClient) SetQuota(fsId, path string, maxGb, maxFiles int64) error {
|
||||
path = fmt.Sprintf("/%s", strings.TrimPrefix(path, "/"))
|
||||
res := fmt.Sprintf("cephfs/%s/quota?path=%s", fsId, path)
|
||||
params := map[string]interface{}{}
|
||||
if maxFiles > 0 {
|
||||
params["max_files"] = fmt.Sprintf("%d", maxFiles)
|
||||
}
|
||||
if maxGb > 0 {
|
||||
params["max_bytes"] = fmt.Sprintf("%d", maxGb*1024*1024*1024)
|
||||
}
|
||||
_, err := cli.put(res, params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *SCephFSClient) GetCephDirs(fsId string) ([]SCephFsDir, error) {
|
||||
res := fmt.Sprintf("cephfs/%s/ls_dir", fsId)
|
||||
params := url.Values{}
|
||||
@@ -108,6 +139,9 @@ func (cli *SCephFSClient) GetCephDirs(fsId string) ([]SCephFsDir, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range ret {
|
||||
ret[i].client = cli
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -118,7 +152,6 @@ func (cli *SCephFSClient) GetICloudFileSystems() ([]cloudprovider.ICloudFileSyst
|
||||
}
|
||||
ret := []cloudprovider.ICloudFileSystem{}
|
||||
for i := range dirs {
|
||||
dirs[i].client = cli
|
||||
ret = append(ret, &dirs[i])
|
||||
}
|
||||
return ret, nil
|
||||
@@ -130,7 +163,6 @@ func (cli *SCephFSClient) GetICloudFileSystemById(id string) (cloudprovider.IClo
|
||||
return nil, err
|
||||
}
|
||||
for i := range dirs {
|
||||
dirs[i].client = cli
|
||||
if dirs[i].GetGlobalId() == id {
|
||||
return &dirs[i], nil
|
||||
}
|
||||
@@ -152,20 +184,11 @@ func (cli *SCephFSClient) DeleteDir(fsId, path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *SCephFSClient) SetDirQuota(fsId, path string, maxBytes int64) error {
|
||||
res := fmt.Sprintf("cephfs/%s/quota", fsId)
|
||||
_, err := cli.put(res, map[string]interface{}{
|
||||
"path": fmt.Sprintf("/%s", strings.TrimPrefix(path, "/")),
|
||||
"max_bytes": maxBytes,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *SCephFSClient) CreateICloudFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (cloudprovider.ICloudFileSystem, error) {
|
||||
err := cli.CreateDir(cli.fsId, opts.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cli.SetDirQuota(cli.fsId, opts.Name, opts.Capacity*1024*1024*1024)
|
||||
cli.SetQuota(cli.fsId, opts.Name, opts.Capacity, 0)
|
||||
return cli.GetICloudFileSystemById("/" + opts.Name)
|
||||
}
|
||||
|
||||
+9
@@ -14,7 +14,16 @@
|
||||
|
||||
package multicloud
|
||||
|
||||
import (
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SNasBase struct {
|
||||
SVirtualResourceBase
|
||||
SBillingBase
|
||||
}
|
||||
|
||||
func (self *SNasBase) SetQuota(input *cloudprovider.SFileSystemSetQuotaInput) error {
|
||||
return errors.Wrapf(cloudprovider.ErrNotImplemented, "SetQuota")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user