github.com/docker/compose-on-kubernetes@v0.5.0/internal/convert/placement.go (about) 1 package convert 2 3 import ( 4 "github.com/docker/compose-on-kubernetes/api/compose/latest" 5 "github.com/pkg/errors" 6 apiv1 "k8s.io/api/core/v1" 7 ) 8 9 const ( 10 kubernetesOs = "beta.kubernetes.io/os" 11 kubernetesArch = "beta.kubernetes.io/arch" 12 kubernetesHostname = "kubernetes.io/hostname" 13 ) 14 15 // node.id Node ID node.id == 2ivku8v2gvtg4 16 // node.hostname Node hostname node.hostname != node-2 17 // node.role Node role node.role == manager 18 // node.labels user defined node labels node.labels.security == high 19 // engine.labels Docker Engine's labels engine.labels.operatingsystem == ubuntu 14.04 20 func toNodeAffinity(constraints *latest.Constraints) (*apiv1.Affinity, error) { 21 if constraints == nil { 22 constraints = &latest.Constraints{} 23 } 24 requirements := []apiv1.NodeSelectorRequirement{} 25 if constraints.OperatingSystem != nil { 26 operator, err := toRequirementOperator(constraints.OperatingSystem.Operator) 27 if err != nil { 28 return nil, err 29 } 30 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 31 Key: kubernetesOs, 32 Operator: operator, 33 Values: []string{constraints.OperatingSystem.Value}, 34 }) 35 } 36 if constraints.Architecture != nil { 37 operator, err := toRequirementOperator(constraints.Architecture.Operator) 38 if err != nil { 39 return nil, err 40 } 41 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 42 Key: kubernetesArch, 43 Operator: operator, 44 Values: []string{constraints.Architecture.Value}, 45 }) 46 } 47 if constraints.Hostname != nil { 48 operator, err := toRequirementOperator(constraints.Hostname.Operator) 49 if err != nil { 50 return nil, err 51 } 52 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 53 Key: kubernetesHostname, 54 Operator: operator, 55 Values: []string{constraints.Hostname.Value}, 56 }) 57 } 58 if constraints.MatchLabels != nil { 59 for key, constraint := range constraints.MatchLabels { 60 operator, err := toRequirementOperator(constraint.Operator) 61 if err != nil { 62 return nil, err 63 } 64 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 65 Key: key, 66 Operator: operator, 67 Values: []string{constraint.Value}, 68 }) 69 } 70 } 71 if !hasRequirement(requirements, kubernetesOs) { 72 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 73 Key: kubernetesOs, 74 Operator: apiv1.NodeSelectorOpIn, 75 Values: []string{"linux"}, 76 }) 77 } 78 if !hasRequirement(requirements, kubernetesArch) { 79 requirements = append(requirements, apiv1.NodeSelectorRequirement{ 80 Key: kubernetesArch, 81 Operator: apiv1.NodeSelectorOpIn, 82 Values: []string{"amd64"}, 83 }) 84 } 85 return &apiv1.Affinity{ 86 NodeAffinity: &apiv1.NodeAffinity{ 87 RequiredDuringSchedulingIgnoredDuringExecution: &apiv1.NodeSelector{ 88 NodeSelectorTerms: []apiv1.NodeSelectorTerm{ 89 { 90 MatchExpressions: requirements, 91 }, 92 }, 93 }, 94 }, 95 }, nil 96 } 97 98 func hasRequirement(requirements []apiv1.NodeSelectorRequirement, key string) bool { 99 for _, r := range requirements { 100 if r.Key == key { 101 return true 102 } 103 } 104 return false 105 } 106 107 func toRequirementOperator(sign string) (apiv1.NodeSelectorOperator, error) { 108 switch sign { 109 case "==": 110 return apiv1.NodeSelectorOpIn, nil 111 case "!=": 112 return apiv1.NodeSelectorOpNotIn, nil 113 case ">": 114 return apiv1.NodeSelectorOpGt, nil 115 case "<": 116 return apiv1.NodeSelectorOpLt, nil 117 default: 118 return "", errors.Errorf("operator %s not supported", sign) 119 } 120 }