Skip to content

Commit 6df94be

Browse files
Merge pull request #22885 from gabemontero/bld-linux-nodes-only
avoid builds on non-linux nodes
2 parents ba2dcc1 + b098040 commit 6df94be

8 files changed

Lines changed: 91 additions & 14 deletions

File tree

pkg/build/controller/build/defaults/defaults.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package defaults
22

33
import (
4+
"strings"
5+
46
"k8s.io/klog"
57
"k8s.io/kubernetes/pkg/api/legacyscheme"
68

@@ -108,11 +110,24 @@ func (b BuildDefaults) applyPodProxyDefaults(pod *corev1.Pod, isCustomBuild bool
108110
}
109111

110112
func (b BuildDefaults) applyPodDefaults(pod *corev1.Pod, isCustomBuild bool) {
111-
if len(b.Config.NodeSelector) != 0 && pod.Spec.NodeSelector == nil {
113+
nodeSelectorAppliable := pod.Spec.NodeSelector == nil
114+
if !nodeSelectorAppliable && len(pod.Spec.NodeSelector) == 1 {
115+
v, ok := pod.Spec.NodeSelector[corev1.LabelOSStable]
116+
if ok && v == "linux" {
117+
nodeSelectorAppliable = true
118+
}
119+
}
120+
if len(b.Config.NodeSelector) != 0 && nodeSelectorAppliable {
112121
// only apply nodeselector defaults if the pod has no nodeselector labels
113122
// already.
114-
pod.Spec.NodeSelector = map[string]string{}
123+
if pod.Spec.NodeSelector == nil {
124+
pod.Spec.NodeSelector = map[string]string{}
125+
}
115126
for k, v := range b.Config.NodeSelector {
127+
// can't override kubernetes.io/os
128+
if strings.TrimSpace(k) == corev1.LabelOSStable {
129+
continue
130+
}
116131
addDefaultNodeSelector(k, v, pod.Spec.NodeSelector)
117132
}
118133
}

pkg/build/controller/build/defaults/defaults_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,18 @@ func TestBuildDefaultsNodeSelector(t *testing.T) {
516516
defaults: map[string]string{"key1": "default1", "key2": "default2"},
517517
expected: map[string]string{"key1": "default1", "key2": "default2"},
518518
},
519+
{
520+
name: "build - non empty linux node only",
521+
build: testutil.Build().WithNodeSelector(map[string]string{corev1.LabelOSStable: "linux"}).AsBuild(),
522+
defaults: map[string]string{"key1": "default1"},
523+
expected: map[string]string{"key1": "default1", corev1.LabelOSStable: "linux"},
524+
},
525+
{
526+
name: "build - try to change linux node only",
527+
build: testutil.Build().WithNodeSelector(map[string]string{corev1.LabelOSStable: "linux"}).AsBuild(),
528+
defaults: map[string]string{corev1.LabelOSStable: "windows"},
529+
expected: map[string]string{corev1.LabelOSStable: "linux"},
530+
},
519531
{
520532
name: "build - ignored",
521533
build: testutil.Build().WithNodeSelector(map[string]string{"key1": "value1"}).AsBuild(),

pkg/build/controller/build/overrides/overrides.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package overrides
22

33
import (
44
"fmt"
5+
"strings"
56

67
"k8s.io/klog"
78

@@ -64,6 +65,9 @@ func (b BuildOverrides) ApplyOverrides(pod *corev1.Pod) error {
6465
pod.Spec.NodeSelector = map[string]string{}
6566
}
6667
for k, v := range b.Config.NodeSelector {
68+
if strings.TrimSpace(k) == corev1.LabelOSStable {
69+
continue
70+
}
6771
klog.V(5).Infof("Adding override nodeselector %s=%s to build pod %s/%s", k, v, pod.Namespace, pod.Name)
6872
pod.Spec.NodeSelector[k] = v
6973
}

pkg/build/controller/build/overrides/overrides_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"reflect"
55
"testing"
66

7-
"k8s.io/api/core/v1"
7+
v1 "k8s.io/api/core/v1"
88
"k8s.io/apiserver/pkg/admission"
99

1010
buildv1 "github.com/openshift/api/build/v1"
@@ -216,6 +216,18 @@ func TestBuildOverrideNodeSelector(t *testing.T) {
216216
overrides: map[string]string{"key2": "override2"},
217217
expected: map[string]string{"key1": "value1", "key2": "override2"},
218218
},
219+
{
220+
name: "build - non empty linux node only",
221+
build: testutil.Build().WithNodeSelector(map[string]string{v1.LabelOSStable: "linux"}).AsBuild(),
222+
overrides: map[string]string{"key1": "default1"},
223+
expected: map[string]string{"key1": "default1", v1.LabelOSStable: "linux"},
224+
},
225+
{
226+
name: "build - try to change linux node only",
227+
build: testutil.Build().WithNodeSelector(map[string]string{v1.LabelOSStable: "linux"}).AsBuild(),
228+
overrides: map[string]string{v1.LabelOSStable: "windows"},
229+
expected: map[string]string{v1.LabelOSStable: "linux"},
230+
},
219231
}
220232

221233
for _, test := range tests {

pkg/build/controller/build/podcreationstrategy.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ func (f *typeBasedFactoryStrategy) CreateBuildPod(build *buildv1.Build, addition
4242
pod.Annotations = map[string]string{}
4343
}
4444
pod.Annotations[buildutil.BuildAnnotation] = build.Name
45+
46+
if pod.Spec.NodeSelector == nil {
47+
pod.Spec.NodeSelector = map[string]string{}
48+
}
49+
pod.Spec.NodeSelector[corev1.LabelOSStable] = "linux"
4550
}
4651
return pod, err
4752
}

pkg/build/controller/build/podcreationstrategy_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"fmt"
55
"testing"
66

7-
"k8s.io/api/core/v1"
7+
v1 "k8s.io/api/core/v1"
88

99
buildv1 "github.com/openshift/api/build/v1"
1010
)
@@ -111,5 +111,9 @@ func TestStrategyCreateBuildPod(t *testing.T) {
111111
if pod != test.expectedPod {
112112
t.Errorf("did not get expected pod with build %#v", test.build)
113113
}
114+
osType, _ := pod.Spec.NodeSelector[v1.LabelOSStable]
115+
if osType != "linux" {
116+
t.Errorf("did not get expected node selector in pod %#v", test.build)
117+
}
114118
}
115119
}

test/extended/builds/start.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
g "github.com/onsi/ginkgo"
1313
o "github.com/onsi/gomega"
1414

15+
corev1 "k8s.io/api/core/v1"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617
"k8s.io/apimachinery/pkg/util/wait"
1718
e2e "k8s.io/kubernetes/test/e2e/framework"
@@ -24,14 +25,21 @@ import (
2425
var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
2526
defer g.GinkgoRecover()
2627
var (
27-
buildFixture = exutil.FixturePath("testdata", "builds", "test-build.yaml")
28-
bcWithPRRef = exutil.FixturePath("testdata", "builds", "test-bc-with-pr-ref.yaml")
29-
exampleGemfile = exutil.FixturePath("testdata", "builds", "test-build-app", "Gemfile")
30-
exampleBuild = exutil.FixturePath("testdata", "builds", "test-build-app")
31-
symlinkFixture = exutil.FixturePath("testdata", "builds", "test-symlink-build.yaml")
32-
exampleGemfileURL = "https://raw.githubusercontent.com/openshift/ruby-hello-world/master/Gemfile"
33-
exampleArchiveURL = "https://github.com/openshift/ruby-hello-world/archive/master.zip"
34-
oc = exutil.NewCLI("cli-start-build", exutil.KubeConfigPath())
28+
buildFixture = exutil.FixturePath("testdata", "builds", "test-build.yaml")
29+
bcWithPRRef = exutil.FixturePath("testdata", "builds", "test-bc-with-pr-ref.yaml")
30+
exampleGemfile = exutil.FixturePath("testdata", "builds", "test-build-app", "Gemfile")
31+
exampleBuild = exutil.FixturePath("testdata", "builds", "test-build-app")
32+
symlinkFixture = exutil.FixturePath("testdata", "builds", "test-symlink-build.yaml")
33+
exampleGemfileURL = "https://raw.githubusercontent.com/openshift/ruby-hello-world/master/Gemfile"
34+
exampleArchiveURL = "https://github.com/openshift/ruby-hello-world/archive/master.zip"
35+
oc = exutil.NewCLI("cli-start-build", exutil.KubeConfigPath())
36+
verifyNodeSelector = func(oc *exutil.CLI, name string) {
37+
pod, err := oc.KubeClient().CoreV1().Pods(oc.Namespace()).Get(name+"-build", metav1.GetOptions{})
38+
o.Expect(err).NotTo(o.HaveOccurred())
39+
os, ok := pod.Spec.NodeSelector[corev1.LabelOSStable]
40+
o.Expect(ok).To(o.BeTrue())
41+
o.Expect(os).To(o.Equal("linux"))
42+
}
3543
)
3644

3745
g.Context("", func() {
@@ -57,6 +65,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
5765
br, err := exutil.StartBuildAndWait(oc, "sample-build", "--wait")
5866
o.Expect(err).NotTo(o.HaveOccurred())
5967
br.AssertSuccess()
68+
verifyNodeSelector(oc, br.BuildName)
6069
})
6170

6271
g.It("should start a build and wait for the build to fail", func() {
@@ -65,6 +74,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
6574
br.AssertFailure()
6675
o.Expect(br.StartBuildErr).To(o.HaveOccurred()) // start-build should detect the build error with --wait flag
6776
o.Expect(br.StartBuildStdErr).Should(o.ContainSubstring(`status is "Failed"`))
77+
verifyNodeSelector(oc, br.BuildName)
6878
})
6979
})
7080

@@ -82,9 +92,11 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
8292
br, err := exutil.StartBuildAndWait(oc, "bc-with-pr-ref-docker")
8393
o.Expect(err).NotTo(o.HaveOccurred())
8494
br.AssertSuccess()
95+
verifyNodeSelector(oc, br.BuildName)
8596
br, err = exutil.StartBuildAndWait(oc, "bc-with-pr-ref")
8697
o.Expect(err).NotTo(o.HaveOccurred())
8798
br.AssertSuccess()
99+
verifyNodeSelector(oc, br.BuildName)
88100
out, err := br.Logs()
89101
o.Expect(err).NotTo(o.HaveOccurred())
90102

@@ -111,6 +123,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
111123
g.By("starting the build with -e FOO=bar,VAR=test")
112124
br, err := exutil.StartBuildAndWait(oc, "sample-build", "-e", "FOO=bar,VAR=test")
113125
br.AssertSuccess()
126+
verifyNodeSelector(oc, br.BuildName)
114127
buildLog, err := br.Logs()
115128
o.Expect(err).NotTo(o.HaveOccurred())
116129

@@ -127,6 +140,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
127140
g.By("starting the build with buildconfig strategy env BUILD_LOGLEVEL=5")
128141
br, err := exutil.StartBuildAndWait(oc, "sample-verbose-build")
129142
br.AssertSuccess()
143+
verifyNodeSelector(oc, br.BuildName)
130144
buildLog, err := br.Logs()
131145
o.Expect(err).NotTo(o.HaveOccurred())
132146
g.By(fmt.Sprintf("verifying the build output is verbose"))
@@ -141,6 +155,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
141155
g.By("starting the build with buildconfig strategy env BUILD_LOGLEVEL=5 but build-loglevel=1")
142156
br, err := exutil.StartBuildAndWait(oc, "sample-verbose-build", "--build-loglevel=1")
143157
br.AssertSuccess()
158+
verifyNodeSelector(oc, br.BuildName)
144159
buildLog, err := br.Logs()
145160
o.Expect(err).NotTo(o.HaveOccurred())
146161
g.By(fmt.Sprintf("verifying the build output is not verbose"))
@@ -163,6 +178,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
163178
g.By("starting the build with a Dockerfile")
164179
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-file=%s", exampleGemfile))
165180
br.AssertSuccess()
181+
verifyNodeSelector(oc, br.BuildName)
166182
buildLog, err := br.Logs()
167183
o.Expect(err).NotTo(o.HaveOccurred())
168184
g.By(fmt.Sprintf("verifying the build %q status", br.BuildPath))
@@ -176,6 +192,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
176192
g.By("starting the build with a directory")
177193
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-dir=%s", exampleBuild))
178194
br.AssertSuccess()
195+
verifyNodeSelector(oc, br.BuildName)
179196
buildLog, err := br.Logs()
180197
o.Expect(err).NotTo(o.HaveOccurred())
181198
g.By(fmt.Sprintf("verifying the build %q status", br.BuildPath))
@@ -189,6 +206,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
189206
tryRepoInit(exampleBuild)
190207
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-repo=%s", exampleBuild))
191208
br.AssertSuccess()
209+
verifyNodeSelector(oc, br.BuildName)
192210
buildLog, err := br.Logs()
193211
o.Expect(err).NotTo(o.HaveOccurred())
194212

@@ -208,6 +226,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
208226
o.Expect(err).NotTo(o.HaveOccurred())
209227
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--commit=%s", commit), fmt.Sprintf("--from-repo=%s", exampleBuild))
210228
br.AssertSuccess()
229+
verifyNodeSelector(oc, br.BuildName)
211230
buildLog, err := br.Logs()
212231
o.Expect(err).NotTo(o.HaveOccurred())
213232

@@ -223,6 +242,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
223242
g.By("starting a valid build with a directory")
224243
br, err := exutil.StartBuildAndWait(oc, "sample-build-binary", "--follow", fmt.Sprintf("--from-dir=%s", exampleBuild))
225244
br.AssertSuccess()
245+
verifyNodeSelector(oc, br.BuildName)
226246
buildLog, err := br.Logs()
227247
o.Expect(err).NotTo(o.HaveOccurred())
228248
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring("Uploading directory"))
@@ -244,6 +264,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
244264
g.By("starting a valid build with input file served by https")
245265
br, err := exutil.StartBuildAndWait(oc, "sample-build", fmt.Sprintf("--from-file=%s", exampleGemfileURL))
246266
br.AssertSuccess()
267+
verifyNodeSelector(oc, br.BuildName)
247268
buildLog, err := br.Logs()
248269
o.Expect(err).NotTo(o.HaveOccurred())
249270
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(fmt.Sprintf("Uploading file from %q as binary input for the build", exampleGemfileURL)))
@@ -255,6 +276,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
255276
// can't use sample-build-binary because we need contextDir due to github archives containing the top-level directory
256277
br, err := exutil.StartBuildAndWait(oc, "sample-build-github-archive", fmt.Sprintf("--from-archive=%s", exampleArchiveURL))
257278
br.AssertSuccess()
279+
verifyNodeSelector(oc, br.BuildName)
258280
buildLog, err := br.Logs()
259281
o.Expect(err).NotTo(o.HaveOccurred())
260282
o.Expect(br.StartBuildStdErr).To(o.ContainSubstring(fmt.Sprintf("Uploading archive from %q as binary input for the build", exampleArchiveURL)))
@@ -329,6 +351,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
329351
g.By("starting the build without --build-arg flag")
330352
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args-preset")
331353
br.AssertSuccess()
354+
verifyNodeSelector(oc, br.BuildName)
332355
buildLog, err := br.Logs()
333356
o.Expect(err).NotTo(o.HaveOccurred())
334357
g.By("verifying the build output contains the build args from the BuildConfig.")
@@ -338,6 +361,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
338361
g.By("starting the build with --build-arg flag")
339362
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args", "--build-arg=foo=bar")
340363
br.AssertSuccess()
364+
verifyNodeSelector(oc, br.BuildName)
341365
buildLog, err := br.Logs()
342366
o.Expect(err).NotTo(o.HaveOccurred())
343367
g.By("verifying the build output contains the changes.")
@@ -347,6 +371,7 @@ var _ = g.Describe("[Feature:Builds][Slow] starting a build using CLI", func() {
347371
g.By("starting the build with --build-arg flag")
348372
br, _ := exutil.StartBuildAndWait(oc, "sample-build-docker-args", "--build-arg=bar=foo")
349373
br.AssertSuccess()
374+
verifyNodeSelector(oc, br.BuildName)
350375
buildLog, err := br.Logs()
351376
o.Expect(err).NotTo(o.HaveOccurred())
352377
g.By("verifying the build completed with a warning.")

test/integration/buildpod_admission_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func TestBuildDefaultLabels(t *testing.T) {
9696
}
9797

9898
func TestBuildDefaultNodeSelectors(t *testing.T) {
99-
selectors := map[string]string{"KEY": "VALUE"}
99+
selectors := map[string]string{"KEY": "VALUE", v1.LabelOSStable: "linux"}
100100
oclient, kclientset, fn := setupBuildDefaultsAdmissionTest(t, &configapi.BuildDefaultsConfig{
101101
NodeSelector: selectors,
102102
})
@@ -205,7 +205,7 @@ func TestBuildOverrideLabels(t *testing.T) {
205205
}
206206

207207
func TestBuildOverrideNodeSelectors(t *testing.T) {
208-
selectors := map[string]string{"KEY": "VALUE"}
208+
selectors := map[string]string{"KEY": "VALUE", v1.LabelOSStable: "linux"}
209209
oclient, kclientset, fn := setupBuildOverridesAdmissionTest(t, &configapi.BuildOverridesConfig{
210210
NodeSelector: selectors,
211211
})

0 commit comments

Comments
 (0)