fix(region): cephfs set quota (#21482)

This commit is contained in:
屈轩
2024-10-28 18:20:51 +08:00
committed by GitHub
parent 895e6f8318
commit 2229f7c956
13 changed files with 179 additions and 20 deletions
+1
View File
@@ -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{})
}
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
+5
View File
@@ -114,3 +114,8 @@ type FileSystemRemoteUpdateInput struct {
// 是否覆盖替换所有标签
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
}
type FileSystemSetQuotaInput struct {
MaxGb *int64
MaxFiles *int64
}
+27
View File
@@ -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 {
+1 -2
View File
@@ -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
}
+1 -1
View File
@@ -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
View File
@@ -21,3 +21,8 @@ type SMountTargetCreateOptions struct {
NetworkId string
FileSystemId string
}
type SFileSystemSetQuotaInput struct {
MaxFiles int64
MaxGb int64
}
+2
View File
@@ -1402,6 +1402,8 @@ type ICloudFileSystem interface {
GetMountTargets() ([]ICloudMountTarget, error)
CreateMountTarget(opts *SMountTargetCreateOptions) (ICloudMountTarget, error)
SetQuota(input *SFileSystemSetQuotaInput) error
Delete() error
}
+37 -14
View File
@@ -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
View File
@@ -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")
}