quota_predicate.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package predicates
  15. import (
  16. "context"
  17. "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
  18. computemodels "yunion.io/x/onecloud/pkg/compute/models"
  19. "yunion.io/x/onecloud/pkg/scheduler/api"
  20. "yunion.io/x/onecloud/pkg/scheduler/core"
  21. "yunion.io/x/onecloud/pkg/scheduler/options"
  22. )
  23. type SQuotaPredicate struct {
  24. BasePredicate
  25. }
  26. func (p *SQuotaPredicate) Name() string {
  27. return "quota"
  28. }
  29. func (p *SQuotaPredicate) Clone() core.FitPredicate {
  30. return &SQuotaPredicate{}
  31. }
  32. func (p *SQuotaPredicate) PreExecute(ctx context.Context, u *core.Unit, cs []core.Candidater) (bool, error) {
  33. if !options.Options.EnableQuotaCheck {
  34. return false, nil
  35. }
  36. if len(u.SchedData().HostId) > 0 {
  37. return false, nil
  38. }
  39. return true, nil
  40. }
  41. func fetchGuestUsageFromSchedInfo(ctx context.Context, s *api.SchedInfo) (computemodels.SQuota, computemodels.SRegionQuota) {
  42. vcpuCount := s.Ncpu
  43. if vcpuCount == 0 {
  44. vcpuCount = 1
  45. }
  46. vmemSize := s.Memory
  47. diskSize := 0
  48. for _, diskConfig := range s.Disks {
  49. diskSize += diskConfig.SizeMb
  50. }
  51. devCount := len(s.IsolatedDevices)
  52. eNicCnt := 0
  53. iNicCnt := 0
  54. for _, netConfig := range s.Networks {
  55. if computemodels.IsExitNetworkInfo(ctx, s.UserCred, netConfig) {
  56. eNicCnt += 1
  57. } else {
  58. iNicCnt += 1
  59. }
  60. }
  61. req := computemodels.SQuota{
  62. Count: 1,
  63. Cpu: int(vcpuCount),
  64. Memory: int(vmemSize),
  65. Storage: diskSize,
  66. IsolatedDevice: devCount,
  67. }
  68. regionReq := computemodels.SRegionQuota{
  69. Port: iNicCnt,
  70. Eport: eNicCnt,
  71. }
  72. return req, regionReq
  73. }
  74. func (p *SQuotaPredicate) Execute(ctx context.Context, u *core.Unit, c core.Candidater) (bool, []core.PredicateFailureReason, error) {
  75. h := NewPredicateHelper(p, u, c)
  76. d := u.SchedData()
  77. computePending := computemodels.SQuota{}
  78. regionPending := computemodels.SRegionQuota{}
  79. if len(d.PendingUsages) > 0 {
  80. d.PendingUsages[0].Unmarshal(&computePending)
  81. }
  82. if len(d.PendingUsages) > 1 {
  83. d.PendingUsages[1].Unmarshal(&regionPending)
  84. }
  85. computePending.ProjectId = d.Project
  86. computePending.DomainId = d.Domain
  87. regionPending.ProjectId = d.Project
  88. regionPending.DomainId = d.Domain
  89. computeKeys := c.Getter().GetQuotaKeys(d)
  90. computeQuota, regionQuota := fetchGuestUsageFromSchedInfo(ctx, d)
  91. computeQuota.SetKeys(computeKeys)
  92. regionQuota.SetKeys(computeKeys.SRegionalCloudResourceKeys)
  93. minCnt := -1
  94. computeCnt, _ := quotas.GetQuotaCount(ctx, &computeQuota, computePending.GetKeys())
  95. if computeCnt >= 0 && (minCnt < 0 || minCnt > computeCnt) {
  96. minCnt = computeCnt
  97. }
  98. regionCnt, _ := quotas.GetQuotaCount(ctx, &regionQuota, regionPending.GetKeys())
  99. if regionCnt >= 0 && (minCnt < 0 || minCnt > regionCnt) {
  100. minCnt = regionCnt
  101. }
  102. if minCnt > 0 {
  103. h.SetCapacity(int64(minCnt))
  104. } else if minCnt == 0 {
  105. h.Exclude("out_of_quota")
  106. }
  107. return h.GetResult()
  108. }