mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #15518 from wanyaoqi/automated-cherry-pick-of-#15509-upstream-release-3.10
Automated cherry pick of #15509: fix(region,host): fix some bugs of server disk change storage
This commit is contained in:
@@ -842,10 +842,11 @@ type ServerChangeDiskStorageInput struct {
|
||||
|
||||
type ServerChangeDiskStorageInternalInput struct {
|
||||
ServerChangeDiskStorageInput
|
||||
StorageId string `json:"storage_id"`
|
||||
TargetDiskId string `json:"target_disk_id"`
|
||||
DiskFormat string `json:"disk_format"`
|
||||
GuestRunning bool `josn:"guest_running"`
|
||||
StorageId string `json:"storage_id"`
|
||||
TargetDiskId string `json:"target_disk_id"`
|
||||
DiskFormat string `json:"disk_format"`
|
||||
GuestRunning bool `josn:"guest_running"`
|
||||
TargetDiskDesc *GuestdiskJsonDesc `json:"target_disk_desc"`
|
||||
}
|
||||
|
||||
type ServerSetExtraOptionInput struct {
|
||||
|
||||
@@ -175,8 +175,12 @@ func (self *SGuestdisk) GetDisk() *SDisk {
|
||||
|
||||
func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api.GuestdiskJsonDesc {
|
||||
disk := self.GetDisk()
|
||||
return self.GetDiskJsonDescAtHost(ctx, host, disk)
|
||||
}
|
||||
|
||||
func (self *SGuestdisk) GetDiskJsonDescAtHost(ctx context.Context, host *SHost, disk *SDisk) *api.GuestdiskJsonDesc {
|
||||
desc := &api.GuestdiskJsonDesc{
|
||||
DiskId: self.DiskId,
|
||||
DiskId: disk.Id,
|
||||
Driver: self.Driver,
|
||||
CacheMode: self.CacheMode,
|
||||
AioMode: self.AioMode,
|
||||
@@ -185,9 +189,9 @@ func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api
|
||||
Size: disk.DiskSize,
|
||||
}
|
||||
desc.TemplateId = disk.GetTemplateId()
|
||||
storage, _ := disk.GetStorage()
|
||||
desc.StorageType = storage.StorageType
|
||||
if len(desc.TemplateId) > 0 {
|
||||
storage, _ := disk.GetStorage()
|
||||
desc.StorageType = storage.StorageType
|
||||
storagecacheimg := StoragecachedimageManager.GetStoragecachedimage(storage.StoragecacheId, desc.TemplateId)
|
||||
if storagecacheimg != nil {
|
||||
desc.ImagePath = storagecacheimg.Path
|
||||
|
||||
@@ -118,6 +118,26 @@ func (t *GuestChangeDiskStorageTask) OnDiskLiveChangeStorageReady(
|
||||
) {
|
||||
if !jsonutils.QueryBoolean(data, "block_jobs_ready", false) {
|
||||
log.Infof("OnDiskLiveChangeStorageReady block jobs not ready")
|
||||
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
|
||||
if err := data.Unmarshal(resp); err != nil {
|
||||
t.TaskFailed(ctx, guest,
|
||||
jsonutils.NewString(fmt.Sprintf("unmarshal OnDiskLiveChangeStorageReady resp failed %s", err)),
|
||||
)
|
||||
return
|
||||
}
|
||||
targetDisk, err := t.GetTargetDisk()
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get target disk %s", err)))
|
||||
return
|
||||
}
|
||||
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
|
||||
targetDisk.AccessPath = resp.TargetAccessPath
|
||||
targetDisk.DiskFormat = resp.TargetFormat
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -126,6 +146,22 @@ func (t *GuestChangeDiskStorageTask) OnDiskLiveChangeStorageReady(
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetInputParams error: %v", err)))
|
||||
return
|
||||
}
|
||||
guestdisk := guest.GetGuestDisk(input.DiskId)
|
||||
if guestdisk == nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString("failed get guest disk"))
|
||||
return
|
||||
}
|
||||
host, err := guest.GetHost()
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get host %s", err)))
|
||||
return
|
||||
}
|
||||
targetDisk, err := t.GetTargetDisk()
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get target disk %s", err)))
|
||||
return
|
||||
}
|
||||
input.TargetDiskDesc = guestdisk.GetDiskJsonDescAtHost(ctx, host, targetDisk)
|
||||
|
||||
t.SetStage("OnDiskChangeStorageComplete", nil)
|
||||
// block job ready, start switch to target storage disk
|
||||
@@ -157,29 +193,36 @@ func (t *GuestChangeDiskStorageTask) OnDiskChangeStorageComplete(ctx context.Con
|
||||
return
|
||||
}
|
||||
|
||||
// update target disk attributes by response
|
||||
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
|
||||
if err := data.Unmarshal(resp); err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Unmarshal response: %v", err)))
|
||||
return
|
||||
}
|
||||
|
||||
if len(resp.TargetFormat) == 0 {
|
||||
resp.TargetFormat = srcDisk.DiskFormat
|
||||
}
|
||||
|
||||
targetDisk, err := t.GetTargetDisk()
|
||||
input, err := t.GetInputParams()
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetTargetDisk error: %v", err)))
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetInputParams error: %v", err)))
|
||||
return
|
||||
}
|
||||
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
|
||||
targetDisk.AccessPath = resp.TargetAccessPath
|
||||
targetDisk.DiskFormat = resp.TargetFormat
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
|
||||
return
|
||||
|
||||
if !input.GuestRunning {
|
||||
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
|
||||
err = data.Unmarshal(resp)
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Unmarshal response: %v", err)))
|
||||
return
|
||||
}
|
||||
if len(resp.TargetFormat) == 0 {
|
||||
resp.TargetFormat = srcDisk.DiskFormat
|
||||
}
|
||||
|
||||
targetDisk, err := t.GetTargetDisk()
|
||||
if err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetTargetDisk error: %v", err)))
|
||||
return
|
||||
}
|
||||
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
|
||||
targetDisk.AccessPath = resp.TargetAccessPath
|
||||
targetDisk.DiskFormat = resp.TargetFormat
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
guestSrcDisk := guest.GetGuestDisk(srcDisk.GetId())
|
||||
@@ -248,9 +291,20 @@ func (t *GuestChangeDiskStorageTask) attachTargetDisk(ctx context.Context, guest
|
||||
}
|
||||
|
||||
func (t *GuestChangeDiskStorageTask) OnTargetDiskAttachComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
t.SetStage("OnGuestSyncStatus", nil)
|
||||
if err := guest.StartSyncstatus(ctx, t.UserCred, t.Id); err != nil {
|
||||
t.TaskFailed(ctx, guest, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *GuestChangeDiskStorageTask) OnGuestSyncStatus(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
t.TaskComplete(ctx, guest, nil)
|
||||
}
|
||||
|
||||
func (t *GuestChangeDiskStorageTask) OnGuestSyncStatusFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
t.TaskFailed(ctx, guest, data)
|
||||
}
|
||||
|
||||
func (t *GuestChangeDiskStorageTask) OnTargetDiskAttachCompleteFailed(ctx context.Context, guest *models.SGuest, err jsonutils.JSONObject) {
|
||||
t.TaskFailed(ctx, guest, err)
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ func guestDestPrepareMigrateInternal(ctx context.Context, userCred mcclient.Toke
|
||||
params.DisksBackingFile = disksBack
|
||||
}
|
||||
disks := guestDesc.Disks
|
||||
if err != nil {
|
||||
if disks == nil {
|
||||
return httperrors.NewInputParameterError("Get desc disks error")
|
||||
} else {
|
||||
targetStorageIds := []string{}
|
||||
@@ -666,12 +666,13 @@ func formatCloneDiskParams(sid string, body jsonutils.JSONObject) (*guestman.SSt
|
||||
}
|
||||
|
||||
params := &guestman.SStorageCloneDisk{
|
||||
ServerId: sid,
|
||||
SourceStorage: srcStorage,
|
||||
SourceDisk: srcDisk,
|
||||
TargetStorage: targetStorage,
|
||||
TargetDiskId: input.TargetDiskId,
|
||||
DiskFormat: input.DiskFormat,
|
||||
ServerId: sid,
|
||||
SourceStorage: srcStorage,
|
||||
SourceDisk: srcDisk,
|
||||
TargetStorage: targetStorage,
|
||||
TargetDiskId: input.TargetDiskId,
|
||||
DiskFormat: input.DiskFormat,
|
||||
TargetDiskDesc: input.TargetDiskDesc,
|
||||
}
|
||||
return params, nil
|
||||
}
|
||||
|
||||
@@ -1278,12 +1278,13 @@ func (m *SGuestManager) ExitGuestCleanup() {
|
||||
}
|
||||
|
||||
type SStorageCloneDisk struct {
|
||||
ServerId string
|
||||
SourceStorage storageman.IStorage
|
||||
SourceDisk storageman.IDisk
|
||||
TargetStorage storageman.IStorage
|
||||
TargetDiskId string
|
||||
DiskFormat string
|
||||
ServerId string
|
||||
SourceStorage storageman.IStorage
|
||||
SourceDisk storageman.IDisk
|
||||
TargetStorage storageman.IStorage
|
||||
TargetDiskId string
|
||||
DiskFormat string
|
||||
TargetDiskDesc *compute.GuestdiskJsonDesc
|
||||
}
|
||||
|
||||
func (m *SGuestManager) StorageCloneDisk(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -2359,6 +2359,7 @@ func (t *SGuestStorageCloneDiskTask) Start(guestRunning bool) {
|
||||
disks := t.Desc.Disks
|
||||
for diskIndex = 0; diskIndex < len(disks); diskIndex++ {
|
||||
if disks[diskIndex].DiskId == t.params.SourceDisk.GetId() {
|
||||
diskIndex = int(disks[diskIndex].Index)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -2444,6 +2445,7 @@ func NewGuestLiveChangeDiskTask(ctx context.Context, guest *SKVMGuestInstance, p
|
||||
disks := guest.Desc.Disks
|
||||
for diskIndex = 0; diskIndex < len(disks); diskIndex++ {
|
||||
if disks[diskIndex].DiskId == params.SourceDisk.GetId() {
|
||||
diskIndex = int(disks[diskIndex].Index)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -2495,6 +2497,16 @@ func (t *SGuestLiveChangeDisk) onReopenImageSuccess(res string) {
|
||||
hostutils.TaskFailed(t.ctx, fmt.Sprintf("reopen image failed: %s", res))
|
||||
return
|
||||
}
|
||||
if t.params.TargetDiskDesc != nil {
|
||||
for i := 0; i < len(t.Desc.Disks); i++ {
|
||||
if t.Desc.Disks[i].Index == int8(t.diskIndex) {
|
||||
log.Debugf("update guest disk %s desc", t.Desc.Disks[i].DiskId)
|
||||
t.Desc.Disks[i].GuestdiskJsonDesc = *t.params.TargetDiskDesc
|
||||
t.SaveLiveDesc(t.Desc)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp := &hostapi.ServerCloneDiskFromStorageResponse{
|
||||
TargetAccessPath: t.targetDisk.GetPath(),
|
||||
|
||||
Reference in New Issue
Block a user