Merge pull request #8774 from rainzm/fix/esxisp

Fix for esxi instance snapshot
This commit is contained in:
yunion-ci-robot
2020-11-16 11:02:03 +08:00
committed by GitHub
6 changed files with 45 additions and 8 deletions
+1
View File
@@ -49,6 +49,7 @@ const (
INSTANCE_SNAPSHOT_FAILED = "instance_snapshot_create_failed"
INSTANCE_SNAPSHOT_START_DELETE = "instance_snapshot_start_delete"
INSTANCE_SNAPSHOT_DELETE_FAILED = "instance_snapshot_delete_failed"
INSTANCE_SNAPSHOT_RESET = "instance_snapshot_reset"
SNAPSHOT_POLICY_CACHE_STATUS_READY = "ready"
SNAPSHOT_POLICY_CACHE_STATUS_DELETING = "deleting"
+1
View File
@@ -4730,6 +4730,7 @@ func (self *SGuest) StartSnapshotResetTask(ctx context.Context, userCred mcclien
data.Set("auto_start", jsonutils.JSONTrue)
}
self.SetStatus(userCred, api.VM_START_SNAPSHOT_RESET, "start snapshot reset task")
instanceSnapshot.SetStatus(userCred, api.INSTANCE_SNAPSHOT_RESET, "start snapshot reset task")
if task, err := taskman.TaskManager.NewTask(
ctx, "InstanceSnapshotResetTask", instanceSnapshot, userCred, data, "", "", nil,
); err != nil {
+17 -5
View File
@@ -17,6 +17,7 @@ package models
import (
"context"
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -361,16 +362,25 @@ func (self *SInstanceSnapshot) ToInstanceCreateInput(
return nil, errors.Wrap(err, "unmarshal sched input")
}
if len(self.ExternalId) > 0 {
cp := self.GetCloudprovider()
if cp == nil {
return nil, fmt.Errorf("unable to get cloudprovider of isp %q", self.GetId())
}
if cp.Provider != api.CLOUD_PROVIDER_VMWARE {
isjs := make([]SInstanceSnapshotJoint, 0)
err := InstanceSnapshotJointManager.Query().Equals("instance_snapshot_id", self.Id).Asc("disk_index").All(&isjs)
if err != nil {
return nil, errors.Wrap(err, "fetch instance snapshots")
}
for i := 0; i < len(serverConfig.Disks); i++ {
serverConfig.Disks[i].SnapshotId = isjs[serverConfig.Disks[i].Index].SnapshotId
index := serverConfig.Disks[i].Index
if index < len(isjs) {
serverConfig.Disks[i].SnapshotId = isjs[index].SnapshotId
}
}
}
sourceInput.Disks = serverConfig.Disks
if sourceInput.VmemSize == 0 {
sourceInput.VmemSize = serverConfig.Memory
@@ -394,7 +404,9 @@ func (self *SInstanceSnapshot) ToInstanceCreateInput(
}
sourceInput.OsType = self.OsType
sourceInput.InstanceType = self.InstanceType
sourceInput.Networks = serverConfig.Networks
if len(sourceInput.Networks) == 0 {
sourceInput.Networks = serverConfig.Networks
}
return sourceInput, nil
}
@@ -422,8 +434,8 @@ func (self *SInstanceSnapshot) GetInstanceSnapshotJointAt(diskIndex int) (*SInst
}
func (self *SInstanceSnapshot) ValidateDeleteCondition(ctx context.Context) error {
if self.Status == api.INSTANCE_SNAPSHOT_START_DELETE {
return httperrors.NewBadRequestError("can't delete snapshot in deleting")
if self.Status == api.INSTANCE_SNAPSHOT_START_DELETE || self.Status == api.INSTANCE_SNAPSHOT_RESET {
return httperrors.NewForbiddenError("can't delete instance snapshot with wrong status")
}
return nil
}
@@ -42,6 +42,7 @@ func (self *InstanceSnapshotResetTask) taskFail(
guest = models.GuestManager.FetchGuestById(isp.GuestId)
}
guest.SetStatus(self.UserCred, compute.VM_SNAPSHOT_RESET_FAILED, reason.String())
isp.SetStatus(self.UserCred, compute.INSTANCE_SNAPSHOT_READY, "")
db.OpsLog.LogEvent(guest, db.ACT_VM_RESET_SNAPSHOT_FAILED, reason, self.UserCred)
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_RESET, reason, self.UserCred, false)
@@ -52,6 +53,7 @@ func (self *InstanceSnapshotResetTask) taskFail(
func (self *InstanceSnapshotResetTask) taskComplete(
ctx context.Context, isp *models.SInstanceSnapshot, guest *models.SGuest, data jsonutils.JSONObject) {
isp.SetStatus(self.UserCred, compute.INSTANCE_SNAPSHOT_READY, "")
if guest == nil {
guest = models.GuestManager.FetchGuestById(isp.GuestId)
}
@@ -102,8 +104,9 @@ func (self *InstanceSnapshotResetTask) OnKvmDiskResetFailed(
func (self *InstanceSnapshotResetTask) OnInstanceSnapshotReset(ctx context.Context, isp *models.SInstanceSnapshot, data jsonutils.JSONObject) {
guest, _ := isp.GetGuest()
if guest.Status == compute.VM_READY && jsonutils.QueryBoolean(self.Params, "auto_start", false) {
if jsonutils.QueryBoolean(self.Params, "auto_start", false) {
self.SetStage("OnGuestStartComplete", nil)
isp.SetStatus(self.UserCred, compute.INSTANCE_SNAPSHOT_READY, "")
guest.StartGueststartTask(ctx, self.UserCred, nil, self.GetTaskId())
} else {
self.taskComplete(ctx, isp, guest, data)
+2 -2
View File
@@ -727,9 +727,9 @@ type SEsxiImageInfo struct {
func (self *SHost) CreateVM2(ctx context.Context, ds *SDatastore, params SCreateVMParam) (*SVirtualMachine, error) {
if len(params.InstanceSnapshotInfo.InstanceSnapshotId) > 0 {
temvm, err := self.manager.SearchTemplateVM(params.InstanceSnapshotInfo.InstanceId)
temvm, err := self.manager.SearchVM(params.InstanceSnapshotInfo.InstanceId)
if err != nil {
return nil, errors.Wrapf(err, "SEsxiClient.SearchTemplateVM for image %q", params.InstanceSnapshotInfo.InstanceId)
return nil, errors.Wrapf(err, "SEsxiClient.SearchVM for image %q", params.InstanceSnapshotInfo.InstanceId)
}
isp, err := temvm.GetInstanceSnapshot(params.InstanceSnapshotInfo.InstanceSnapshotId)
if err != nil {
+20
View File
@@ -349,6 +349,26 @@ func (cli *SESXiClient) scanAllMObjects(props []string, dst interface{}) error {
return cli.scanMObjects(cli.client.ServiceContent.RootFolder, props, dst)
}
func (cli *SESXiClient) SearchVM(id string) (*SVirtualMachine, error) {
filter := property.Filter{}
filter["summary.config.uuid"] = id
var movms []mo.VirtualMachine
err := cli.scanMObjectsWithFilter(cli.client.ServiceContent.RootFolder, VIRTUAL_MACHINE_PROPS, &movms, filter)
if err != nil {
return nil, err
}
if len(movms) == 0 {
return nil, errors.ErrNotFound
}
vm := NewVirtualMachine(cli, &movms[0], nil)
dc, err := vm.fetchDatacenter()
if err != nil {
return nil, errors.Wrap(err, "fetchDatacenter")
}
vm.datacenter = dc
return vm, nil
}
func (cli *SESXiClient) SearchTemplateVM(id string) (*SVirtualMachine, error) {
filter := property.Filter{}
uuid := toTemplateUuid(id)