diff --git a/pkg/scheduler/algorithm/predicates/k8s/doc.go b/pkg/scheduler/algorithm/predicates/k8s/doc.go deleted file mode 100644 index 388e288c02..0000000000 --- a/pkg/scheduler/algorithm/predicates/k8s/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 k8s // import "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates/k8s" diff --git a/pkg/scheduler/algorithm/predicates/k8s/host_status_predicate.go b/pkg/scheduler/algorithm/predicates/k8s/host_status_predicate.go deleted file mode 100644 index 8dea392aa1..0000000000 --- a/pkg/scheduler/algorithm/predicates/k8s/host_status_predicate.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 k8s - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - - "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates/guest" - "yunion.io/x/onecloud/pkg/scheduler/cache/candidate" -) - -type HostStatusPredicate struct{} - -func (p *HostStatusPredicate) Clone() IPredicate { - return &HostStatusPredicate{} -} - -func (p *HostStatusPredicate) Name() string { - return "host_status" -} - -func (p *HostStatusPredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool { - return true -} - -func (p *HostStatusPredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) { - if host.Status != guest.ExpectedStatus { - return false, fmt.Errorf("Host status is %s", host.Status) - } - - if !host.GetEnabled() { - return false, fmt.Errorf("Host is disabled") - } - return true, nil -} diff --git a/pkg/scheduler/algorithm/predicates/k8s/k8s.go b/pkg/scheduler/algorithm/predicates/k8s/k8s.go deleted file mode 100644 index a62be3618d..0000000000 --- a/pkg/scheduler/algorithm/predicates/k8s/k8s.go +++ /dev/null @@ -1,97 +0,0 @@ -// 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 k8s - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - - "yunion.io/x/onecloud/pkg/scheduler/cache/candidate" -) - -var PredicatesManager *SPredicatesManager - -func init() { - PredicatesManager = newPredicatesManager() - - PredicatesManager.Register( - &HostStatusPredicate{}, - &NetworkPredicate{}, - &LocalVolumePredicate{}, - ) -} - -type IPredicate interface { - Name() string - Clone() IPredicate - PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool - Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) -} - -type SPredicatesManager struct { - predicates []IPredicate -} - -func newPredicatesManager() *SPredicatesManager { - man := &SPredicatesManager{ - predicates: make([]IPredicate, 0), - } - return man -} - -func (man *SPredicatesManager) Register(pres ...IPredicate) *SPredicatesManager { - for _, pre := range pres { - if !man.Has(pre) { - man.predicates = append(man.predicates, pre) - } - } - return man -} - -func (man *SPredicatesManager) Has(newPre IPredicate) bool { - if len(man.predicates) == 0 { - return false - } - for _, pre := range man.predicates { - if pre.Name() == newPre.Name() { - return true - } - } - return false -} - -func (man *SPredicatesManager) DoFilter( - k8sCli *kubernetes.Clientset, - pod *v1.Pod, - node *v1.Node, - host *candidate.HostDesc, -) (bool, error) { - for _, pre := range man.predicates { - tmpPre := pre.Clone() - if !tmpPre.PreExecute(k8sCli, pod, node, host) { - continue - } - fit, err := tmpPre.Execute(k8sCli, pod, node, host) - if err != nil { - return false, err - } - if !fit { - return false, fmt.Errorf("Filtered by %s", tmpPre.Name()) - } - } - return true, nil -} diff --git a/pkg/scheduler/algorithm/predicates/k8s/network_predicate.go b/pkg/scheduler/algorithm/predicates/k8s/network_predicate.go deleted file mode 100644 index 0240c5fb74..0000000000 --- a/pkg/scheduler/algorithm/predicates/k8s/network_predicate.go +++ /dev/null @@ -1,124 +0,0 @@ -// 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 k8s - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - - "yunion.io/x/pkg/util/errors" - "yunion.io/x/pkg/util/netutils" - - "yunion.io/x/onecloud/pkg/compute/models" - "yunion.io/x/onecloud/pkg/scheduler/api" - "yunion.io/x/onecloud/pkg/scheduler/cache/candidate" -) - -const ( - // k8s annotations for create pod - YUNION_CNI_NETWORK_ANNOTATION = "cni.yunion.io/network" - YUNION_CNI_IPADDR_ANNOTATION = "cni.yunion.io/ip" -) - -type NetworkPredicate struct { - network string - ipAddr string -} - -func (p *NetworkPredicate) Clone() IPredicate { - return &NetworkPredicate{} -} - -func (p *NetworkPredicate) Name() string { - return "network" -} - -func (p *NetworkPredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool { - net, netCont := pod.Annotations[YUNION_CNI_NETWORK_ANNOTATION] - ipAddr, ipCont := pod.Annotations[YUNION_CNI_IPADDR_ANNOTATION] - p.network = net - p.ipAddr = ipAddr - return netCont || ipCont -} - -func (p *NetworkPredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) { - hostNets := host.Networks - if p.network != "" { - err := p.checkByNetworks(hostNets) - if err != nil { - return false, err - } - } - if p.ipAddr != "" { - err := p.checkNetworksIP(p.ipAddr, hostNets) - if err != nil { - return false, err - } - } - return true, nil -} - -func (p NetworkPredicate) checkByNetworks(nets []*api.CandidateNetwork) error { - if len(nets) == 0 { - return fmt.Errorf("Network is empty") - } - errs := make([]error, 0) - for _, net := range nets { - err := p.checkByNetwork(net.SNetwork) - if err == nil { - return nil - } - errs = append(errs, err) - } - return errors.NewAggregate(errs) -} - -func (p NetworkPredicate) checkByNetwork(net *models.SNetwork) error { - if net.GetPorts() <= 0 { - return fmt.Errorf("Network %s no free IPs", net.Name) - } - if !(p.network == net.Name || p.network == net.Id) { - return fmt.Errorf("Network %s:%s or id not match %s", net.Name, net.Id, p.network) - } - return nil -} - -func (p NetworkPredicate) checkNetworksIP(ip string, nets []*api.CandidateNetwork) error { - if len(nets) == 0 { - return fmt.Errorf("Network is empty") - } - errs := make([]error, 0) - for _, net := range nets { - err := p.checkNetworkIP(ip, net.SNetwork) - if err == nil { - return nil - } - errs = append(errs, err) - } - return errors.NewAggregate(errs) -} - -func (p NetworkPredicate) checkNetworkIP(ip string, net *models.SNetwork) error { - ipAddr, err := netutils.NewIPV4Addr(ip) - if err != nil { - return err - } - if ok := net.GetIPRange().Contains(ipAddr); !ok { - return fmt.Errorf("Network %s not contains ip %s", net.Name, ip) - } - return nil -} diff --git a/pkg/scheduler/algorithm/predicates/k8s/volume_predicate.go b/pkg/scheduler/algorithm/predicates/k8s/volume_predicate.go deleted file mode 100644 index 33851931b0..0000000000 --- a/pkg/scheduler/algorithm/predicates/k8s/volume_predicate.go +++ /dev/null @@ -1,103 +0,0 @@ -// 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 k8s - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - - "yunion.io/x/log" - - "yunion.io/x/onecloud/pkg/scheduler/cache/candidate" -) - -const ( - YUNION_CSI_STORAGECLASS = "csi-yunion" -) - -type LocalVolumePredicate struct { - pvcs []*v1.PersistentVolumeClaim -} - -func (p *LocalVolumePredicate) Clone() IPredicate { - return &LocalVolumePredicate{} -} - -func (p *LocalVolumePredicate) Name() string { - return "local-volume" -} - -func (p *LocalVolumePredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool { - if cli == nil { - log.Errorf("k8s client is nil, not execute %s filter", p.Name()) - return false - } - pvcs := make([]*v1.PersistentVolumeClaim, 0) - if pod.Spec.Volumes != nil && len(pod.Spec.Volumes) > 0 { - for _, v := range pod.Spec.Volumes { - if v.PersistentVolumeClaim == nil { - continue - } - pvcName := v.PersistentVolumeClaim.ClaimName - pvc, err := cli.CoreV1().PersistentVolumeClaims(pod.Namespace).Get(pvcName, metav1.GetOptions{}) - if err != nil { - log.Warningf("Not found pvc %s for pod %s/%s", pvcName, pod.Namespace, pod.Name) - return false - } - // pvc's StorageClassName must "csi-yunion" - if pvc.Spec.StorageClassName != nil && *(pvc.Spec.StorageClassName) != YUNION_CSI_STORAGECLASS { - continue - } - pvcs = append(pvcs, pvc) - } - } - p.pvcs = pvcs - return len(pvcs) != 0 -} - -func (p *LocalVolumePredicate) getPvcRequestSize(pvc *v1.PersistentVolumeClaim) int64 { - req := pvc.Spec.Resources.Requests[v1.ResourceStorage] - return req.Value() -} - -func (p *LocalVolumePredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) { - var reqSize int64 - for _, pvc := range p.pvcs { - pvName := pvc.Spec.VolumeName - if pvName != "" { - pv, _ := cli.CoreV1().PersistentVolumes().Get(pvName, metav1.GetOptions{}) - if pv != nil { - // PersistentVolume already exists - log.V(10).Debugf("PV %s already exists", pv) - continue - } - } - reqSize += p.getPvcRequestSize(pvc) - } - reqSizeMB := reqSize / 1024 / 1024 - return p.canHostStorageCreateVol(host, reqSizeMB) -} - -func (p *LocalVolumePredicate) canHostStorageCreateVol(host *candidate.HostDesc, reqSize int64) (bool, error) { - freeSize := host.GetFreeStorageSizeOfType("local", false) - log.Debugf("[host %s] PVC request %dMB, free %dMB", host.Name, reqSize, freeSize) - if freeSize > reqSize { - return true, nil - } - return false, fmt.Errorf("Out of local storage for volume: %d/%d (request/free)MB", reqSize, freeSize) -}