123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /*
- Copyright 2018 The Rook Authors. All rights reserved.
- 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 v1
- import (
- v1 "k8s.io/api/core/v1"
- )
- func (p PlacementSpec) All() Placement {
- return p[KeyAll]
- }
- // ApplyToPodSpec adds placement to a pod spec
- func (p Placement) ApplyToPodSpec(t *v1.PodSpec) {
- if t.Affinity == nil {
- t.Affinity = &v1.Affinity{}
- }
- if p.NodeAffinity != nil {
- t.Affinity.NodeAffinity = p.mergeNodeAffinity(t.Affinity.NodeAffinity)
- }
- if p.PodAffinity != nil {
- t.Affinity.PodAffinity = p.PodAffinity.DeepCopy()
- }
- if p.PodAntiAffinity != nil {
- t.Affinity.PodAntiAffinity = p.PodAntiAffinity.DeepCopy()
- }
- if p.Tolerations != nil {
- t.Tolerations = p.mergeTolerations(t.Tolerations)
- }
- if p.TopologySpreadConstraints != nil {
- t.TopologySpreadConstraints = p.TopologySpreadConstraints
- }
- }
- func (p Placement) mergeNodeAffinity(nodeAffinity *v1.NodeAffinity) *v1.NodeAffinity {
- // no node affinity is specified yet, so return the placement's nodeAffinity
- result := p.NodeAffinity.DeepCopy()
- if nodeAffinity == nil {
- return result
- }
- // merge the preferred node affinity that was already specified, and the placement's nodeAffinity
- result.PreferredDuringSchedulingIgnoredDuringExecution = append(
- nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution,
- p.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution...)
- // nothing to merge if no affinity was passed in
- if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
- return result
- }
- // take the desired affinity if there was none on the placement
- if p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
- result.RequiredDuringSchedulingIgnoredDuringExecution = nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution
- return result
- }
- // take the desired affinity node selectors without the need to merge
- if len(nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 {
- return result
- }
- // take the placement affinity node selectors without the need to merge
- if len(p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 {
- // take the placement from the first option since the second isn't specified
- result.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms =
- nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms
- return result
- }
- // merge the match expressions together since they are defined in both placements
- // this will only work if we want an "and" between all the expressions, more complex conditions won't work with this merge
- var nodeTerm v1.NodeSelectorTerm
- nodeTerm.MatchExpressions = append(
- nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions,
- p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions...)
- nodeTerm.MatchFields = append(
- nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields,
- p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields...)
- result.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0] = nodeTerm
- return result
- }
- func (p Placement) mergeTolerations(tolerations []v1.Toleration) []v1.Toleration {
- // no toleration is specified yet, return placement's toleration
- if tolerations == nil {
- return p.Tolerations
- }
- return append(p.Tolerations, tolerations...)
- }
- // Merge returns a Placement which results from merging the attributes of the
- // original Placement with the attributes of the supplied one. The supplied
- // Placement's attributes will override the original ones if defined.
- func (p Placement) Merge(with Placement) Placement {
- ret := p
- if with.NodeAffinity != nil {
- ret.NodeAffinity = with.NodeAffinity
- }
- if with.PodAffinity != nil {
- ret.PodAffinity = with.PodAffinity
- }
- if with.PodAntiAffinity != nil {
- ret.PodAntiAffinity = with.PodAntiAffinity
- }
- if with.Tolerations != nil {
- ret.Tolerations = ret.mergeTolerations(with.Tolerations)
- }
- if with.TopologySpreadConstraints != nil {
- ret.TopologySpreadConstraints = with.TopologySpreadConstraints
- }
- return ret
- }
- // GetMgrPlacement returns the placement for the MGR service
- func GetMgrPlacement(p PlacementSpec) Placement {
- return p.All().Merge(p[KeyMgr])
- }
- // GetMonPlacement returns the placement for the MON service
- func GetMonPlacement(p PlacementSpec) Placement {
- return p.All().Merge(p[KeyMon])
- }
- // GetArbiterPlacement returns the placement for the arbiter MON service
- func GetArbiterPlacement(p PlacementSpec) Placement {
- // If the mon is the arbiter in a stretch cluster and its placement is specified, return it
- // without merging with the "all" placement so it can be handled separately from all other daemons
- return p[KeyMonArbiter]
- }
- // GetOSDPlacement returns the placement for the OSD service
- func GetOSDPlacement(p PlacementSpec) Placement {
- return p.All().Merge(p[KeyOSD])
- }
|