scheduler: add resource type filter

This commit is contained in:
Zexi Li
2018-12-07 15:45:03 +08:00
parent 1f5ab8750f
commit 4e344450c5
13 changed files with 118 additions and 21 deletions
@@ -24,6 +24,7 @@ const (
ErrNoMoreSpaceForUnspecificSplit = `no more space for an unspecific split`
ErrSubtotalOfSplitExceedsDiskSize = `subtotal of split exceeds disk size`
ErrBaremetalHasAlreadyBeenOccupied = `baremetal has already been occupied`
ErrPrepaidHostOccupied = `prepaid host occupied`
ErrUnknown = `unknown error`
)
@@ -0,0 +1,48 @@
package predicates
import (
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/scheduler/core"
)
type ResourceTypePredicate struct {
BasePredicate
}
func (p *ResourceTypePredicate) Name() string {
return "resource_type"
}
func (p *ResourceTypePredicate) Clone() core.FitPredicate {
return &ResourceTypePredicate{}
}
func (p *ResourceTypePredicate) PreExecute(u *core.Unit, cs []core.Candidater) (bool, error) {
if u.SchedData().ResourceType == "" {
return false, nil
}
return true, nil
}
func (p *ResourceTypePredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core.PredicateFailureReason, error) {
h := NewPredicateHelper(p, u, c)
d := u.SchedData()
hostResType := c.GetResourceType()
reqResType := d.ResourceType
if hostResType != reqResType {
h.Exclude2("resource_type", hostResType, reqResType)
}
if reqResType == models.HostResourceTypePrepaidRecycle {
if c.GetGuestCount() == 0 {
h.SetCapacity(1)
} else {
h.Exclude(ErrPrepaidHostOccupied)
}
}
// TODO: support HostResourceTypeDedicated
return h.GetResult()
}
@@ -20,5 +20,6 @@ func baremetalPredicates() sets.String {
factory.RegisterFitPredicate("d-BaremetalMemoryFilter", &predicatebm.MemoryPredicate{}),
factory.RegisterFitPredicate("e-BaremetalStorageFilter", &predicatebm.StoragePredicate{}),
factory.RegisterFitPredicate("f-BaremetalNetFilter", &predicatebm.NetworkPredicate{}),
factory.RegisterFitPredicate("g-BaremetalResourceTypeFilter", &predicates.ResourceTypePredicate{}),
)
}
@@ -25,6 +25,7 @@ func defaultPredicates() sets.String {
factory.RegisterFitPredicate("i-GuestStorageFilter", &predicateguest.StoragePredicate{}),
factory.RegisterFitPredicate("j-GuestNetworkFilter", &predicateguest.NetworkPredicate{}),
factory.RegisterFitPredicate("k-GuestIsolatedDeviceFilter", &predicateguest.IsolatedDevicePredicate{}),
factory.RegisterFitPredicate("l-GuestResourceTypeFilter", &predicates.ResourceTypePredicate{}),
)
}
+5
View File
@@ -94,6 +94,7 @@ type SchedData struct {
ForGuests []*ForGuest `json:"for_guests"`
GuestStatus string `json:"guest_status"`
Hypervisor string `json:"hypervisor"`
ResourceType string `json:"resource_type"`
// VM
Groups []string `json:"group"`
@@ -168,6 +169,10 @@ func NewSchedData(sjson *simplejson.Json, count int64, byTest bool) (*SchedData,
}
}
if resourceType, ok := sjson.CheckGet("resource_type"); ok {
data.ResourceType = resourceType.MustString()
}
data.Candidates = candidates
err := data.reviseSchedType(sjson)
+3 -10
View File
@@ -4,6 +4,8 @@ import (
"fmt"
"yunion.io/x/pkg/util/sets"
"yunion.io/x/onecloud/pkg/compute/models"
)
const (
@@ -16,10 +18,6 @@ const (
SchedTypeHyperV = "hyperv"
SchedTypeKvm = "kvm"
HostHypervisorForKvm = "hypervisor"
HostTypeAliyun = "aliyun"
HostTypeAzure = "azure"
HostTypeAws = "aws"
HostTypeQcloud = "qcloud"
HostTypeKubelet = "kubelet"
AggregateStrategyRequire = "require"
@@ -49,12 +47,7 @@ var (
AggregateStrategyAvoid,
)
PublicCloudProviders = sets.NewString(
HostTypeAliyun,
HostTypeAzure,
HostTypeAws,
HostTypeQcloud,
)
PublicCloudProviders = sets.NewString(models.PUBLIC_CLOUD_HYPERVISORS...)
ValidGpuTypes = sets.NewString(
GPU_HPC_TYPE,
+7
View File
@@ -104,6 +104,13 @@ func (bd *BaremetalDesc) Get(key string) interface{} {
}
}
func (bd *BaremetalDesc) GetGuestCount() int64 {
if bd.ServerID == "" {
return 0
}
return 1
}
func (bd *BaremetalDesc) XGet(key string, kind core.Kind) interface{} {
return core.XGetCalculator(bd, key, kind)
}
+29 -10
View File
@@ -8,6 +8,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
cloudmodels "yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/db/models"
)
@@ -24,6 +25,7 @@ func (b *baseDesc) UUID() string {
type baseHostDesc struct {
baseDesc
models.BillingResourceBase
ManagerID *string `json:"manager_id"`
Status string `json:"status"`
@@ -44,6 +46,15 @@ type baseHostDesc struct {
Aggregates []*models.Aggregate `json:"aggregates"`
HostAggregates []*models.Aggregate `json:"host_aggregates"`
Cloudprovider *models.Cloudprovider `json:"cloudprovider"`
ResourceType string `json:"resource_type"`
RealExternalId string `json:"real_external_id"`
}
func reviseResourceType(resType string) string {
if resType == "" {
return cloudmodels.HostResourceTypeDefault
}
return resType
}
func newBaseHostDesc(host *models.Host) (*baseHostDesc, error) {
@@ -53,16 +64,19 @@ func newBaseHostDesc(host *models.Host) (*baseHostDesc, error) {
Name: host.Name,
UpdatedAt: host.UpdatedAt,
},
ManagerID: host.ManagerID,
Status: host.Status,
CPUCount: host.CPUCount,
MemSize: host.MemSize,
HostStatus: host.HostStatus,
Enabled: host.Enabled,
HostType: host.HostType,
IsBaremetal: host.IsBaremetal,
NodeCount: host.NodeCount,
IsMaintenance: host.IsMaintenance,
BillingResourceBase: host.BillingResourceBase,
ManagerID: host.ManagerID,
Status: host.Status,
CPUCount: host.CPUCount,
MemSize: host.MemSize,
HostStatus: host.HostStatus,
Enabled: host.Enabled,
HostType: host.HostType,
IsBaremetal: host.IsBaremetal,
NodeCount: host.NodeCount,
IsMaintenance: host.IsMaintenance,
ResourceType: reviseResourceType(host.ResourceType),
RealExternalId: host.RealExternalId,
}
if err := desc.fillCloudProvider(host); err != nil {
@@ -97,6 +111,7 @@ func (b baseHostDesc) GetSchedDesc() *jsonutils.JSONDict {
desc.Add(jsonutils.NewString(b.HostType), "host_type")
desc.Add(jsonutils.NewString(b.ZoneID), "zone_id")
desc.Add(jsonutils.NewString(b.Zone), "zone")
desc.Add(jsonutils.NewString(b.ResourceType), "resource_type")
if b.Cloudprovider != nil {
p := b.Cloudprovider
@@ -109,6 +124,10 @@ func (b baseHostDesc) GetSchedDesc() *jsonutils.JSONDict {
return desc
}
func (b baseHostDesc) GetResourceType() string {
return b.ResourceType
}
func (b *baseHostDesc) fillCloudProvider(host *models.Host) error {
if host.ManagerID == nil {
log.Debugf("Host %q manager id is empty, no cloud provider", host.Name)
+5 -1
View File
@@ -224,6 +224,10 @@ func (h *HostDesc) Type() int {
return 0
}
func (h *HostDesc) GetGuestCount() int64 {
return h.GuestCount
}
func (h *HostDesc) Get(key string) interface{} {
switch key {
case "ID":
@@ -953,7 +957,7 @@ func (b *HostBuilder) build() ([]interface{}, error) {
if len(errs) > 0 {
//return nil, errors.NewAggregate(errs)
err := errors.NewAggregate(errs)
log.Warningf("Build schedule descs error: %s", err)
log.V(4).Warningf("Build schedule descs error: %s", err)
}
return schedDescs, nil
+1
View File
@@ -7,6 +7,7 @@ import (
"sync"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/scheduler/api"
)
+2
View File
@@ -49,6 +49,8 @@ type Candidater interface {
GetHostAggregates() []*models.Aggregate
GetSchedDesc() *jsonutils.JSONDict
GetGuestCount() int64
GetResourceType() string
}
// HostPriority represents the priority of scheduling to particular host, higher priority is better.
+11
View File
@@ -0,0 +1,11 @@
package models
import (
"time"
)
type BillingResourceBase struct {
BillingType string `json:"billing_type" gorm:"column:billing_type"`
ExpiredAt time.Time `json:"expired_at" gorm:"column:expired_at;type:datetime"`
BillingCycle string `json:"billing_cycle" gorm:"column:billing_cycle"`
}
+4
View File
@@ -20,6 +20,7 @@ var (
type Host struct {
StandaloneModel
BillingResourceBase
Rack string `json:"rack,omitempty" gorm:"column:rack"`
Slots string `json:"slots,omitempty" gorm:"column:slots"`
@@ -57,6 +58,9 @@ type Host struct {
ManagerID *string `json:"manager_id" gorm:"column:manager_id"`
IsMaintenance bool `json:"is_maintenance" gorm:"column:is_maintenance"`
ResourceType string `json:"resource_type" gorm:"column:resource_type"`
RealExternalId string `json:"real_external_id" gorm:"column:real_external_id;type:varchar(256) CHARACTER SET utf8"`
// DECAPITATE
ClusterID string `json:"cluster_id" gorm:"column:cluster_id"`
PoolID string `json:"pool_id,omitempty" gorm:"column:pool_id"`