diff --git a/pkg/scheduler/algorithm/predicates/network_base_predicate.go b/pkg/scheduler/algorithm/predicates/network_base_predicate.go new file mode 100644 index 00000000000..41d736f8e58 --- /dev/null +++ b/pkg/scheduler/algorithm/predicates/network_base_predicate.go @@ -0,0 +1,74 @@ +// 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 predicates + +import ( + "context" + + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/sets" + + "yunion.io/x/onecloud/pkg/scheduler/core" + schedmodels "yunion.io/x/onecloud/pkg/scheduler/models" +) + +type NetworkBasePredicate struct { + NetworkNicCountGetter INetworkNicCountGetter + networkFreePortCount map[string]int +} + +func NewNetworkBasePredicate() *NetworkBasePredicate { + return &NetworkBasePredicate{ + NetworkNicCountGetter: nil, + networkFreePortCount: make(map[string]int), + } +} + +func (p *NetworkBasePredicate) Clone() *NetworkBasePredicate { + return &NetworkBasePredicate{ + NetworkNicCountGetter: p.NetworkNicCountGetter, + networkFreePortCount: p.networkFreePortCount, + } +} + +func (p *NetworkBasePredicate) PreExecute(ctx context.Context, u *core.Unit, cs []core.Candidater) (bool, error) { + networkIds := sets.NewString() + for i := range cs { + for _, net := range cs[i].Getter().Networks() { + networkIds.Insert(net.GetId()) + } + } + + if p.NetworkNicCountGetter != nil { + netCounts, err := p.NetworkNicCountGetter.GetTotalNicCount(networkIds.UnsortedList()) + if err != nil { + return false, errors.Wrap(err, "unable to GetTotalNicCount") + } + for i := range cs { + for _, net := range cs[i].Getter().Networks() { + p.networkFreePortCount[net.Id] = net.GetTotalAddressCount() - netCounts[net.Id] + } + } + } + + return true, nil +} + +func (p *NetworkBasePredicate) GetFreePort(id string, c core.Candidater) int { + if _, ok := p.networkFreePortCount[id]; ok { + return p.networkFreePortCount[id] - schedmodels.HostPendingUsageManager.GetNetPendingUsage(id) + } + return c.Getter().GetFreePort(id) +} diff --git a/pkg/scheduler/algorithm/predicates/network_predicate.go b/pkg/scheduler/algorithm/predicates/network_predicate.go index be9c86be345..90c492c6c0d 100644 --- a/pkg/scheduler/algorithm/predicates/network_predicate.go +++ b/pkg/scheduler/algorithm/predicates/network_predicate.go @@ -18,10 +18,8 @@ import ( "context" "fmt" - "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/netutils" "yunion.io/x/pkg/util/rbacscope" - "yunion.io/x/pkg/util/sets" "yunion.io/x/pkg/utils" computeapi "yunion.io/x/onecloud/pkg/apis/compute" @@ -30,7 +28,6 @@ import ( "yunion.io/x/onecloud/pkg/scheduler/algorithm/plugin" "yunion.io/x/onecloud/pkg/scheduler/api" "yunion.io/x/onecloud/pkg/scheduler/core" - schedmodels "yunion.io/x/onecloud/pkg/scheduler/models" ) // NetworkPredicate will filter the current network information with @@ -39,14 +36,12 @@ import ( type NetworkPredicate struct { BasePredicate plugin.BasePlugin - NetworkNicCountGetter INetworkNicCountGetter - networkFreePortCount map[string]int + *NetworkBasePredicate } func NewNetworkPredicate() *NetworkPredicate { return &NetworkPredicate{ - NetworkNicCountGetter: nil, - networkFreePortCount: make(map[string]int), + NetworkBasePredicate: NewNetworkBasePredicate(), } } @@ -65,8 +60,7 @@ func (p *NetworkPredicate) Name() string { func (p *NetworkPredicate) Clone() core.FitPredicate { return &NetworkPredicate{ - NetworkNicCountGetter: p.NetworkNicCountGetter, - networkFreePortCount: p.networkFreePortCount, + NetworkBasePredicate: p.NetworkBasePredicate.Clone(), } } @@ -80,30 +74,10 @@ func (p *NetworkPredicate) PreExecute(ctx context.Context, u *core.Unit, cs []co if data.ResetCpuNumaPin { return false, nil } - if len(data.Networks) == 0 { return false, nil } - networkIds := sets.NewString() - for i := range cs { - for _, net := range cs[i].Getter().Networks() { - networkIds.Insert(net.GetId()) - } - } - - if p.NetworkNicCountGetter != nil { - netCounts, err := p.NetworkNicCountGetter.GetTotalNicCount(networkIds.UnsortedList()) - if err != nil { - return false, errors.Wrap(err, "unable to GetTotalNicCount") - } - for i := range cs { - for _, net := range cs[i].Getter().Networks() { - p.networkFreePortCount[net.Id] = net.GetTotalAddressCount() - netCounts[net.Id] - } - } - } - - return true, nil + return p.NetworkBasePredicate.PreExecute(ctx, u, cs) } func IsNetworksAvailable(ctx context.Context, c core.Candidater, data *api.SchedInfo, req *computeapi.NetworkConfig, networks []*api.CandidateNetwork, netTypes []string, getFreePort func(string) int) (int, []core.PredicateFailureReason) { @@ -314,16 +288,11 @@ func (p *NetworkPredicate) Execute(ctx context.Context, u *core.Unit, c core.Can networks := getter.Networks() d := u.SchedData() - getFreePort := func(id string) int { - if _, ok := p.networkFreePortCount[id]; ok { - return p.networkFreePortCount[id] - schedmodels.HostPendingUsageManager.GetNetPendingUsage(id) - } - return c.Getter().GetFreePort(id) - } - for _, reqNet := range d.Networks { netTypes := p.GetNetworkTypes(u, reqNet.NetType) - freePortCnt, errs := IsNetworksAvailable(ctx, c, d, reqNet, networks, netTypes, getFreePort) + freePortCnt, errs := IsNetworksAvailable(ctx, c, d, reqNet, networks, netTypes, func(id string) int { + return p.GetFreePort(id, c) + }) if len(errs) > 0 { h.ExcludeByErrors(errs) return h.GetResult() diff --git a/pkg/scheduler/algorithm/predicates/network_schedtag_predicate.go b/pkg/scheduler/algorithm/predicates/network_schedtag_predicate.go index c341ea769c7..f817bc66821 100644 --- a/pkg/scheduler/algorithm/predicates/network_schedtag_predicate.go +++ b/pkg/scheduler/algorithm/predicates/network_schedtag_predicate.go @@ -20,6 +20,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" computeapi "yunion.io/x/onecloud/pkg/apis/compute" schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" @@ -29,20 +30,37 @@ import ( type NetworkSchedtagPredicate struct { *BaseSchedtagPredicate + *NetworkBasePredicate } func (p *NetworkSchedtagPredicate) Name() string { return "network_schedtag" } +func NewNetworkSchedtagPredicate() core.FitPredicate { + return &NetworkSchedtagPredicate{ + BaseSchedtagPredicate: NewBaseSchedtagPredicate(), + NetworkBasePredicate: NewNetworkBasePredicate(), + } +} + func (p *NetworkSchedtagPredicate) Clone() core.FitPredicate { return &NetworkSchedtagPredicate{ BaseSchedtagPredicate: NewBaseSchedtagPredicate(), + NetworkBasePredicate: p.NetworkBasePredicate.Clone(), } } func (p *NetworkSchedtagPredicate) PreExecute(ctx context.Context, u *core.Unit, cs []core.Candidater) (bool, error) { - return p.BaseSchedtagPredicate.PreExecute(ctx, p, u, cs) + ok, err := p.BaseSchedtagPredicate.PreExecute(ctx, p, u, cs) + if err != nil { + return false, errors.Wrap(err, "schedtag predicate") + } + ok, err = p.NetworkBasePredicate.PreExecute(ctx, u, cs) + if err != nil { + return false, errors.Wrap(err, "network predicate") + } + return ok, nil } type netW struct { @@ -99,7 +117,9 @@ func (p *NetworkSchedtagPredicate) IsResourceMatchInput(ctx context.Context, inp func (p *NetworkSchedtagPredicate) IsResourceFitInput(ctx context.Context, u *core.Unit, c core.Candidater, res ISchedtagCandidateResource, input ISchedtagCustomer) core.PredicateFailureReason { network := res.(*api.CandidateNetwork) net := input.(*netW) - return IsNetworkAvailable(ctx, c, u.SchedData(), net.NetworkConfig, network, p.GetNetworkTypes(net.NetType), nil) + return IsNetworkAvailable(ctx, c, u.SchedData(), net.NetworkConfig, network, p.GetNetworkTypes(net.NetType), func(id string) int { + return p.GetFreePort(id, c) + }) } func (p *NetworkSchedtagPredicate) GetNetworkTypes(specifyType string) []string { diff --git a/pkg/scheduler/algorithmprovider/baremetal.go b/pkg/scheduler/algorithmprovider/baremetal.go index 960d374cf73..8e854eb2c85 100644 --- a/pkg/scheduler/algorithmprovider/baremetal.go +++ b/pkg/scheduler/algorithmprovider/baremetal.go @@ -34,10 +34,10 @@ func baremetalPredicates() sets.String { factory.RegisterFitPredicate("c-BaremetalCPUFilter", &predicatebm.CPUPredicate{}), factory.RegisterFitPredicate("d-BaremetalMemoryFilter", &predicatebm.MemoryPredicate{}), factory.RegisterFitPredicate("e-BaremetalStorageFilter", &predicatebm.StoragePredicate{}), - factory.RegisterFitPredicate("f-BaremetalNetFilter", predicates.NewNetworkPredicate()), + factory.RegisterFitPredicate("f-BaremetalNetFilter", predicates.NewNetworkPredicateWithNicCounter()), factory.RegisterFitPredicate("g-BaremetalResourceTypeFilter", &predicates.ResourceTypePredicate{}), factory.RegisterFitPredicate("h-DiskschedtagFilter", &predicates.DiskSchedtagPredicate{}), - factory.RegisterFitPredicate("i-NetschedtagFilter", &predicates.NetworkSchedtagPredicate{}), + factory.RegisterFitPredicate("i-NetschedtagFilter", predicates.NewNetworkSchedtagPredicate()), factory.RegisterFitPredicate("k-NetBondingFilter", &predicatebm.NetBondingPredicate{}), factory.RegisterFitPredicate("l-CdromFilter", &predicatebm.CdromBootPredicate{}), factory.RegisterFitPredicate("m-IsolatedDevicesFilter", &predicates.IsolatedDevicePredicate{}), diff --git a/pkg/scheduler/algorithmprovider/defaults.go b/pkg/scheduler/algorithmprovider/defaults.go index f6d225a73d2..c760308b3ee 100644 --- a/pkg/scheduler/algorithmprovider/defaults.go +++ b/pkg/scheduler/algorithmprovider/defaults.go @@ -45,7 +45,7 @@ func defaultPredicates() sets.String { factory.RegisterFitPredicate("l-GuestResourceTypeFilter", &predicates.ResourceTypePredicate{}), factory.RegisterFitPredicate("m-GuestDiskschedtagFilter", &predicates.DiskSchedtagPredicate{}), factory.RegisterFitPredicate("n-ServerSkuFilter", &predicates.InstanceTypePredicate{}), - factory.RegisterFitPredicate("o-GuestNetschedtagFilter", &predicates.NetworkSchedtagPredicate{}), + factory.RegisterFitPredicate("o-GuestNetschedtagFilter", predicates.NewNetworkSchedtagPredicate()), factory.RegisterFitPredicate("p-CloudproviderschedtagFilter", predicates.NewCloudproviderSchedtagPredicate()), factory.RegisterFitPredicate("q-CloudregionschedtagFilter", predicates.NewCloudregionSchedtagPredicate()), factory.RegisterFitPredicate("r-ZoneschedtagFilter", predicates.NewZoneSchedtagPredicate()),