mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-24 02:26:39 +08:00
bug fixes
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
type ComputeQuotaKeys struct {
|
||||
RegionQuotaKeys
|
||||
ZoneQuotaKeys
|
||||
|
||||
Hypervisor string `help:"hypervisor" choices:"kvm|baremetal"`
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
"yunion.io/x/pkg/util/filterclause"
|
||||
"yunion.io/x/pkg/utils"
|
||||
@@ -43,10 +44,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
var (
|
||||
CancelUsages func(ctx context.Context, userCred mcclient.TokenCredential, usages []IUsage)
|
||||
)
|
||||
|
||||
type DBModelDispatcher struct {
|
||||
modelManager IModelManager
|
||||
}
|
||||
@@ -1104,9 +1101,15 @@ func (dispatcher *DBModelDispatcher) Create(ctx context.Context, query jsonutils
|
||||
return nil, httperrors.NewForbiddenError("Not allow to create item")
|
||||
}
|
||||
|
||||
ctx = InitPendingUsagesInContext(ctx)
|
||||
|
||||
model, err := DoCreate(dispatcher.modelManager, ctx, userCred, query, data, ownerId)
|
||||
if err != nil {
|
||||
log.Errorf("fail to doCreateItem %s", err)
|
||||
// log.Errorf("fail to doCreateItem %s", err)
|
||||
failErr := manager.OnCreateFailed(ctx, userCred, ownerId, query, data)
|
||||
if failErr != nil {
|
||||
log.Errorf("manager.OnCreateFailed %s", failErr)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
|
||||
@@ -1179,41 +1182,61 @@ func (dispatcher *DBModelDispatcher) BatchCreate(ctx context.Context, query json
|
||||
}
|
||||
|
||||
var (
|
||||
multiData []jsonutils.JSONObject
|
||||
onBatchCreateFail func()
|
||||
validateError error
|
||||
multiData []jsonutils.JSONObject
|
||||
// onBatchCreateFail func()
|
||||
// validateError error
|
||||
)
|
||||
|
||||
ctx = InitPendingUsagesInContext(ctx)
|
||||
|
||||
createResults, err := func() ([]sCreateResult, error) {
|
||||
lockman.LockClass(ctx, manager, GetLockClassKey(manager, ownerId))
|
||||
defer lockman.ReleaseClass(ctx, manager, GetLockClassKey(manager, ownerId))
|
||||
|
||||
multiData, err = expandMultiCreateParams(data, count)
|
||||
// invoke only Once
|
||||
err = manager.BatchPreValidate(ctx, userCred, ownerId, query, data.(*jsonutils.JSONDict), count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "manager.BatchPreValidate")
|
||||
}
|
||||
|
||||
multiData, err = expandMultiCreateParams(data, count)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "expandMultiCreateParams")
|
||||
}
|
||||
|
||||
// one fail, then all fail
|
||||
ret := make([]sCreateResult, len(multiData))
|
||||
for i, cdata := range multiData {
|
||||
if i == 0 {
|
||||
onBatchCreateFail, validateError = manager.BatchPreValidate(
|
||||
ctx, userCred, ownerId, query, cdata.(*jsonutils.JSONDict), len(multiData))
|
||||
if validateError != nil {
|
||||
return nil, validateError
|
||||
for i := range multiData {
|
||||
var model IModel
|
||||
model, err = batchCreateDoCreateItem(manager, ctx, userCred, ownerId, query, multiData[i], i)
|
||||
if err == nil {
|
||||
ret[i] = sCreateResult{model: model, err: nil}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
for i := range ret {
|
||||
if ret[i].model != nil {
|
||||
DeleteModel(ctx, userCred, ret[i].model)
|
||||
ret[i].model = nil
|
||||
}
|
||||
}
|
||||
model, err := batchCreateDoCreateItem(manager, ctx, userCred, ownerId, query, cdata, i)
|
||||
if err != nil && onBatchCreateFail != nil {
|
||||
onBatchCreateFail()
|
||||
ret[i].err = err
|
||||
}
|
||||
ret[i] = sCreateResult{model: model, err: err}
|
||||
return nil, errors.Wrap(err, "batchCreateDoCreateItem")
|
||||
} else {
|
||||
return ret, nil
|
||||
}
|
||||
return ret, nil
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
failErr := manager.OnCreateFailed(ctx, userCred, ownerId, query, data)
|
||||
if failErr != nil {
|
||||
log.Errorf("manager.OnCreateFailed %s", failErr)
|
||||
}
|
||||
return nil, errors.Wrap(err, "createResults")
|
||||
}
|
||||
|
||||
results := make([]modulebase.SubmitResult, count)
|
||||
models := make([]IModel, 0)
|
||||
for i, res := range createResults {
|
||||
|
||||
@@ -30,11 +30,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type IUsage interface {
|
||||
FetchUsage(ctx context.Context) error
|
||||
IsEmpty() bool
|
||||
}
|
||||
|
||||
type IModelManager interface {
|
||||
lockman.ILockedClass
|
||||
object.IObject
|
||||
@@ -91,7 +86,9 @@ type IModelManager interface {
|
||||
// ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
|
||||
OnCreateComplete(ctx context.Context, items []IModel, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject)
|
||||
BatchPreValidate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider,
|
||||
query jsonutils.JSONObject, data *jsonutils.JSONDict, count int) (func(), error)
|
||||
query jsonutils.JSONObject, data *jsonutils.JSONDict, count int) error
|
||||
|
||||
OnCreateFailed(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error
|
||||
|
||||
// allow perform action
|
||||
AllowPerformAction(ctx context.Context, userCred mcclient.TokenCredential, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) bool
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -381,14 +382,24 @@ func (manager *SModelBaseManager) GetPropertyDistinctField(ctx context.Context,
|
||||
func (manager *SModelBaseManager) BatchPreValidate(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider,
|
||||
query jsonutils.JSONObject, data *jsonutils.JSONDict, count int,
|
||||
) (func(), error) {
|
||||
return nil, nil
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) BatchCreateValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) OnCreateFailed(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if CancelPendingUsagesInContext != nil {
|
||||
err := CancelPendingUsagesInContext(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "CancelPendingUsagesInContext")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SModelBase) GetId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package quotas
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appctx"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
const (
|
||||
APP_CONTEXT_KEY_PENDINGUSAGES = appctx.AppContextKey("pendingusages")
|
||||
)
|
||||
|
||||
func initPendingUsagesInContext(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, APP_CONTEXT_KEY_PENDINGUSAGES, list.New())
|
||||
}
|
||||
|
||||
func appContextPendingUsages(ctx context.Context) []IQuota {
|
||||
val := ctx.Value(APP_CONTEXT_KEY_PENDINGUSAGES)
|
||||
if val != nil {
|
||||
quotaList := val.(*list.List)
|
||||
ret := make([]IQuota, 0)
|
||||
for e := quotaList.Front(); e != nil; e = e.Next() {
|
||||
ret = append(ret, e.Value.(IQuota))
|
||||
}
|
||||
return ret
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func clearPendingUsagesInContext(ctx context.Context) {
|
||||
val := ctx.Value(APP_CONTEXT_KEY_PENDINGUSAGES)
|
||||
if val != nil {
|
||||
quotaList := val.(*list.List)
|
||||
for quotaList.Len() > 0 {
|
||||
quotaList.Remove(quotaList.Front())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SavePendingUsagesInContext(ctx context.Context, quotas ...IQuota) {
|
||||
val := ctx.Value(APP_CONTEXT_KEY_PENDINGUSAGES)
|
||||
if val != nil {
|
||||
quotaList := val.(*list.List)
|
||||
for i := range quotas {
|
||||
quotaList.PushBack(quotas[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cancelPendingUsagesInContext(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
quotas := appContextPendingUsages(ctx)
|
||||
if quotas == nil {
|
||||
return nil
|
||||
}
|
||||
errs := make([]error, 0)
|
||||
for i := range quotas {
|
||||
err := CancelPendingUsage(ctx, userCred, quotas[i], quotas[i])
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "CancelPendingUsage %s", jsonutils.Marshal(quotas[i])))
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
clearPendingUsagesInContext(ctx)
|
||||
return nil
|
||||
}
|
||||
@@ -216,13 +216,11 @@ func (manager *SQuotaBaseManager) checkQuota(ctx context.Context, request IQuota
|
||||
|
||||
func (manager *SQuotaBaseManager) __checkQuota(ctx context.Context, quota IQuota, request IQuota) error {
|
||||
keys := quota.GetKeys()
|
||||
log.Debugf("__checkQuota for keys: %s", QuotaKeyString(keys))
|
||||
used := manager.newQuota()
|
||||
err := manager.usageStore.GetQuota(ctx, keys, used)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.usageStore.GetQuotaByKeys")
|
||||
}
|
||||
log.Debugf("__checkQuota usage: %s", jsonutils.Marshal(used))
|
||||
pendings, err := manager.pendingStore.GetChildrenQuotas(ctx, keys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.pendingStore.GetChildrenQuotas")
|
||||
@@ -231,7 +229,6 @@ func (manager *SQuotaBaseManager) __checkQuota(ctx context.Context, quota IQuota
|
||||
if pendings[i].IsEmpty() {
|
||||
continue
|
||||
}
|
||||
log.Debugf("__checkQuota pending %d: %s", i, jsonutils.Marshal(pendings[i]))
|
||||
used.Add(pendings[i])
|
||||
}
|
||||
return used.Exceed(request, quota)
|
||||
@@ -296,13 +293,11 @@ func (manager *SQuotaBaseManager) getQuotaCount(ctx context.Context, request IQu
|
||||
|
||||
func (manager *SQuotaBaseManager) __getQuotaCount(ctx context.Context, quota IQuota, request IQuota) (int, error) {
|
||||
keys := quota.GetKeys()
|
||||
log.Debugf("__checkQuota for keys: %s", QuotaKeyString(keys))
|
||||
used := manager.newQuota()
|
||||
err := manager.usageStore.GetQuota(ctx, keys, used)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "manager.usageStore.GetQuotaByKeys")
|
||||
}
|
||||
log.Debugf("__checkQuota usage: %s", jsonutils.Marshal(used))
|
||||
pendings, err := manager.pendingStore.GetChildrenQuotas(ctx, keys)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "manager.pendingStore.GetChildrenQuotas")
|
||||
@@ -311,9 +306,13 @@ func (manager *SQuotaBaseManager) __getQuotaCount(ctx context.Context, quota IQu
|
||||
if pendings[i].IsEmpty() {
|
||||
continue
|
||||
}
|
||||
log.Debugf("__checkQuota pending %d: %s", i, jsonutils.Marshal(pendings[i]))
|
||||
used.Add(pendings[i])
|
||||
}
|
||||
err = used.Exceed(request, quota)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
quota.Sub(used)
|
||||
return quota.Allocable(request), nil
|
||||
cnt := quota.Allocable(request)
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ func init() {
|
||||
quotaManagerTable = make(map[reflect.Type]IQuotaManager)
|
||||
|
||||
db.CancelUsages = CancelUsages
|
||||
db.CancelPendingUsagesInContext = cancelPendingUsagesInContext
|
||||
db.InitPendingUsagesInContext = initPendingUsagesInContext
|
||||
}
|
||||
|
||||
func Register(manager IQuotaManager) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type IUsage interface {
|
||||
FetchUsage(ctx context.Context) error
|
||||
IsEmpty() bool
|
||||
}
|
||||
|
||||
var (
|
||||
CancelUsages func(ctx context.Context, userCred mcclient.TokenCredential, usages []IUsage)
|
||||
|
||||
CancelPendingUsagesInContext func(ctx context.Context, userCred mcclient.TokenCredential) error
|
||||
|
||||
InitPendingUsagesInContext func(ctx context.Context) context.Context
|
||||
)
|
||||
@@ -540,6 +540,7 @@ func totalGuestNicCount(
|
||||
guests := GuestManager.Query().SubQuery()
|
||||
hosts := HostManager.Query().SubQuery()
|
||||
guestnics := GuestnetworkManager.Query().SubQuery()
|
||||
|
||||
q := guestnics.Query()
|
||||
q = q.Join(guests, sqlchemy.Equals(guests.Field("id"), guestnics.Field("guest_id")))
|
||||
q = q.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
|
||||
|
||||
@@ -904,40 +904,18 @@ func serverCreateInput2ComputeQuotaKeys(input api.ServerCreateInput, ownerId mcc
|
||||
func (manager *SGuestManager) BatchPreValidate(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider,
|
||||
query jsonutils.JSONObject, data *jsonutils.JSONDict, count int,
|
||||
) (func(), error) {
|
||||
) error {
|
||||
input, err := manager.validateCreateData(ctx, userCred, ownerId, query, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return errors.Wrap(err, "manager.validateCreateData")
|
||||
}
|
||||
if input.IsSystem == nil || *input.IsSystem == false {
|
||||
reqQuota, reqRegionQuota, err := manager.checkCreateQuota(ctx, userCred, ownerId, *input, input.Backup, count)
|
||||
if input.IsSystem == nil || !(*input.IsSystem) {
|
||||
err := manager.checkCreateQuota(ctx, userCred, ownerId, *input, input.Backup, count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return errors.Wrap(err, "manager.checkCreateQuota")
|
||||
}
|
||||
quota := &SQuota{
|
||||
Count: reqQuota.Count / count,
|
||||
Cpu: reqQuota.Cpu / count,
|
||||
Memory: reqQuota.Memory / count,
|
||||
Storage: reqQuota.Storage / count,
|
||||
IsolatedDevice: reqQuota.IsolatedDevice / count,
|
||||
}
|
||||
regionQuota := &SRegionQuota{
|
||||
Port: reqRegionQuota.Port / count,
|
||||
Eport: reqRegionQuota.Eport / count,
|
||||
Bw: reqRegionQuota.Bw / count,
|
||||
Ebw: reqRegionQuota.Ebw / count,
|
||||
Eip: reqRegionQuota.Eip / count,
|
||||
}
|
||||
keys := serverCreateInput2ComputeQuotaKeys(*input, ownerId)
|
||||
regionKeys := keys.SRegionalCloudResourceKeys
|
||||
quota.SetKeys(keys)
|
||||
regionQuota.SetKeys(regionKeys)
|
||||
return func() {
|
||||
quotas.CancelPendingUsage(ctx, userCred, quota, quota)
|
||||
quotas.CancelPendingUsage(ctx, userCred, regionQuota, regionQuota)
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseInstanceSnapshot(input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
@@ -1335,7 +1313,7 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
|
||||
return nil, err
|
||||
}
|
||||
if input.IsSystem == nil || !(*input.IsSystem) {
|
||||
_, _, err = manager.checkCreateQuota(ctx, userCred, ownerId, *input, input.Backup, 1)
|
||||
err = manager.checkCreateQuota(ctx, userCred, ownerId, *input, input.Backup, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1402,17 +1380,21 @@ func (manager *SGuestManager) checkCreateQuota(
|
||||
input api.ServerCreateInput,
|
||||
hasBackup bool,
|
||||
count int,
|
||||
) (*SQuota, *SRegionQuota, error) {
|
||||
) error {
|
||||
req, regionReq := getGuestResourceRequirements(ctx, userCred, input, ownerId, count, hasBackup)
|
||||
log.Debugf("computeQuota: %s", jsonutils.Marshal(req))
|
||||
log.Debugf("regionQuota: %s", jsonutils.Marshal(regionReq))
|
||||
|
||||
err := quotas.CheckSetPendingQuota(ctx, userCred, &req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return errors.Wrap(err, "quotas.CheckSetPendingQuota")
|
||||
}
|
||||
err = quotas.CheckSetPendingQuota(ctx, userCred, ®ionReq)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return errors.Wrap(err, "quotas.CheckSetPendingQuota")
|
||||
}
|
||||
return &req, ®ionReq, nil
|
||||
quotas.SavePendingUsagesInContext(ctx, &req, ®ionReq)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) checkUpdateQuota(ctx context.Context, userCred mcclient.TokenCredential, vcpuCount int, vmemSize int) (quotas.IQuota, error) {
|
||||
|
||||
@@ -84,6 +84,9 @@ func StartService() {
|
||||
cron.AddJobAtIntervals("StartHostPingDetectionTask", time.Duration(opts.HostOfflineDetectionInterval)*time.Second, models.HostManager.PingDetectionTask)
|
||||
|
||||
cron.AddJobAtIntervalsWithStartRun("CalculateQuotaUsages", time.Duration(opts.CalculateQuotaUsageIntervalSeconds)*time.Second, models.QuotaManager.CalculateQuotaUsages, true)
|
||||
cron.AddJobAtIntervalsWithStartRun("CalculateRegionQuotaUsages", time.Duration(opts.CalculateQuotaUsageIntervalSeconds)*time.Second, models.RegionQuotaManager.CalculateQuotaUsages, true)
|
||||
cron.AddJobAtIntervalsWithStartRun("CalculateZoneQuotaUsages", time.Duration(opts.CalculateQuotaUsageIntervalSeconds)*time.Second, models.ZoneQuotaManager.CalculateQuotaUsages, true)
|
||||
cron.AddJobAtIntervalsWithStartRun("CalculateProjectQuotaUsages", time.Duration(opts.CalculateQuotaUsageIntervalSeconds)*time.Second, models.ProjectQuotaManager.CalculateQuotaUsages, true)
|
||||
|
||||
cron.AddJobAtIntervalsWithStartRun("AutoSyncCloudaccountTask", time.Duration(opts.CloudAutoSyncIntervalSeconds)*time.Second, models.CloudaccountManager.AutoSyncCloudaccountTask, true)
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package predicates
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
computemodels "yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/api"
|
||||
@@ -110,20 +111,18 @@ func (p *SQuotaPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core
|
||||
minCnt := -1
|
||||
if !computePending.IsEmpty() {
|
||||
computeCnt, _ := quotas.GetQuotaCount(ctx, &computeQuota, computePending.GetKeys())
|
||||
if minCnt < 0 || minCnt > computeCnt {
|
||||
if computeCnt >= 0 && (minCnt < 0 || minCnt > computeCnt) {
|
||||
minCnt = computeCnt
|
||||
}
|
||||
}
|
||||
if !regionPending.IsEmpty() {
|
||||
regionCnt, _ := quotas.GetQuotaCount(ctx, ®ionQuota, regionPending.GetKeys())
|
||||
if minCnt < 0 || minCnt > regionCnt {
|
||||
if regionCnt >= 0 && (minCnt < 0 || minCnt > regionCnt) {
|
||||
minCnt = regionCnt
|
||||
}
|
||||
}
|
||||
|
||||
if minCnt == 0 {
|
||||
h.Exclude("quota limit")
|
||||
} else if minCnt > 0 {
|
||||
if minCnt >= 0 {
|
||||
h.SetCapacity(int64(minCnt))
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -297,7 +297,9 @@ func (b BaseHostDesc) GetResourceType() string {
|
||||
|
||||
func (b *BaseHostDesc) fillCloudProvider(host *computemodels.SHost) error {
|
||||
b.Cloudprovider = host.GetCloudprovider()
|
||||
b.Cloudaccount = b.Cloudprovider.GetCloudaccount()
|
||||
if b.Cloudprovider != nil {
|
||||
b.Cloudaccount = b.Cloudprovider.GetCloudaccount()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user