mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 21:52:54 +08:00
fix(region): support change storage type (#23529)
This commit is contained in:
@@ -47,6 +47,7 @@ func init() {
|
||||
cmd.Perform("migrate", &compute_options.DiskMigrateOptions{})
|
||||
cmd.Perform("reset-template", &compute_options.DiskResetTemplateOptions{})
|
||||
cmd.Perform("change-billing-type", new(compute_options.DiskChangeBillingTypeOptions))
|
||||
cmd.Perform("change-storage-type", &compute_options.DiskChangeStorageTypeOptions{})
|
||||
|
||||
type DiskDetailOptions struct {
|
||||
ID string `help:"ID or Name of disk"`
|
||||
|
||||
2
go.mod
2
go.mod
@@ -97,7 +97,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.20251013100607-3a8dc1b149ab
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251014082718-119f8d6bfa32
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1470,8 +1470,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.20251013100607-3a8dc1b149ab h1:4PW8f9gW2eoxPTSpdFAJkzskIElTWN4NkRi7gA68GK8=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251013100607-3a8dc1b149ab/go.mod h1:qn8eC11Gn4/41YJRzQcwB/G1Z3rQRxRrDNC8LDvQR48=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251014082718-119f8d6bfa32 h1:tSXqxkX61bmo65YYm0JS9CGDtoOi9WEHM4OCLZBpmGo=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251014082718-119f8d6bfa32/go.mod h1:qn8eC11Gn4/41YJRzQcwB/G1Z3rQRxRrDNC8LDvQR48=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
|
||||
@@ -354,6 +354,11 @@ type DiskMigrateInput struct {
|
||||
TargetStorageId string `json:"target_storage_id"`
|
||||
}
|
||||
|
||||
type DiskChagneStorageTypeInput struct {
|
||||
// 目标存储类型
|
||||
StorageType string `json:"storage_type"`
|
||||
}
|
||||
|
||||
type DiskSnapshotpolicyInput struct {
|
||||
SnapshotpolicyId string `json:"snapshotpolicy_id"`
|
||||
}
|
||||
|
||||
@@ -1077,6 +1077,40 @@ func (self *SDisk) PerformMigrate(ctx context.Context, userCred mcclient.TokenCr
|
||||
return nil, task.ScheduleRun(nil)
|
||||
}
|
||||
|
||||
func (self *SDisk) PerformChangeStorageType(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.DiskChagneStorageTypeInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.StorageType) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("storage_type")
|
||||
}
|
||||
storage, err := self.GetStorage()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetStorage")
|
||||
}
|
||||
if storage.StorageType == input.StorageType {
|
||||
return nil, httperrors.NewInputParameterError("Storage type is already %s", input.StorageType)
|
||||
}
|
||||
storages := []SStorage{}
|
||||
q := StorageManager.Query().Equals("zone_id", storage.ZoneId).Equals("storage_type", input.StorageType).IsTrue("enabled").Equals("status", api.STORAGE_ONLINE).Equals("manager_id", storage.ManagerId)
|
||||
err = q.All(&storages)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CountWithError")
|
||||
}
|
||||
if len(storages) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("no available storage type %s to change", input.StorageType)
|
||||
}
|
||||
if len(storages) > 1 {
|
||||
return nil, httperrors.NewInputParameterError("duplicate storage type %s found", input.StorageType)
|
||||
}
|
||||
|
||||
self.SetStatus(ctx, userCred, api.DISK_MIGRATING, "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("storage_id", jsonutils.NewString(storages[0].Id))
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "DiskChangeStorageTypeTask", self, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewTask")
|
||||
}
|
||||
return nil, task.ScheduleRun(nil)
|
||||
}
|
||||
|
||||
func (self *SDisk) GetSchedMigrateParams(targetStorageId string) (*schedapi.ScheduleInput, error) {
|
||||
diskConfig := self.ToDiskConfig()
|
||||
diskConfig.Medium = ""
|
||||
|
||||
86
pkg/compute/tasks/disk/disk_change_storage_type_task.go
Normal file
86
pkg/compute/tasks/disk/disk_change_storage_type_task.go
Normal file
@@ -0,0 +1,86 @@
|
||||
// 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 disk
|
||||
|
||||
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"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type DiskChangeStorageTypeTask struct {
|
||||
SDiskBaseTask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(DiskChangeStorageTypeTask{})
|
||||
}
|
||||
|
||||
func (self *DiskChangeStorageTypeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
disk := obj.(*models.SDisk)
|
||||
|
||||
idisk, err := disk.GetIDisk(ctx)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, errors.Wrapf(err, "GetIDisk"))
|
||||
return
|
||||
}
|
||||
|
||||
storageId, err := self.GetParams().GetString("storage_id")
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, errors.Wrapf(err, "get storage_id"))
|
||||
return
|
||||
}
|
||||
|
||||
storageObj, err := models.StorageManager.FetchById(storageId)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, errors.Wrapf(err, "fetch storage by id"))
|
||||
return
|
||||
}
|
||||
storage := storageObj.(*models.SStorage)
|
||||
|
||||
opts := &cloudprovider.ChangeStorageOptions{
|
||||
DiskId: disk.ExternalId,
|
||||
StorageType: storage.StorageType,
|
||||
}
|
||||
|
||||
err = idisk.ChangeStorage(ctx, opts)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, errors.Wrapf(err, "ChangeStorage"))
|
||||
return
|
||||
}
|
||||
|
||||
db.Update(disk, func() error {
|
||||
disk.StorageId = storage.Id
|
||||
disk.Status = api.DISK_READY
|
||||
return nil
|
||||
})
|
||||
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_MIGRATE, opts.StorageType, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *DiskChangeStorageTypeTask) taskFail(ctx context.Context, disk *models.SDisk, err error) {
|
||||
disk.SetStatus(ctx, self.GetUserCred(), api.DISK_MIGRATE_FAIL, "")
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_MIGRATE, err, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
@@ -28,8 +28,7 @@ import (
|
||||
)
|
||||
|
||||
type SDisk struct {
|
||||
multicloud.SVirtualResourceBase
|
||||
multicloud.SBillingBase
|
||||
multicloud.SDisk
|
||||
CloudpodsTags
|
||||
region *SRegion
|
||||
|
||||
|
||||
@@ -92,6 +92,20 @@ func (o *DiskMigrateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.StructToParams(o)
|
||||
}
|
||||
|
||||
type DiskChangeStorageTypeOptions struct {
|
||||
ID string `help:"ID of the server" json:"-"`
|
||||
|
||||
StorageType string `help:"Disk migrate target storage type" json:"storage_type"`
|
||||
}
|
||||
|
||||
func (o *DiskChangeStorageTypeOptions) GetId() string {
|
||||
return o.ID
|
||||
}
|
||||
|
||||
func (o *DiskChangeStorageTypeOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.StructToParams(o)
|
||||
}
|
||||
|
||||
type DiskResetTemplateOptions struct {
|
||||
ID string `help:"ID of the server" json:"-"`
|
||||
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -2037,7 +2037,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.20251013100607-3a8dc1b149ab
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20251014082718-119f8d6bfa32
|
||||
## explicit; go 1.24
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
|
||||
5
vendor/yunion.io/x/cloudmux/pkg/cloudprovider/disk.go
generated
vendored
5
vendor/yunion.io/x/cloudmux/pkg/cloudprovider/disk.go
generated
vendored
@@ -26,3 +26,8 @@ type DiskCreateConfig struct {
|
||||
|
||||
Tags map[string]string
|
||||
}
|
||||
|
||||
type ChangeStorageOptions struct {
|
||||
StorageType string
|
||||
DiskId string
|
||||
}
|
||||
|
||||
1
vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go
generated
vendored
1
vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go
generated
vendored
@@ -573,6 +573,7 @@ type ICloudDisk interface {
|
||||
Rebuild(ctx context.Context) error
|
||||
|
||||
GetPreallocation() string
|
||||
ChangeStorage(ctx context.Context, opts *ChangeStorageOptions) error
|
||||
}
|
||||
|
||||
type ICloudSnapshot interface {
|
||||
|
||||
25
vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go
generated
vendored
25
vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go
generated
vendored
@@ -471,3 +471,28 @@ func (self *SRegion) rebuildDisk(diskId string) error {
|
||||
func (self *SDisk) GetProjectId() string {
|
||||
return self.ResourceGroupId
|
||||
}
|
||||
|
||||
func (region *SRegion) ChagneDiskStorage(ctx context.Context, opts *cloudprovider.ChangeStorageOptions) error {
|
||||
params := map[string]string{
|
||||
"DiskId": opts.DiskId,
|
||||
"DiskCategory": opts.StorageType,
|
||||
}
|
||||
switch opts.StorageType {
|
||||
case api.STORAGE_CLOUD_ESSD_PL0:
|
||||
params["DiskCategory"] = api.STORAGE_CLOUD_ESSD
|
||||
params["PerformanceLevel"] = "PL0"
|
||||
case api.STORAGE_CLOUD_ESSD_PL2:
|
||||
params["DiskCategory"] = api.STORAGE_CLOUD_ESSD
|
||||
params["PerformanceLevel"] = "PL2"
|
||||
case api.STORAGE_CLOUD_ESSD_PL3:
|
||||
params["DiskCategory"] = api.STORAGE_CLOUD_ESSD
|
||||
params["PerformanceLevel"] = "PL3"
|
||||
}
|
||||
_, err := region.ecsRequest("ModifyDiskSpec", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (disk *SDisk) ChangeStorage(ctx context.Context, opts *cloudprovider.ChangeStorageOptions) error {
|
||||
opts.DiskId = disk.DiskId
|
||||
return disk.storage.zone.region.ChagneDiskStorage(ctx, opts)
|
||||
}
|
||||
|
||||
14
vendor/yunion.io/x/cloudmux/pkg/multicloud/disk_base.go
generated
vendored
14
vendor/yunion.io/x/cloudmux/pkg/multicloud/disk_base.go
generated
vendored
@@ -15,7 +15,11 @@
|
||||
package multicloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SDisk struct {
|
||||
@@ -23,14 +27,18 @@ type SDisk struct {
|
||||
SBillingBase
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorageId() string {
|
||||
func (disk *SDisk) GetIStorageId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIops() int {
|
||||
func (disk *SDisk) GetIops() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SDisk) GetPreallocation() string {
|
||||
func (disk *SDisk) GetPreallocation() string {
|
||||
return api.DISK_PREALLOCATION_OFF
|
||||
}
|
||||
|
||||
func (disk *SDisk) ChangeStorage(ctx context.Context, opts *cloudprovider.ChangeStorageOptions) error {
|
||||
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ChangeStorage")
|
||||
}
|
||||
|
||||
5
vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/disk.go
generated
vendored
5
vendor/yunion.io/x/cloudmux/pkg/multicloud/remotefile/disk.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SDisk struct {
|
||||
@@ -134,3 +135,7 @@ func (self *SDisk) Rebuild(ctx context.Context) error {
|
||||
func (disk *SDisk) SetStorage(storage SStorage) {
|
||||
disk.storage = &storage
|
||||
}
|
||||
|
||||
func (disk *SDisk) ChangeStorage(ctx context.Context, opts *cloudprovider.ChangeStorageOptions) error {
|
||||
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ChangeStorage")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user