From bf3275feaee762c1b477b645e921c58116731888 Mon Sep 17 00:00:00 2001 From: Corey Daley Date: Mon, 1 Jan 2018 23:11:19 -0500 Subject: [PATCH] Ability to specify default tolerations via the buildconfig defaulter Trello: https://trello.com/c/LNxlMjjU/1435-5-ability-to-specify-default-tolerations-via-the-buildconfig-defaulter-builds --- .../informers/internalversion/factory.go | 7 ++-- .../informers/internalversion/generic.go | 1 - .../controller/build/defaults/defaults.go | 29 +++++++-------- .../controller/build/overrides/api/types.go | 5 +++ .../build/overrides/api/v1/types.go | 5 +++ .../overrides/api/v1/zz_generated.deepcopy.go | 8 +++++ .../overrides/api/zz_generated.deepcopy.go | 8 +++++ .../controller/build/overrides/overrides.go | 21 +++++++++++ test/integration/buildpod_admission_test.go | 35 +++++++++++++++++++ 9 files changed, 97 insertions(+), 22 deletions(-) diff --git a/pkg/apps/generated/informers/internalversion/factory.go b/pkg/apps/generated/informers/internalversion/factory.go index 0c8e20cb3ac2..96314f198aa4 100644 --- a/pkg/apps/generated/informers/internalversion/factory.go +++ b/pkg/apps/generated/informers/internalversion/factory.go @@ -3,10 +3,6 @@ package internalversion import ( - reflect "reflect" - sync "sync" - time "time" - apps "github.com/openshift/origin/pkg/apps/generated/informers/internalversion/apps" internalinterfaces "github.com/openshift/origin/pkg/apps/generated/informers/internalversion/internalinterfaces" internalclientset "github.com/openshift/origin/pkg/apps/generated/internalclientset" @@ -14,6 +10,9 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" + reflect "reflect" + sync "sync" + time "time" ) type sharedInformerFactory struct { diff --git a/pkg/apps/generated/informers/internalversion/generic.go b/pkg/apps/generated/informers/internalversion/generic.go index e7c603451116..048b55083be1 100644 --- a/pkg/apps/generated/informers/internalversion/generic.go +++ b/pkg/apps/generated/informers/internalversion/generic.go @@ -4,7 +4,6 @@ package internalversion import ( "fmt" - apps "github.com/openshift/origin/pkg/apps/apis/apps" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" diff --git a/pkg/build/controller/build/defaults/defaults.go b/pkg/build/controller/build/defaults/defaults.go index 51b67c973cf6..8ef021678d20 100644 --- a/pkg/build/controller/build/defaults/defaults.go +++ b/pkg/build/controller/build/defaults/defaults.go @@ -45,9 +45,9 @@ func (b BuildDefaults) ApplyDefaults(pod *v1.Pod) error { } glog.V(4).Infof("Applying defaults to build %s/%s", build.Namespace, build.Name) - b.applyBuildDefaults(build) + glog.V(4).Infof("Applying defaults to pod %s/%s", pod.Namespace, pod.Name) b.applyPodDefaults(pod) err = buildadmission.SetPodLogLevelFromBuild(pod, build) @@ -68,11 +68,13 @@ func (b BuildDefaults) applyPodDefaults(pod *v1.Pod) { } } - if len(b.config.Annotations) != 0 && pod.Annotations == nil { - pod.Annotations = map[string]string{} - } - for k, v := range b.config.Annotations { - addDefaultAnnotations(k, v, pod.Annotations) + if len(b.config.Annotations) != 0 { + if pod.Annotations == nil { + pod.Annotations = map[string]string{} + } + for k, v := range b.config.Annotations { + addDefaultAnnotation(k, v, pod.Annotations) + } } // Apply default resources @@ -187,29 +189,22 @@ func addDefaultEnvVar(build *buildapi.Build, v kapi.EnvVar) { } func addDefaultLabel(defaultLabel buildapi.ImageLabel, buildLabels *[]buildapi.ImageLabel) { - found := false for _, lbl := range *buildLabels { if lbl.Name == defaultLabel.Name { - found = true + return } } - if !found { - *buildLabels = append(*buildLabels, defaultLabel) - } + *buildLabels = append(*buildLabels, defaultLabel) } -func addDefaultNodeSelector(k, v string, selectors map[string]string) bool { +func addDefaultNodeSelector(k, v string, selectors map[string]string) { if _, ok := selectors[k]; !ok { selectors[k] = v - return true } - return false } -func addDefaultAnnotations(k, v string, annotations map[string]string) bool { +func addDefaultAnnotation(k, v string, annotations map[string]string) { if _, ok := annotations[k]; !ok { annotations[k] = v - return true } - return false } diff --git a/pkg/build/controller/build/overrides/api/types.go b/pkg/build/controller/build/overrides/api/types.go index 910f4063f86b..94bb223c9fea 100644 --- a/pkg/build/controller/build/overrides/api/types.go +++ b/pkg/build/controller/build/overrides/api/types.go @@ -2,6 +2,7 @@ package api import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kapi "k8s.io/kubernetes/pkg/apis/core" buildapi "github.com/openshift/origin/pkg/build/apis/build" ) @@ -27,4 +28,8 @@ type BuildOverridesConfig struct { // annotations are annotations that will be added to the build pod Annotations map[string]string + + // tolerations is a list of Tolerations that will override any existing + // tolerations set on a build pod. + Tolerations []kapi.Toleration } diff --git a/pkg/build/controller/build/overrides/api/v1/types.go b/pkg/build/controller/build/overrides/api/v1/types.go index c2d08e6b414a..7d7735c8b9b4 100644 --- a/pkg/build/controller/build/overrides/api/v1/types.go +++ b/pkg/build/controller/build/overrides/api/v1/types.go @@ -1,6 +1,7 @@ package v1 import ( + kapi "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" buildapi "github.com/openshift/api/build/v1" @@ -25,4 +26,8 @@ type BuildOverridesConfig struct { // annotations are annotations that will be added to the build pod Annotations map[string]string `json:"annotations,omitempty"` + + // tolerations is a list of Tolerations that will override any existing + // tolerations set on a build pod. + Tolerations []kapi.Toleration `json:"tolerations,omitempty"` } diff --git a/pkg/build/controller/build/overrides/api/v1/zz_generated.deepcopy.go b/pkg/build/controller/build/overrides/api/v1/zz_generated.deepcopy.go index 3258ff944456..79ed13102a90 100644 --- a/pkg/build/controller/build/overrides/api/v1/zz_generated.deepcopy.go +++ b/pkg/build/controller/build/overrides/api/v1/zz_generated.deepcopy.go @@ -6,6 +6,7 @@ package v1 import ( build_v1 "github.com/openshift/api/build/v1" + core_v1 "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -32,6 +33,13 @@ func (in *BuildOverridesConfig) DeepCopyInto(out *BuildOverridesConfig) { (*out)[key] = val } } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]core_v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/build/controller/build/overrides/api/zz_generated.deepcopy.go b/pkg/build/controller/build/overrides/api/zz_generated.deepcopy.go index a87fdf2faa73..913820708f49 100644 --- a/pkg/build/controller/build/overrides/api/zz_generated.deepcopy.go +++ b/pkg/build/controller/build/overrides/api/zz_generated.deepcopy.go @@ -7,6 +7,7 @@ package api import ( build "github.com/openshift/origin/pkg/build/apis/build" runtime "k8s.io/apimachinery/pkg/runtime" + core "k8s.io/kubernetes/pkg/apis/core" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -32,6 +33,13 @@ func (in *BuildOverridesConfig) DeepCopyInto(out *BuildOverridesConfig) { (*out)[key] = val } } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]core.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/build/controller/build/overrides/overrides.go b/pkg/build/controller/build/overrides/overrides.go index 69003ac0c597..369c8b5bf7b0 100644 --- a/pkg/build/controller/build/overrides/overrides.go +++ b/pkg/build/controller/build/overrides/overrides.go @@ -1,8 +1,13 @@ package overrides import ( + "fmt" + "github.com/golang/glog" + "k8s.io/api/core/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + kapiv1 "k8s.io/kubernetes/pkg/apis/core/v1" buildadmission "github.com/openshift/origin/pkg/build/admission" buildapi "github.com/openshift/origin/pkg/build/apis/build" @@ -84,6 +89,22 @@ func (b BuildOverrides) ApplyOverrides(pod *v1.Pod) error { pod.Annotations[k] = v } + // Override Tolerations + if len(b.config.Tolerations) != 0 { + glog.V(5).Infof("Overriding tolerations for pod %s/%s", pod.Namespace, pod.Name) + pod.Spec.Tolerations = []v1.Toleration{} + for _, toleration := range b.config.Tolerations { + t := v1.Toleration{} + + if err := kapiv1.Convert_core_Toleration_To_v1_Toleration(&toleration, &t, nil); err != nil { + err := fmt.Errorf("Unable to convert core.Toleration to v1.Toleration: %v", err) + utilruntime.HandleError(err) + return err + } + pod.Spec.Tolerations = append(pod.Spec.Tolerations, t) + } + } + return buildadmission.SetBuildInPod(pod, build, version) } diff --git a/test/integration/buildpod_admission_test.go b/test/integration/buildpod_admission_test.go index 35b9f03b5bcf..bc9b18c2c681 100644 --- a/test/integration/buildpod_admission_test.go +++ b/test/integration/buildpod_admission_test.go @@ -12,6 +12,7 @@ import ( watchapi "k8s.io/apimachinery/pkg/watch" kclientset "k8s.io/client-go/kubernetes" kapi "k8s.io/kubernetes/pkg/apis/core" + kapiv1 "k8s.io/kubernetes/pkg/apis/core/v1" buildtestutil "github.com/openshift/origin/pkg/build/admission/testutil" buildapi "github.com/openshift/origin/pkg/build/apis/build" @@ -107,6 +108,40 @@ func TestBuildDefaultAnnotations(t *testing.T) { } } +func TestBuildOverrideTolerations(t *testing.T) { + tolerations := []kapi.Toleration{ + { + Key: "mykey1", + Value: "myvalue1", + Effect: "NoSchedule", + Operator: "Equal", + }, + { + Key: "mykey2", + Value: "myvalue2", + Effect: "NoSchedule", + Operator: "Equal", + }, + } + + oclient, kclientset, fn := setupBuildOverridesAdmissionTest(t, &overridesapi.BuildOverridesConfig{ + Tolerations: tolerations, + }) + + defer fn() + + _, pod := runBuildPodAdmissionTest(t, oclient, kclientset, buildPodAdmissionTestDockerBuild()) + for i, toleration := range tolerations { + tol := v1.Toleration{} + if err := kapiv1.Convert_core_Toleration_To_v1_Toleration(&toleration, &tol, nil); err != nil { + t.Errorf("Unable to convert core.Toleration to v1.Toleration: %v", err) + } + if !reflect.DeepEqual(pod.Spec.Tolerations[i], tol) { + t.Errorf("Resulting pod did not get expected tolerations, expected: %#v, actual: %#v", toleration, pod.Spec.Tolerations[i]) + } + } +} + func TestBuildOverrideForcePull(t *testing.T) { oclient, kclientset, fn := setupBuildOverridesAdmissionTest(t, &overridesapi.BuildOverridesConfig{ ForcePull: true,