diff --git a/cmd/climc/shell/compute/disks.go b/cmd/climc/shell/compute/disks.go index e8328e8dd0..9f766d0505 100644 --- a/cmd/climc/shell/compute/disks.go +++ b/cmd/climc/shell/compute/disks.go @@ -45,6 +45,7 @@ func init() { cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{}) cmd.Perform("rebuild", &options.ResourceIdOptions{}) cmd.Perform("migrate", &compute_options.DiskMigrateOptions{}) + cmd.Perform("change-billing-type", new(compute_options.DiskChangeBillingTypeOptions)) type DiskDetailOptions struct { ID string `help:"ID or Name of disk"` diff --git a/go.mod b/go.mod index e5446a15c9..0880b8191e 100644 --- a/go.mod +++ b/go.mod @@ -87,14 +87,14 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250508131448-6abefa38df57 + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020440-3208a31b1fb6 yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256 yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1 yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91 yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 - yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281 + yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 - yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b + yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c ) diff --git a/go.sum b/go.sum index 4125d73b23..569e8e5fa4 100644 --- a/go.sum +++ b/go.sum @@ -1274,8 +1274,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.20250508131448-6abefa38df57 h1:pTIqSYPPDuWsgYJ6zl9kjNNYyvrfDfySRp+2kmlcF/k= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250508131448-6abefa38df57/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020440-3208a31b1fb6 h1:1E5vx3mqSlQEXEiKaurZdHi7duvQ5nyJGGLa8oN3oi0= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020440-3208a31b1fb6/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ= yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256 h1:kLKQ6zbgPDQflRwoHFAjxNChcbhXIFgsUVLkJwiXu/8= yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= @@ -1289,11 +1289,11 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc= yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= -yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281 h1:P22/MaBc9bqE9DyHvS3oQjc4XsaIEbIVGMLdTSroDew= -yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM= +yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e h1:OiBxJR18bq5fFK/IZWYRX+5HTMs2KgQJe0a3BZfdIVU= +yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM= yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4= yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b h1:VDSvBxXEcrac4pw9+fHP17XXPZNgHzkUPxtGDNx518M= -yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A= +yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a h1:mDW1VyYJxZ4ORITZGDWacUiBNyqX6rMObnQk77NvUOg= +yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A= yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ= yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/pkg/apis/compute/disk.go b/pkg/apis/compute/disk.go index e44494fef7..aa26f89544 100644 --- a/pkg/apis/compute/disk.go +++ b/pkg/apis/compute/disk.go @@ -340,3 +340,11 @@ type DiskSnapshotpolicyInput struct { } type DiskRebuildInput struct{} + +type DiskChangeBillingTypeInput struct { + // 仅在磁盘挂载在虚拟机上时调用 + // 目前支持阿里云 + // enmu: [postpaid, prepaid] + // required: true + BillingType string `json:"billing_type"` +} diff --git a/pkg/apis/compute/guest_const.go b/pkg/apis/compute/guest_const.go index 421e5dc5ab..849f166780 100644 --- a/pkg/apis/compute/guest_const.go +++ b/pkg/apis/compute/guest_const.go @@ -178,10 +178,6 @@ const ( VM_QGA_SET_NETWORK = "qga_set_network" VM_QGA_SET_NETWORK_FAILED = "qga_set_network_failed" - // 更改计费模式 - VM_CHANGE_BILLING_TYPE = "change_billing_type" - VM_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed" - SHUTDOWN_STOP = "stop" SHUTDOWN_TERMINATE = "terminate" diff --git a/pkg/apis/const.go b/pkg/apis/const.go index 2aeb25745d..5de084c2ed 100644 --- a/pkg/apis/const.go +++ b/pkg/apis/const.go @@ -58,6 +58,10 @@ const ( STATUS_AVAILABLE = "available" STATUS_CREATE_FAILED = "create_failed" + // 更改计费模式 + STATUS_CHANGE_BILLING_TYPE = "change_billing_type" + STATUS_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed" + CLOUD_TAG_PREFIX = "ext:" USER_TAG_PREFIX = "user:" SYS_CLOUD_TAG_PREFIX = "sys:" diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 1782c8a5ba..7e92c0b340 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -479,7 +479,7 @@ func (drv *SManagedVirtualizedGuestDriver) RequestStartOnHost(ctx context.Contex if guest.BillingType == billing_api.BILLING_TYPE_POSTPAID && jsonutils.QueryBoolean(task.GetParams(), "auto_prepaid", false) { err = ivm.ChangeBillingType(billing_api.BILLING_TYPE_PREPAID) if err != nil && errors.Cause(err) != cloudprovider.ErrNotImplemented { - logclient.AddSimpleActionLog(guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_PREPAID), userCred, false) + logclient.AddSimpleActionLog(guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_PREPAID), userCred, false) } } @@ -949,7 +949,7 @@ func (drv *SManagedVirtualizedGuestDriver) RequestStopOnHost(ctx context.Context if opts.StopCharging && guest.BillingType == billing_api.BILLING_TYPE_PREPAID { err = ivm.ChangeBillingType(billing_api.BILLING_TYPE_POSTPAID) if err != nil && errors.Cause(err) != cloudprovider.ErrNotImplemented { - logclient.AddSimpleActionLog(guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_POSTPAID), task.GetUserCred(), false) + logclient.AddSimpleActionLog(guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_POSTPAID), task.GetUserCred(), false) } } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 6fdb1ca2fb..e487d11499 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -3166,3 +3166,29 @@ func (disk *SDisk) PerformRebuild( disk.SetStatus(ctx, userCred, api.DISK_REBUILD, "disk rebuild") return nil, disk.StartDiskCreateTask(ctx, userCred, true, disk.SnapshotId, "") } + +func (disk *SDisk) PerformChangeBillingType(ctx context.Context, userCred mcclient.TokenCredential, _ jsonutils.JSONObject, input *api.DiskChangeBillingTypeInput) (jsonutils.JSONObject, error) { + if !utils.IsInStringArray(disk.Status, []string{api.DISK_READY}) { + return nil, httperrors.NewServerStatusError("Cannot change disk billing type in status %s", disk.Status) + } + if len(input.BillingType) == 0 { + return nil, httperrors.NewMissingParameterError("billing_type") + } + if !utils.IsInStringArray(input.BillingType, []string{billing_api.BILLING_TYPE_POSTPAID, billing_api.BILLING_TYPE_PREPAID}) { + return nil, httperrors.NewInputParameterError("invalid billing_type %s", input.BillingType) + } + if disk.BillingType == input.BillingType { + return nil, nil + } + return nil, disk.StartChangeBillingTypeTask(ctx, userCred, "") +} + +func (disk *SDisk) StartChangeBillingTypeTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + disk.SetStatus(ctx, userCred, apis.STATUS_CHANGE_BILLING_TYPE, "") + kwargs := jsonutils.NewDict() + task, err := taskman.TaskManager.NewTask(ctx, "DiskChangeBillingTypeTask", disk, userCred, kwargs, parentTaskId, "", nil) + if err != nil { + return err + } + return task.ScheduleRun(nil) +} diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 59d160170b..60e5baef81 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -6309,7 +6309,7 @@ func (g *SGuest) PerformChangeBillingType(ctx context.Context, userCred mcclient } func (self *SGuest) StartChangeBillingTypeTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { - self.SetStatus(ctx, userCred, api.VM_CHANGE_BILLING_TYPE, "") + self.SetStatus(ctx, userCred, apis.STATUS_CHANGE_BILLING_TYPE, "") kwargs := jsonutils.NewDict() task, err := taskman.TaskManager.NewTask(ctx, "GuestChangeBillingTypeTask", self, userCred, kwargs, parentTaskId, "", nil) if err != nil { diff --git a/pkg/compute/tasks/disk_change_billing_type_task.go b/pkg/compute/tasks/disk_change_billing_type_task.go new file mode 100644 index 0000000000..173e568408 --- /dev/null +++ b/pkg/compute/tasks/disk_change_billing_type_task.go @@ -0,0 +1,95 @@ +// 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" + "time" + + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + "yunion.io/x/onecloud/pkg/apis" + billing_api "yunion.io/x/onecloud/pkg/apis/billing" + 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 DiskChangeBillingTypeTask struct { + SDiskBaseTask +} + +func init() { + taskman.RegisterTask(DiskChangeBillingTypeTask{}) +} + +func (self *DiskChangeBillingTypeTask) 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 + } + + billType := "" + switch disk.BillingType { + case billing_api.BILLING_TYPE_POSTPAID: + billType = billing_api.BILLING_TYPE_PREPAID + case billing_api.BILLING_TYPE_PREPAID: + billType = billing_api.BILLING_TYPE_POSTPAID + } + + err = idisk.ChangeBillingType(billType) + if err != nil { + if errors.Cause(err) == cloudprovider.ErrNotImplemented { + disk.SetStatus(ctx, self.GetUserCred(), api.DISK_READY, "") + self.SetStageComplete(ctx, nil) + return + } + self.taskFail(ctx, disk, errors.Wrapf(err, "ChangeBillingType")) + return + } + + idisk.Refresh() + + db.Update(disk, func() error { + disk.BillingType = billType + disk.ExpiredAt = time.Time{} + if disk.BillingType == billing_api.BILLING_TYPE_PREPAID { + disk.AutoRenew = idisk.IsAutoRenew() + disk.ExpiredAt = idisk.GetExpiredAt() + } + return nil + }) + + self.taskComplete(ctx, disk) +} + +func (self *DiskChangeBillingTypeTask) taskComplete(ctx context.Context, disk *models.SDisk) { + disk.SetStatus(ctx, self.GetUserCred(), api.DISK_READY, "") + logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CHANGE_BILLING_TYPE, disk.BillingType, self.UserCred, true) + self.SetStageComplete(ctx, nil) +} + +func (self *DiskChangeBillingTypeTask) taskFail(ctx context.Context, disk *models.SDisk, err error) { + disk.SetStatus(ctx, self.GetUserCred(), apis.STATUS_CHANGE_BILLING_TYPE_FAILED, "") + logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CHANGE_BILLING_TYPE, err, self.UserCred, false) + self.SetStageFailed(ctx, jsonutils.NewString(err.Error())) +} diff --git a/pkg/compute/tasks/guest_change_billing_type_task.go b/pkg/compute/tasks/guest_change_billing_type_task.go index 26b74f565e..07441785c8 100644 --- a/pkg/compute/tasks/guest_change_billing_type_task.go +++ b/pkg/compute/tasks/guest_change_billing_type_task.go @@ -19,7 +19,7 @@ import ( "yunion.io/x/jsonutils" - api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/apis" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" @@ -45,12 +45,12 @@ func (self *GuestChangeBillingTypeTask) OnInit(ctx context.Context, obj db.IStan } func (self *GuestChangeBillingTypeTask) OnGuestChangeBillingTypeTaskComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { - logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, guest.BillingType, self.UserCred, false) + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_CHANGE_BILLING_TYPE, guest.BillingType, self.UserCred, false) self.SetStageComplete(ctx, nil) } func (self *GuestChangeBillingTypeTask) OnGuestChangeBillingTypeTaskCompleteFailed(ctx context.Context, guest *models.SGuest, reason jsonutils.JSONObject) { - guest.SetStatus(ctx, self.GetUserCred(), api.VM_CHANGE_BILLING_TYPE_FAILED, "") - logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, reason.String(), self.UserCred, false) + guest.SetStatus(ctx, self.GetUserCred(), apis.STATUS_CHANGE_BILLING_TYPE_FAILED, "") + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_CHANGE_BILLING_TYPE, reason.String(), self.UserCred, false) self.SetStageFailed(ctx, reason) } diff --git a/pkg/compute/tasks/guest_create_disk_task.go b/pkg/compute/tasks/guest_create_disk_task.go index bbf36f0f83..85dd82bfc6 100644 --- a/pkg/compute/tasks/guest_create_disk_task.go +++ b/pkg/compute/tasks/guest_create_disk_task.go @@ -24,10 +24,12 @@ import ( "yunion.io/x/log" "yunion.io/x/pkg/errors" + billing_api "yunion.io/x/onecloud/pkg/apis/billing" 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 GuestCreateDiskTask struct { @@ -206,12 +208,12 @@ func (self *ManagedGuestCreateDiskTask) OnManagedDiskPrepared(ctx context.Contex for _, d := range disks { diskId := d.DiskId - iDisk, err := models.DiskManager.FetchById(diskId) + _disk, err := models.DiskManager.FetchById(diskId) if err != nil { self.SetStageFailed(ctx, jsonutils.NewString(err.Error())) return } - disk := iDisk.(*models.SDisk) + disk := _disk.(*models.SDisk) if disk.Status != api.DISK_READY { self.SetStageFailed(ctx, jsonutils.NewString(fmt.Sprintf("disk %s is not ready(status=%s)", disk.Id, disk.Status))) return @@ -235,7 +237,28 @@ func (self *ManagedGuestCreateDiskTask) OnManagedDiskPrepared(ctx context.Contex self.SetStageFailed(ctx, jsonutils.NewString(fmt.Sprintf("Attach Disk to guest fail error: %v", err))) return } + time.Sleep(time.Second * 5) + + if guest.BillingType == billing_api.BILLING_TYPE_PREPAID { + idisk, err := disk.GetIDisk(ctx) + if err != nil { + if errors.Cause(err) != cloudprovider.ErrNotFound { + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, "GetIDisk %s", disk.ExternalId), self.UserCred, false) + continue + } + } + err = idisk.ChangeBillingType(guest.BillingType) + if err != nil { + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, "ChangeBillingType %s", disk.ExternalId), self.UserCred, false) + continue + } + + db.Update(disk, func() error { + disk.BillingType = guest.BillingType + return nil + }) + } } self.SetStageComplete(ctx, nil) diff --git a/pkg/mcclient/options/compute/disks.go b/pkg/mcclient/options/compute/disks.go index 89f2925a4e..2bb193d884 100644 --- a/pkg/mcclient/options/compute/disks.go +++ b/pkg/mcclient/options/compute/disks.go @@ -127,3 +127,16 @@ func (opts *DiskListOptions) Params() (jsonutils.JSONObject, error) { } return params, nil } + +type DiskChangeBillingTypeOptions struct { + ID string + BillingType string `choices:"prepaid|postpaid"` +} + +func (o *DiskChangeBillingTypeOptions) GetId() string { + return o.ID +} + +func (o *DiskChangeBillingTypeOptions) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(map[string]string{"billing_type": o.BillingType}), nil +} diff --git a/pkg/util/logclient/consts.go b/pkg/util/logclient/consts.go index e322837a7a..30af707330 100644 --- a/pkg/util/logclient/consts.go +++ b/pkg/util/logclient/consts.go @@ -74,7 +74,6 @@ const ( ACT_VM_SETSECGROUP = "vm_setsecgroup" ACT_VM_CPUSET = "vm_cpuset" ACT_VM_CPUSET_REMOVE = "vm_cpuset_remove" - ACT_VM_CHANGE_BILLING_TYPE = "vm_change_billing_type" ACT_RESET_DISK = "reset_disk" ACT_SYNC_STATUS = "sync_status" ACT_SYNC_CONF = "sync_conf" @@ -112,6 +111,7 @@ const ( ACT_VM_CONVERT = "vm_convert" ACT_FREEZE = "freeze" ACT_UNFREEZE = "unfreeze" + ACT_CHANGE_BILLING_TYPE = "change_billing_type" // 到期释放 ACT_SET_EXPIRED_TIME = "set_expired_time" ACT_VM_SYNC_ISOLATED_DEVICE = "vm_sync_isolated_device" diff --git a/pkg/util/logclient/consts_i18n.go b/pkg/util/logclient/consts_i18n.go index 6fced7f036..37ba442d31 100644 --- a/pkg/util/logclient/consts_i18n.go +++ b/pkg/util/logclient/consts_i18n.go @@ -1533,7 +1533,7 @@ func init() { EN("Set Commit Bound"). CN("设置超售比"), ) - o.Set(ACT_VM_CHANGE_BILLING_TYPE, i18n.NewTableEntry(). + o.Set(ACT_CHANGE_BILLING_TYPE, i18n.NewTableEntry(). EN("Change Billing Type"). CN("更改计费模式"), ) diff --git a/vendor/modules.txt b/vendor/modules.txt index 3b019eaa55..be94776cf9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1576,7 +1576,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.20250508131448-6abefa38df57 +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020440-3208a31b1fb6 ## explicit; go 1.21 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing @@ -1671,7 +1671,7 @@ yunion.io/x/log/hooks yunion.io/x/ovsdb/cli_util yunion.io/x/ovsdb/schema/ovn_nb yunion.io/x/ovsdb/types -# yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281 +# yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e ## explicit; go 1.18 yunion.io/x/pkg/appctx yunion.io/x/pkg/errors @@ -1725,7 +1725,7 @@ yunion.io/x/pkg/utils # yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 ## explicit; go 1.12 yunion.io/x/s3cli -# yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b +# yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a ## explicit; go 1.17 yunion.io/x/sqlchemy yunion.io/x/sqlchemy/backends diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go index 6f4522a650..347ead10d4 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/disk.go @@ -24,6 +24,7 @@ import ( "yunion.io/x/pkg/errors" "yunion.io/x/pkg/utils" + billing_api "yunion.io/x/cloudmux/pkg/apis/billing" api "yunion.io/x/cloudmux/pkg/apis/compute" "yunion.io/x/cloudmux/pkg/cloudprovider" "yunion.io/x/cloudmux/pkg/multicloud" @@ -159,6 +160,27 @@ func (self *SDisk) Resize(ctx context.Context, sizeMb int64) error { return self.storage.zone.region.resizeDisk(self.DiskId, sizeMb) } +func (self *SDisk) ChangeBillingType(billingType string) error { + return self.storage.zone.region.ChangeDiskChargeType(self.InstanceId, self.DiskId, billingType) +} + +func (self *SRegion) ChangeDiskChargeType(vmId, diskId string, billingType string) error { + params := make(map[string]string) + params["RegionId"] = self.RegionId + params["DiskIds"] = jsonutils.Marshal([]string{diskId}).String() + switch billingType { + case billing_api.BILLING_TYPE_POSTPAID: + params["DiskChargeType"] = "PostPaid" + case billing_api.BILLING_TYPE_PREPAID: + params["DiskChargeType"] = "PrePaid" + } + params["AutoPay"] = "true" + params["ClientToken"] = utils.GenRequestId(20) + params["InstanceId"] = vmId + _, err := self.ecsRequest("ModifyDiskChargeType", params) + return err +} + func (self *SDisk) GetName() string { if len(self.DiskName) > 0 { return self.DiskName diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/image.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/image.go index d385ce2c7d..2db8010131 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/image.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/image.go @@ -252,7 +252,7 @@ func (self *SImage) GetSizeByte() int64 { func (self *SImage) getNormalizedImageInfo() *imagetools.ImageInfo { if self.imgInfo == nil { name := self.ImageName - if len(self.Description) > 0 { + if len(self.Description) > 0 && self.GetImageType() != cloudprovider.ImageTypeCustomized { name = self.Description } imgInfo := imagetools.NormalizeImageInfo(name, self.Architecture, getImageOSType(*self), getImageOSDist(*self), getImageOSVersion(*self)) diff --git a/vendor/yunion.io/x/pkg/util/imagetools/imagetools.go b/vendor/yunion.io/x/pkg/util/imagetools/imagetools.go index 3461d6ae13..317c318ec9 100644 --- a/vendor/yunion.io/x/pkg/util/imagetools/imagetools.go +++ b/vendor/yunion.io/x/pkg/util/imagetools/imagetools.go @@ -183,7 +183,7 @@ var imageVersions = map[string][]string{ OS_DIST_ALIBABA_CLOUD_LINUX: {"2.1903", "3.2104"}, OS_DIST_ANOLIS: {"7.9", "8.2", "8.4"}, - OS_DIST_ROCKY_LINUX: {"8.5", "8.6", "8.7", "8.8", "8.9", "8.10", "9.0", "9.1", "9.2", "9.3", "9.4"}, + OS_DIST_ROCKY_LINUX: {"8.5", "8.6", "8.7", "8.8", "8.9", "8.10", "9.0", "9.1", "9.2", "9.3", "9.4", "9.5"}, OS_DIST_FEDORA: {"33", "34", "35"}, OS_DIST_ALMA_LINUX: {"8.5"}, OS_DIST_AMAZON_LINUX: {"2023", "2"}, diff --git a/vendor/yunion.io/x/sqlchemy/column.go b/vendor/yunion.io/x/sqlchemy/column.go index 0f68809044..154692763c 100644 --- a/vendor/yunion.io/x/sqlchemy/column.go +++ b/vendor/yunion.io/x/sqlchemy/column.go @@ -423,5 +423,8 @@ func (c *SBaseCompoundColumn) ConvertFromValue(val interface{}) interface{} { if ok && bVal != nil { return bVal.String() } + if _, ok := val.(string); ok { + return val + } return jsonutils.Marshal(val).String() }