volume_resize_task.go 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package volume
  2. import (
  3. "context"
  4. "fmt"
  5. "yunion.io/x/jsonutils"
  6. "yunion.io/x/pkg/errors"
  7. computeapi "yunion.io/x/onecloud/pkg/apis/compute"
  8. llmapi "yunion.io/x/onecloud/pkg/apis/llm"
  9. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  10. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  11. "yunion.io/x/onecloud/pkg/llm/models"
  12. "yunion.io/x/onecloud/pkg/llm/tasks/worker"
  13. "yunion.io/x/onecloud/pkg/mcclient/auth"
  14. "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
  15. "yunion.io/x/onecloud/pkg/util/logclient"
  16. )
  17. type VolumeResizeTask struct {
  18. taskman.STask
  19. }
  20. func init() {
  21. taskman.RegisterTask(VolumeResizeTask{})
  22. }
  23. func (task *VolumeResizeTask) taskFailed(ctx context.Context, volume *models.SVolume, err error) {
  24. volume.SetStatus(ctx, task.UserCred, computeapi.DISK_RESIZE_FAILED, err.Error())
  25. db.OpsLog.LogEvent(volume, db.ACT_RESIZE_FAIL, err, task.UserCred)
  26. logclient.AddActionLogWithStartable(task, volume, logclient.ACT_RESIZE, err.Error(), task.UserCred, false)
  27. task.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
  28. }
  29. func (task *VolumeResizeTask) taskComplete(ctx context.Context, volume *models.SVolume) {
  30. volume.SetStatus(ctx, task.UserCred, computeapi.DISK_READY, "resize success")
  31. logclient.AddActionLogWithStartable(task, volume, logclient.ACT_RESIZE, nil, task.UserCred, true)
  32. task.SetStageComplete(ctx, nil)
  33. }
  34. func (task *VolumeResizeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
  35. volume := obj.(*models.SVolume)
  36. input := llmapi.VolumeResizeTaskInput{}
  37. err := task.Params.Unmarshal(&input)
  38. if err != nil {
  39. task.taskFailed(ctx, volume, errors.Wrap(err, "Unmarshal SVolumeResizeTaskInput"))
  40. return
  41. }
  42. volume.SetStatus(ctx, task.UserCred, llmapi.VOLUME_STATUS_RESIZING, "resizing")
  43. if int(input.SizeMB) > volume.SizeMB {
  44. // need to resize disk
  45. s := auth.GetSession(ctx, task.UserCred, "")
  46. params := computeapi.DiskResizeInput{}
  47. params.Size = fmt.Sprintf("%dM", input.SizeMB)
  48. _, err := compute.Disks.PerformAction(s, volume.CmpId, "resize", jsonutils.Marshal(params))
  49. if err != nil {
  50. task.taskFailed(ctx, volume, errors.Wrap(err, "disk resize"))
  51. return
  52. }
  53. task.SetStage("OnDiskResizeComplete", nil)
  54. worker.BackupTaskRun(task, func() (jsonutils.JSONObject, error) {
  55. _, err := volume.WaitDiskStatus(ctx, task.UserCred, []string{computeapi.DISK_READY}, 3600)
  56. if err != nil {
  57. return nil, errors.Wrap(err, "WaitDiskStatus")
  58. }
  59. d := volume.GetLLM()
  60. if d != nil && len(input.DesktopStatus) > 0 {
  61. _, err = d.WaitServerStatus(ctx, task.UserCred, []string{input.DesktopStatus}, 3600)
  62. if err != nil {
  63. return nil, errors.Wrap(err, "WaitServerStatus")
  64. }
  65. }
  66. // update volume size
  67. err = volume.UpdateSize(ctx, task.UserCred, input.SizeMB)
  68. if err != nil {
  69. return nil, errors.Wrap(err, "UpdateSize")
  70. }
  71. return nil, nil
  72. })
  73. } else {
  74. task.OnDiskResizeComplete(ctx, volume, nil)
  75. }
  76. }
  77. func (task *VolumeResizeTask) OnDiskResizeComplete(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
  78. volume := obj.(*models.SVolume)
  79. task.taskComplete(ctx, volume)
  80. }
  81. func (task *VolumeResizeTask) OnDiskResizeCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
  82. volume := obj.(*models.SVolume)
  83. task.taskFailed(ctx, volume, errors.Error(err.String()))
  84. }