diff --git a/pkg/compute/models/guestdrivers.go b/pkg/compute/models/guestdrivers.go index 4654a40322..90efa48470 100644 --- a/pkg/compute/models/guestdrivers.go +++ b/pkg/compute/models/guestdrivers.go @@ -77,8 +77,6 @@ type IGuestDriver interface { RequestGuestCreateAllDisks(ctx context.Context, guest *SGuest, task taskman.ITask) error - OnGuestCreateTaskComplete(ctx context.Context, guest *SGuest, task taskman.ITask) error - RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *SGuest, task taskman.ITask) error StartGuestStopTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error diff --git a/pkg/compute/tasks/eip_associate_task.go b/pkg/compute/tasks/eip_associate_task.go index a85972c194..14d48a1f73 100644 --- a/pkg/compute/tasks/eip_associate_task.go +++ b/pkg/compute/tasks/eip_associate_task.go @@ -65,14 +65,28 @@ func (self *EipAssociateTask) OnInit(ctx context.Context, obj db.IStandaloneMode return } + self.SetStage("OnAssociateEipComplete", nil) if err := driver.RequestAssociateEip(ctx, self.UserCred, server, eip, self); err != nil { self.TaskFail(ctx, eip, err.Error(), server) return } +} +func (self *EipAssociateTask) OnAssociateEipComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + eip := obj.(*models.SElasticip) + instanceId, _ := self.Params.GetString("instance_id") + server := models.GuestManager.FetchGuestById(instanceId) server.StartSyncstatus(ctx, self.UserCred, "") logclient.AddActionLogWithStartable(self, server, logclient.ACT_EIP_ASSOCIATE, nil, self.UserCred, true) logclient.AddActionLogWithStartable(self, eip, logclient.ACT_VM_ASSOCIATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) } + +func (self *EipAssociateTask) OnAssociateEipCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + eip := obj.(*models.SElasticip) + instanceId, _ := self.Params.GetString("instance_id") + server := models.GuestManager.FetchGuestById(instanceId) + self.TaskFail(ctx, eip, data.String(), server) + return +} diff --git a/pkg/compute/tasks/guest_create_task.go b/pkg/compute/tasks/guest_create_task.go index 853bf9f104..6aba295c54 100644 --- a/pkg/compute/tasks/guest_create_task.go +++ b/pkg/compute/tasks/guest_create_task.go @@ -28,6 +28,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/mcclient/modules/notify" + "yunion.io/x/onecloud/pkg/util/billing" "yunion.io/x/onecloud/pkg/util/logclient" ) @@ -108,11 +109,34 @@ func (self *GuestCreateTask) StartDeployGuest(ctx context.Context, guest *models func (self *GuestCreateTask) OnDeployGuestDescComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { guest := obj.(*models.SGuest) - db.OpsLog.LogEvent(guest, db.ACT_ALLOCATE, nil, self.UserCred) - if !guest.IsSystem { - self.notifyServerCreated(ctx, guest) + + // bind eip + { + eipId, _ := self.Params.GetString("eip") + if len(eipId) > 0 { + self.SetStage("OnDeployEipComplete", nil) + eipObj, err := models.ElasticipManager.FetchById(eipId) + if err != nil { + log.Errorf("fail to get eip %s %s", eipId, err) + return + } + + eip := eipObj.(*models.SElasticip) + + eipBw, _ := self.Params.Int("eip_bw") + if eipBw > 0 { + // newly allocated eip, need allocation and associate + eip.AllocateAndAssociateVM(ctx, self.UserCred, guest) + } else { + // existing eip, association only + eip.StartEipAssociateInstanceTask(ctx, self.UserCred, guest, "") + } + + return + } } - guest.GetDriver().OnGuestCreateTaskComplete(ctx, guest, self) + + self.OnDeployEipComplete(ctx, guest, nil) } func (self *GuestCreateTask) notifyServerCreated(ctx context.Context, guest *models.SGuest) { @@ -132,6 +156,47 @@ func (self *GuestCreateTask) OnDeployGuestDescCompleteFailed(ctx context.Context self.SetStageFailed(ctx, data.String()) } +func (self *GuestCreateTask) OnDeployEipComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + guest := obj.(*models.SGuest) + db.OpsLog.LogEvent(guest, db.ACT_ALLOCATE, nil, self.UserCred) + if !guest.IsSystem { + self.notifyServerCreated(ctx, guest) + } + + // Guest Create Complete + duration, _ := self.GetParams().GetString("duration") + if len(duration) > 0 { + bc, err := billing.ParseBillingCycle(duration) + if err == nil && guest.ExpiredAt.IsZero() { + guest.SaveRenewInfo(ctx, self.GetUserCred(), &bc, nil) + } + if jsonutils.QueryBoolean(self.GetParams(), "auto_prepaid_recycle", false) { + err := guest.CanPerformPrepaidRecycle() + if err == nil { + self.SetStageComplete(ctx, nil) + guest.DoPerformPrepaidRecycle(ctx, self.GetUserCred(), true) + } + } + } + + if jsonutils.QueryBoolean(self.GetParams(), "auto_start", false) { + self.SetStage("on_auto_start_guest", nil) + guest.StartGueststartTask(ctx, self.GetUserCred(), nil, self.GetTaskId()) + } else { + self.SetStage("on_sync_status_complete", nil) + guest.StartSyncstatus(ctx, self.GetUserCred(), self.GetTaskId()) + } +} + +func (self *GuestCreateTask) OnDeployEipCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { + guest := obj.(*models.SGuest) + guest.SetStatus(self.UserCred, api.VM_ASSOCIATE_EIP_FAILED, "deploy_failed") + db.OpsLog.LogEvent(guest, db.ACT_EIP_ATTACH, data, self.UserCred) + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_EIP_ASSOCIATE, data, self.UserCred, false) + notifyclient.NotifySystemError(guest.Id, guest.Name, api.VM_ASSOCIATE_EIP_FAILED, data.String()) + self.SetStageFailed(ctx, data.String()) +} + func (self *GuestCreateTask) OnAutoStartGuest(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { guest := obj.(*models.SGuest) self.TaskComplete(ctx, guest) @@ -146,28 +211,4 @@ func (self *GuestCreateTask) TaskComplete(ctx context.Context, guest *models.SGu db.OpsLog.LogEvent(guest, db.ACT_ALLOCATE, "", self.UserCred) logclient.AddActionLogWithContext(ctx, guest, logclient.ACT_ALLOCATE, "", self.UserCred, true) self.SetStageComplete(ctx, guest.GetShortDesc(ctx)) - self.StartEipSubTask(ctx, guest) -} - -func (self *GuestCreateTask) StartEipSubTask(ctx context.Context, guest *models.SGuest) { - eipId, _ := self.Params.GetString("eip") - if len(eipId) > 0 { - eipObj, err := models.ElasticipManager.FetchById(eipId) - if err != nil { - log.Errorf("fail to get eip %s %s", eipId, err) - return - } - - eip := eipObj.(*models.SElasticip) - - eipBw, _ := self.Params.Int("eip_bw") - if eipBw > 0 { - // newly allocated eip, need allocation and associate - eip.AllocateAndAssociateVM(ctx, self.UserCred, guest) - } else { - // existing eip, association only - eip.StartEipAssociateInstanceTask(ctx, self.UserCred, guest, "") - } - return - } }