diff --git a/pkg/compute/models/capabilities.go b/pkg/compute/models/capabilities.go index 67d2c75271..4568852cd9 100644 --- a/pkg/compute/models/capabilities.go +++ b/pkg/compute/models/capabilities.go @@ -38,6 +38,7 @@ func getHypervisors(zone *SZone) []string { if zone != nil { q = q.Equals("zone_id", zone.Id) } + q = q.IsNotEmpty("host_type").IsNotNull("host_type") q = q.Distinct() rows, err := q.Rows() if err != nil { @@ -59,6 +60,8 @@ func getStorageTypes(zone *SZone) []string { if zone != nil { q = q.Equals("zone_id", zone.Id) } + q = q.IsNotEmpty("storage_type").IsNotNull("storage_type") + q = q.IsNotEmpty("medium_type").IsNotNull("medium_type") q = q.Distinct() rows, err := q.Rows() if err != nil { diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index 02d10139eb..8ba88c35bd 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -39,6 +39,8 @@ const ( EIP_STATUS_DISSOCIATE = "dissociate" EIP_STATUS_DISSOCIATE_FAIL = "dissociate_fail" + EIP_STATUS_CHANGE_BANDWIDTH = "change_bandwidth" + EIP_CHARGE_TYPE_BY_TRAFFIC = "traffic" EIP_CHARGE_TYPE_BY_BANDWIDTH = "bandwidth" EIP_CHARGE_TYPE_DEFAULT = EIP_CHARGE_TYPE_BY_TRAFFIC @@ -178,7 +180,7 @@ func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclien } func (self *SElasticip) SyncInstanceWithCloudEip(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudEIP) error { - vm := self.getVM() + vm := self.GetAssociateVM() vmExtId := ext.GetAssociationExternalId() if vm == nil && len(vmExtId) == 0 { @@ -281,7 +283,7 @@ func (manager *SElasticipManager) getEipForInstance(instanceType string, instanc return &eip, nil } -func (self *SElasticip) getVM() *SGuest { +func (self *SElasticip) GetAssociateVM() *SGuest { if self.AssociateType == "server" && len(self.AssociateId) > 0 { return GuestManager.FetchGuestById(self.AssociateId) } @@ -292,7 +294,7 @@ func (self *SElasticip) Dissociate(ctx context.Context, userCred mcclient.TokenC if len(self.AssociateType) == 0 { return nil } - vm := self.getVM() + vm := self.GetAssociateVM() if vm == nil { log.Errorf("dissociate VM not exists???") } @@ -305,7 +307,9 @@ func (self *SElasticip) Dissociate(ctx context.Context, userCred mcclient.TokenC return err } if vm != nil { + db.OpsLog.LogDetachEvent(vm, self, userCred, self.GetShortDesc()) db.OpsLog.LogEvent(self, db.ACT_EIP_DETACH, vm.GetShortDesc(), userCred) + db.OpsLog.LogEvent(vm, db.ACT_EIP_DETACH, self.GetShortDesc(), userCred) } if self.Mode == EIP_MODE_INSTANCE_PUBLICIP { self.Delete(ctx, userCred) @@ -325,7 +329,11 @@ func (self *SElasticip) AssociateVM(userCred mcclient.TokenCredential, vm *SGues if err != nil { return err } + + db.OpsLog.LogAttachEvent(vm, self, userCred, self.GetShortDesc()) db.OpsLog.LogEvent(self, db.ACT_EIP_ATTACH, vm.GetShortDesc(), userCred) + db.OpsLog.LogEvent(vm, db.ACT_EIP_ATTACH, self.GetShortDesc(), userCred) + return nil } @@ -638,7 +646,7 @@ func (self *SElasticip) GetCustomizeColumns(ctx context.Context, userCred mcclie } func (self *SElasticip) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict { - vm := self.getVM() + vm := self.GetAssociateVM() if vm != nil { extra.Add(jsonutils.NewString(vm.GetName()), "associate_name") } @@ -704,6 +712,9 @@ func (self *SElasticip) PerformChangeBandwidth(ctx context.Context, userCred mcc } func (self *SElasticip) StartEipChangeBandwidthTask(ctx context.Context, userCred mcclient.TokenCredential, bandwidth int64) error { + + self.SetStatus(userCred, EIP_STATUS_CHANGE_BANDWIDTH, "change bandwidth") + params := jsonutils.NewDict() params.Add(jsonutils.NewInt(bandwidth), "bandwidth") @@ -722,6 +733,8 @@ func (self *SElasticip) DoChangeBandwidth(userCred mcclient.TokenCredential, ban return nil }) + self.SetStatus(userCred, EIP_STATUS_READY, "finish change bandwidth") + if err != nil { log.Errorf("DoChangeBandwidth update fail %s", err) return err diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 560c3c22b6..b96c1e2081 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -100,6 +100,9 @@ const ( VM_RESTORE_STATE = "restore_state" VM_RESTORE_FAILED = "restore_failed" + VM_ASSOCIATE_EIP = "associate_eip" + VM_DISSOCIATE_EIP = "dissociate_eip" + VM_REMOVE_STATEFILE = "remove_state" VM_ADMIN = "admin" @@ -4148,7 +4151,7 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T return nil, httperrors.NewUnsupportOperationError("fixed eip cannot be associated") } - eipVm := eip.getVM() + eipVm := eip.GetAssociateVM() if eipVm != nil { return nil, httperrors.NewConflictError("eip has been associated") } @@ -4166,6 +4169,8 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T return nil, httperrors.NewInputParameterError("cannot associate eip and instance in different provider") } + self.SetStatus(userCred, VM_ASSOCIATE_EIP, "associate eip") + params := jsonutils.NewDict() params.Add(jsonutils.NewString(self.ExternalId), "instance_external_id") params.Add(jsonutils.NewString(self.Id), "instance_id") @@ -4189,6 +4194,9 @@ func (self *SGuest) PerformDissociateEip(ctx context.Context, userCred mcclient. if eip == nil { return nil, httperrors.NewInvalidStatusError("No eip to dissociate") } + + self.SetStatus(userCred, VM_DISSOCIATE_EIP, "associate eip") + err = eip.StartEipDissociateTask(ctx, userCred, "") if err != nil { log.Errorf("fail to start dissociate task %s", err) diff --git a/pkg/compute/tasks/eip_associate_task.go b/pkg/compute/tasks/eip_associate_task.go index da81236056..77bf7077d5 100644 --- a/pkg/compute/tasks/eip_associate_task.go +++ b/pkg/compute/tasks/eip_associate_task.go @@ -32,6 +32,11 @@ func (self *EipAssociateTask) OnInit(ctx context.Context, obj db.IStandaloneMode instanceId, _ := self.Params.GetString("instance_id") server := models.GuestManager.FetchGuestById(instanceId) + + if server.Status != models.VM_ASSOCIATE_EIP { + server.SetStatus(self.UserCred, models.VM_ASSOCIATE_EIP, "associate eip") + } + if server == nil { msg := fmt.Sprintf("fail to find server for instanceId %s", instanceId) eip.SetStatus(self.UserCred, models.EIP_STATUS_ASSOCIATE_FAIL, msg) @@ -57,5 +62,7 @@ func (self *EipAssociateTask) OnInit(ctx context.Context, obj db.IStandaloneMode eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "associate") + server.StartSyncstatus(ctx, self.UserCred, "") + self.SetStageComplete(ctx, nil) } \ No newline at end of file diff --git a/pkg/compute/tasks/eip_dissociate_task.go b/pkg/compute/tasks/eip_dissociate_task.go index 637133792b..d2ff942029 100644 --- a/pkg/compute/tasks/eip_dissociate_task.go +++ b/pkg/compute/tasks/eip_dissociate_task.go @@ -2,7 +2,6 @@ package tasks import ( - "fmt" "context" "yunion.io/x/jsonutils" @@ -10,6 +9,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" + "fmt" ) type EipDissociateTask struct { @@ -23,33 +23,43 @@ func init() { func (self *EipDissociateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { eip := obj.(*models.SElasticip) - extEip, err := eip.GetIEip() - if err != nil { - msg := fmt.Sprintf("fail to find iEIP for eip %s", err) - eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg) - self.SetStageFailed(ctx, msg) - return - } + server := eip.GetAssociateVM() + if server != nil { - if len(extEip.GetAssociationExternalId()) > 0 { - err = extEip.Dissociate() + if server.Status != models.VM_DISSOCIATE_EIP { + server.SetStatus(self.UserCred, models.VM_DISSOCIATE_EIP, "dissociate eip") + } + + extEip, err := eip.GetIEip() if err != nil { - msg := fmt.Sprintf("fail to remote dissociate eip %s", err) + msg := fmt.Sprintf("fail to find iEIP for eip %s", err) eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg) self.SetStageFailed(ctx, msg) return } - } - err = eip.Dissociate(ctx, self.UserCred) - if err != nil { - msg := fmt.Sprintf("fail to local dissociate eip %s", err) - eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg) - self.SetStageFailed(ctx, msg) - return - } + if len(extEip.GetAssociationExternalId()) > 0 { + err = extEip.Dissociate() + if err != nil { + msg := fmt.Sprintf("fail to remote dissociate eip %s", err) + eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg) + self.SetStageFailed(ctx, msg) + return + } + } - eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "dissociate") + err = eip.Dissociate(ctx, self.UserCred) + if err != nil { + msg := fmt.Sprintf("fail to local dissociate eip %s", err) + eip.SetStatus(self.UserCred, models.EIP_STATUS_DISSOCIATE_FAIL, msg) + self.SetStageFailed(ctx, msg) + return + } + + eip.SetStatus(self.UserCred, models.EIP_STATUS_READY, "dissociate") + + server.StartSyncstatus(ctx, self.UserCred, "") + } self.SetStageComplete(ctx, nil) diff --git a/pkg/util/aliyun/storagecache.go b/pkg/util/aliyun/storagecache.go index aed2d7c32b..5f8bd8e41c 100644 --- a/pkg/util/aliyun/storagecache.go +++ b/pkg/util/aliyun/storagecache.go @@ -88,6 +88,8 @@ func (self *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) { func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, extId string, isForce bool) (string, error) { if len(extId) > 0 { + log.Debugf("UploadImage: Image external ID exists %s", extId) + status, err := self.region.GetImageStatus(extId) if err != nil { log.Errorf("GetImageStatus error %s", err) @@ -95,6 +97,8 @@ func (self *SStoragecache) UploadImage(userCred mcclient.TokenCredential, imageI if status == ImageStatusAvailable && !isForce { return extId, nil } + } else { + log.Debugf("UploadImage: no external ID") } return self.uploadImage(userCred, imageId, osArch, osType, osDist, isForce)