mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix(region): change config stop options check (#25285)
This commit is contained in:
@@ -890,8 +890,9 @@ type ServerChangeConfigInput struct {
|
||||
// 内存大小, 1024M, 1G
|
||||
VmemSize string `json:"vmem_size"`
|
||||
|
||||
// 是否强制关机
|
||||
// 若虚拟机不支持开机调整配置, 则需要指定此参数为true, 强制关机后, 再调整配置, 再启动虚拟机
|
||||
// 是否允许强制关机
|
||||
// 仅当虚拟机不支持开机调整配置, 或开机状态下降配(降低CPU/内存), 或ARM架构时时生效: 需指定为true以允许强制关机后再调整配置并启动;
|
||||
// 若已支持开机变配, 即使传入该参数也不会强制关机
|
||||
ForceStop bool `json:"force_stop"`
|
||||
|
||||
// 调整完配置后是否自动启动
|
||||
@@ -1512,6 +1513,8 @@ type ServerChangeConfigSettings struct {
|
||||
|
||||
AutoStart bool `json:"auto_start"`
|
||||
GuestOnline bool `json:"guest_online"`
|
||||
// 需要强制关机后再调整配置(仅不支持在线变配/降配时为true), 并在完成后自动启动
|
||||
ForceStop bool `json:"force_stop"`
|
||||
|
||||
// 设置虚拟网卡的流量上限
|
||||
SetTrafficLimits []ServerNicTrafficLimit `json:"set_traffic_limits"`
|
||||
@@ -1525,6 +1528,10 @@ func (conf ServerChangeConfigSettings) CpuChanged() bool {
|
||||
return conf.VcpuCount != conf.Old.VcpuCount
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) CpuReduced() bool {
|
||||
return conf.VcpuCount < conf.Old.VcpuCount
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) AddedCpu() int {
|
||||
addCpu := conf.VcpuCount - conf.Old.VcpuCount
|
||||
if addCpu < 0 {
|
||||
@@ -1537,6 +1544,10 @@ func (conf ServerChangeConfigSettings) ExtraCpuChanged() bool {
|
||||
return conf.ExtraCpuCount != conf.Old.ExtraCpuCount
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) ExtraCpuReduced() bool {
|
||||
return conf.ExtraCpuCount < conf.Old.ExtraCpuCount
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) AddedExtraCpu() int {
|
||||
addCpu := conf.ExtraCpuCount - conf.Old.ExtraCpuCount
|
||||
if addCpu < 0 {
|
||||
@@ -1549,6 +1560,10 @@ func (conf ServerChangeConfigSettings) MemChanged() bool {
|
||||
return conf.VmemSize != conf.Old.VmemSize
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) MemReduced() bool {
|
||||
return conf.VmemSize < conf.Old.VmemSize
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) InstanceTypeChanged() bool {
|
||||
return len(conf.InstanceType) > 0 && conf.InstanceType != conf.Old.InstanceType
|
||||
}
|
||||
@@ -1561,6 +1576,11 @@ func (conf ServerChangeConfigSettings) AddedMem() int {
|
||||
return addMem
|
||||
}
|
||||
|
||||
// ConfigReduced 是否为降配(降低CPU/内存)
|
||||
func (conf ServerChangeConfigSettings) ConfigReduced() bool {
|
||||
return conf.CpuReduced() || conf.MemReduced() || conf.ExtraCpuReduced()
|
||||
}
|
||||
|
||||
func (conf ServerChangeConfigSettings) AddedDisk() int {
|
||||
var size int
|
||||
for _, resize := range conf.Resize {
|
||||
|
||||
@@ -87,6 +87,10 @@ func (self *SBaremetalGuestDriver) GetMaxSecurityGroupCount() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) AllowReconfigGuest() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetMaxVCpuCount() int {
|
||||
return 1024
|
||||
}
|
||||
|
||||
@@ -91,6 +91,10 @@ func (self *SBingoCloudGuestDriver) GetDeployStatus() ([]string, error) {
|
||||
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
||||
}
|
||||
|
||||
func (self *SBingoCloudGuestDriver) AllowReconfigGuest() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBingoCloudGuestDriver) GetDefaultSysDiskBackend() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ func (self *SCNwareGuestDriver) GetInstanceCapability() cloudprovider.SInstanceC
|
||||
}
|
||||
|
||||
func (self *SCNwareGuestDriver) AllowReconfigGuest() bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SCNwareGuestDriver) IsSupportEip() bool {
|
||||
|
||||
@@ -1187,35 +1187,6 @@ func (drv *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Con
|
||||
instanceType = sku.Name
|
||||
}
|
||||
|
||||
drv, err := guest.GetDriver()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetDriver")
|
||||
}
|
||||
|
||||
runningOk, err := drv.IsChangeInstanceTypeWhileRunningSupported(guest)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "IsChangeInstanceTypeWhileRunningSupported")
|
||||
}
|
||||
|
||||
needStart := false
|
||||
|
||||
if !runningOk {
|
||||
status := iVM.GetStatus()
|
||||
if status == api.VM_RUNNING {
|
||||
err = iVM.StopVM(ctx, &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "StopVM")
|
||||
}
|
||||
err = cloudprovider.WaitStatus(iVM, api.VM_READY, time.Second*5, time.Minute*10)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "WaitStatus")
|
||||
}
|
||||
needStart = true
|
||||
}
|
||||
}
|
||||
|
||||
config := &cloudprovider.SManagedVMChangeConfig{
|
||||
Cpu: int(vcpuCount),
|
||||
CpuSocket: int(cpuSockets),
|
||||
@@ -1261,17 +1232,6 @@ func (drv *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Con
|
||||
}
|
||||
}
|
||||
|
||||
if needStart {
|
||||
err = iVM.StartVM(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "StartVM")
|
||||
}
|
||||
err = cloudprovider.WaitStatus(iVM, api.VM_RUNNING, time.Second*5, time.Minute*10)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "WaitStatus")
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ func (self *SRemoteFileGuestDriver) GetComputeQuotaKeys(scope rbacscope.TRbacSco
|
||||
return keys
|
||||
}
|
||||
|
||||
func (self *SRemoteFileGuestDriver) AllowReconfigGuest() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SRemoteFileGuestDriver) GetDefaultSysDiskBackend() string {
|
||||
return api.STORAGE_LOCAL
|
||||
}
|
||||
|
||||
@@ -3543,6 +3543,16 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in status %s", self.Status)
|
||||
}
|
||||
|
||||
if self.RescueMode {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in rescue mode")
|
||||
}
|
||||
|
||||
// 停止计费模式下, 不允许调整配置
|
||||
if len(self.ExternalId) > 0 && self.ShutdownMode == api.VM_SHUTDOWN_MODE_STOP_CHARGING && self.Status == api.VM_READY {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in ready status when shutdown mode is stop charging")
|
||||
}
|
||||
|
||||
driver, err := self.GetDriver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -3570,12 +3580,20 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !runningOk && !input.ForceStop {
|
||||
// 仅在不支持开机变配, 或开机降配时需要强制关机,或ARM架构时需要强制关机; force_stop 表示允许关机, 而非一定关机
|
||||
needForceStop := !runningOk || confs.ConfigReduced() || apis.IsARM(self.OsArch)
|
||||
if needForceStop && !input.ForceStop {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in %s for %s, requires force_stop to change config", self.Status, self.GetHypervisor())
|
||||
}
|
||||
if needForceStop {
|
||||
// 走离线变配路径, 变配完成后自动启动
|
||||
confs.ForceStop = true
|
||||
confs.GuestOnline = false
|
||||
confs.AutoStart = true
|
||||
}
|
||||
}
|
||||
|
||||
if self.PowerStates == api.VM_POWER_STATES_ON && (confs.CpuChanged() || confs.MemChanged()) {
|
||||
if self.PowerStates == api.VM_POWER_STATES_ON && (confs.CpuChanged() || confs.MemChanged()) && !confs.ForceStop {
|
||||
confs, err = driver.ValidateGuestHotChangeConfigInput(ctx, self, confs)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot change CPU/Memory spec in power status %s: %s", self.PowerStates, err)
|
||||
|
||||
@@ -235,6 +235,15 @@ func (task *GuestChangeConfigTask) OnCreateDisksComplete(ctx context.Context, ob
|
||||
}
|
||||
|
||||
if confs.CpuChanged() || confs.MemChanged() || (drv.DoScheduleSKUFilter() && confs.InstanceTypeChanged()) {
|
||||
// Status is already VM_CHANGE_FLAVOR; ForceStop means guest was running and needs offline change.
|
||||
if confs.ForceStop {
|
||||
task.SetStage("OnGuestStopForChangeConfigComplete", nil)
|
||||
err = guest.StartGuestStopTask(ctx, task.UserCred, 60, true, false, task.GetTaskId())
|
||||
if err != nil {
|
||||
task.markStageFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
task.SetStage("OnGuestChangeCpuMemSpecComplete", nil)
|
||||
task.startGuestChangeCpuMemSpec(ctx, guest, confs.InstanceType, confs.VcpuCount, confs.CpuSockets, confs.VmemSize)
|
||||
} else {
|
||||
@@ -242,6 +251,23 @@ func (task *GuestChangeConfigTask) OnCreateDisksComplete(ctx context.Context, ob
|
||||
}
|
||||
}
|
||||
|
||||
func (task *GuestChangeConfigTask) OnGuestStopForChangeConfigComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
|
||||
confs, err := task.getChangeConfigSetting()
|
||||
if err != nil {
|
||||
task.markStageFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
task.SetStage("OnGuestChangeCpuMemSpecComplete", nil)
|
||||
task.startGuestChangeCpuMemSpec(ctx, guest, confs.InstanceType, confs.VcpuCount, confs.CpuSockets, confs.VmemSize)
|
||||
}
|
||||
|
||||
func (task *GuestChangeConfigTask) OnGuestStopForChangeConfigCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
task.markStageFailed(ctx, obj.(*models.SGuest), data)
|
||||
}
|
||||
|
||||
func (task *GuestChangeConfigTask) startGuestChangeCpuMemSpec(ctx context.Context, guest *models.SGuest, instanceType string, vcpuCount, cpuSockets int, vmemSize int) {
|
||||
drv, err := guest.GetDriver()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user