mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-20 16:36:03 +08:00
119 lines
3.0 KiB
Go
119 lines
3.0 KiB
Go
// 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 handler
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"yunion.io/x/log"
|
|
|
|
"yunion.io/x/onecloud/pkg/scheduler/api"
|
|
"yunion.io/x/onecloud/pkg/scheduler/core"
|
|
)
|
|
|
|
func transToSchedForecastResult(result *core.SchedResultItemList) interface{} {
|
|
unit := result.Unit
|
|
schedData := unit.SchedData()
|
|
reqCount := int64(schedData.Count)
|
|
filters := make([]*api.ForecastFilter, 0)
|
|
|
|
filtersMap := make(map[string]*api.ForecastFilter)
|
|
getOrNewFilter := func(preName string) (*api.ForecastFilter, bool) {
|
|
if info, ok := filtersMap[preName]; !ok {
|
|
i := &api.ForecastFilter{
|
|
Filter: preName,
|
|
Count: 0,
|
|
Messages: make([]string, 0),
|
|
}
|
|
filtersMap[preName] = i
|
|
return i, false
|
|
} else {
|
|
return info, true
|
|
}
|
|
}
|
|
|
|
logIndex := func(item *core.SchedResultItem) string {
|
|
getter := item.Candidater.Getter()
|
|
name := getter.Name()
|
|
id := getter.Id()
|
|
return fmt.Sprintf("%s:%s", name, id)
|
|
}
|
|
addInfos := func(logs core.SchedLogList, item *core.SchedResultItem) {
|
|
for preName, cnt := range item.CapacityDetails {
|
|
if cnt > 0 {
|
|
continue
|
|
}
|
|
failedLog := logs.Get(logIndex(item))
|
|
if failedLog == nil {
|
|
log.Errorf("predicate %q count is 0, but not found failed log", preName)
|
|
continue
|
|
}
|
|
for _, msg := range failedLog.Messages {
|
|
info, exist := getOrNewFilter(msg.Type)
|
|
info.Count++
|
|
info.Messages = append(info.Messages, msg.Info)
|
|
if !exist {
|
|
filters = append(filters, info)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
items := make(core.SchedResultItems, 0)
|
|
for _, item := range result.Data {
|
|
hostType := item.Candidater.Getter().HostType()
|
|
if schedData.Hypervisor == hostType {
|
|
items = append(items, item)
|
|
}
|
|
}
|
|
|
|
for _, item := range items {
|
|
addInfos(result.Unit.LogManager.FailedLogs(), item)
|
|
}
|
|
|
|
var (
|
|
output = transToSchedResult(result, schedData)
|
|
readyCount int64
|
|
)
|
|
|
|
for _, candi := range output.Candidates {
|
|
if len(candi.Error) != 0 {
|
|
info, exist := getOrNewFilter("select_candidate")
|
|
msg := candi.Error
|
|
info.Messages = append(info.Messages, msg)
|
|
if !exist {
|
|
filters = append(filters, info)
|
|
}
|
|
} else {
|
|
readyCount++
|
|
}
|
|
}
|
|
|
|
canCreate := true
|
|
if readyCount < reqCount {
|
|
canCreate = false
|
|
filters = append(filters, &api.ForecastFilter{
|
|
Messages: []string{
|
|
fmt.Sprintf("No enough resources: %d/%d(free/request)", readyCount, reqCount),
|
|
},
|
|
})
|
|
}
|
|
return &api.SchedForecastResult{
|
|
CanCreate: canCreate,
|
|
Filters: filters,
|
|
Results: output.Candidates,
|
|
}
|
|
}
|