mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
fix(llm): harden volume resize and update size log (#24670)
- Wait for disk/desktop status after resize via backup worker - Centralize volume SizeMB update with resize action log - Expose vCPU/memory fields in LLM customize columns
This commit is contained in:
@@ -152,6 +152,7 @@ type LLMSkuBaseUpdateInput struct {
|
||||
|
||||
// RequstSyncImage *bool `json:"request_sync_image"`
|
||||
|
||||
DiskSize *int `json:"disk_size" yunion-deprecated-by:"disk_size_mb"`
|
||||
DiskSizeMB *int `json:"disk_size_mb"`
|
||||
TemplateId *string `json:"template_id"`
|
||||
StorageType *string `json:"storage_type"`
|
||||
|
||||
@@ -318,6 +318,8 @@ func (man *SLLMManager) FetchCustomizeColumns(
|
||||
res[i].HostEIP = guest.HostEIP
|
||||
res[i].Zone = guest.Zone
|
||||
res[i].ZoneId = guest.ZoneId
|
||||
res[i].VcpuCount = guest.VcpuCount
|
||||
res[i].VmemSizeMb = guest.VmemSize
|
||||
|
||||
adbMappedPort := -1
|
||||
// for j := range res[i].AccessInfo {
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/image"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -247,3 +248,27 @@ func (volume *SVolume) DoReset(ctx context.Context, userCred mcclient.TokenCrede
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (volume *SVolume) UpdateSize(ctx context.Context, userCred mcclient.TokenCredential, sizeMb int) error {
|
||||
if volume.SizeMB == sizeMb {
|
||||
return nil
|
||||
}
|
||||
oldSize := volume.SizeMB
|
||||
_, err := db.Update(volume, func() error {
|
||||
volume.SizeMB = sizeMb
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(volume, logclient.ACT_RESIZE, err, userCred, false)
|
||||
return errors.Wrap(err, "update volume size")
|
||||
}
|
||||
notes := struct {
|
||||
OldSizeMb int `json:"old_size_mb"`
|
||||
NewSizeMb int `json:"new_size_mb"`
|
||||
}{
|
||||
OldSizeMb: oldSize,
|
||||
NewSizeMb: sizeMb,
|
||||
}
|
||||
logclient.AddSimpleActionLog(volume, logclient.ACT_RESIZE, jsonutils.Marshal(notes), userCred, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
api "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
llmapi "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/llm/models"
|
||||
"yunion.io/x/onecloud/pkg/llm/tasks/worker"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
@@ -28,71 +28,66 @@ func init() {
|
||||
|
||||
func (task *VolumeResizeTask) taskFailed(ctx context.Context, volume *models.SVolume, err error) {
|
||||
volume.SetStatus(ctx, task.UserCred, computeapi.DISK_RESIZE_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(volume, "resize", err, task.UserCred)
|
||||
logclient.AddActionLogWithStartable(task, volume, "resize", err.Error(), task.UserCred, false)
|
||||
db.OpsLog.LogEvent(volume, db.ACT_RESIZE_FAIL, err, task.UserCred)
|
||||
logclient.AddActionLogWithStartable(task, volume, logclient.ACT_RESIZE, err.Error(), task.UserCred, false)
|
||||
task.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (task *VolumeResizeTask) taskComplete(ctx context.Context, volume *models.SVolume) {
|
||||
volume.SetStatus(ctx, task.UserCred, computeapi.DISK_READY, "")
|
||||
volume.SetStatus(ctx, task.UserCred, computeapi.DISK_READY, "resize success")
|
||||
logclient.AddActionLogWithStartable(task, volume, logclient.ACT_RESIZE, nil, task.UserCred, true)
|
||||
task.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (task *VolumeResizeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
volume := obj.(*models.SVolume)
|
||||
|
||||
input := api.VolumeResizeTaskInput{}
|
||||
if task.GetParams() != nil {
|
||||
_ = task.GetParams().Unmarshal(&input)
|
||||
}
|
||||
if input.SizeMB <= 0 {
|
||||
task.taskFailed(ctx, volume, errors.Wrap(httperrors.ErrInputParameter, "missing size_mb"))
|
||||
return
|
||||
}
|
||||
if volume.SizeMB >= input.SizeMB {
|
||||
task.taskComplete(ctx, volume)
|
||||
return
|
||||
}
|
||||
if len(volume.CmpId) == 0 {
|
||||
task.taskFailed(ctx, volume, errors.Wrap(errors.ErrInvalidStatus, "empty cmp_id"))
|
||||
return
|
||||
}
|
||||
|
||||
// Resize disk
|
||||
s := auth.GetSession(ctx, task.UserCred, "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("size", jsonutils.NewString(fmt.Sprintf("%dM", input.SizeMB)))
|
||||
|
||||
task.SetStage("OnDiskResizeComplete", nil)
|
||||
err := s.WithTaskCallback(task.GetId(), func() error {
|
||||
_, err := compute.Disks.PerformAction(s, volume.CmpId, "resize", params)
|
||||
return err
|
||||
})
|
||||
input := llmapi.VolumeResizeTaskInput{}
|
||||
err := task.Params.Unmarshal(&input)
|
||||
if err != nil {
|
||||
task.taskFailed(ctx, volume, errors.Wrap(err, "disk resize"))
|
||||
task.taskFailed(ctx, volume, errors.Wrap(err, "Unmarshal SVolumeResizeTaskInput"))
|
||||
return
|
||||
}
|
||||
|
||||
volume.SetStatus(ctx, task.UserCred, llmapi.VOLUME_STATUS_RESIZING, "resizing")
|
||||
|
||||
if int(input.SizeMB) > volume.SizeMB {
|
||||
// need to resize disk
|
||||
s := auth.GetSession(ctx, task.UserCred, "")
|
||||
params := computeapi.DiskResizeInput{}
|
||||
params.Size = fmt.Sprintf("%dM", input.SizeMB)
|
||||
_, err := compute.Disks.PerformAction(s, volume.CmpId, "resize", jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
task.taskFailed(ctx, volume, errors.Wrap(err, "disk resize"))
|
||||
return
|
||||
}
|
||||
|
||||
task.SetStage("OnDiskResizeComplete", nil)
|
||||
worker.BackupTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
_, err := volume.WaitDiskStatus(ctx, task.UserCred, []string{computeapi.DISK_READY}, 3600)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "WaitDiskStatus")
|
||||
}
|
||||
d := volume.GetLLM()
|
||||
if d != nil && len(input.DesktopStatus) > 0 {
|
||||
_, err = d.WaitServerStatus(ctx, task.UserCred, []string{input.DesktopStatus}, 3600)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "WaitServerStatus")
|
||||
}
|
||||
}
|
||||
// update volume size
|
||||
err = volume.UpdateSize(ctx, task.UserCred, input.SizeMB)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UpdateSize")
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
} else {
|
||||
task.OnDiskResizeComplete(ctx, volume, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (task *VolumeResizeTask) OnDiskResizeComplete(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
volume := obj.(*models.SVolume)
|
||||
|
||||
input := api.VolumeResizeTaskInput{}
|
||||
if task.GetParams() != nil {
|
||||
_ = task.GetParams().Unmarshal(&input)
|
||||
}
|
||||
if _, err := volume.WaitDiskStatus(ctx, task.UserCred, []string{computeapi.DISK_READY}, 7200); err != nil {
|
||||
task.taskFailed(ctx, volume, err)
|
||||
return
|
||||
}
|
||||
_, err := db.Update(volume, func() error {
|
||||
volume.SizeMB = input.SizeMB
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
task.taskFailed(ctx, volume, errors.Wrap(err, "update volume size_mb"))
|
||||
return
|
||||
}
|
||||
task.taskComplete(ctx, volume)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user