Skip to content
This repository was archived by the owner on Sep 5, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkg/apis/build/v1alpha1/build_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ type BuildSpec struct {
// Specified build timeout should be less than 24h.
// Refer Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration
Timeout string `json:"timeout,omitempty"`

// If specified, the pod's scheduling constraints
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty"`
}

// TemplateKind defines the type of BuildTemplate used by the build.
Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/build/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/builder/cluster/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ func FromCRD(build *v1alpha1.Build, kubeclient kubernetes.Interface) (*corev1.Po
ServiceAccountName: build.Spec.ServiceAccountName,
Volumes: volumes,
NodeSelector: build.Spec.NodeSelector,
Affinity: build.Spec.Affinity,
},
}, nil
}
Expand Down Expand Up @@ -501,6 +502,7 @@ func ToCRD(pod *corev1.Pod) (*v1alpha1.Build, error) {
ServiceAccountName: podSpec.ServiceAccountName,
Volumes: volumes,
NodeSelector: podSpec.NodeSelector,
Affinity: podSpec.Affinity,
},
}, nil
}
1 change: 0 additions & 1 deletion test/e2e/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ type buildClient struct {
func (c *buildClient) watchBuild(name string) (*v1alpha1.Build, error) {
ls := metav1.SingleObject(metav1.ObjectMeta{Name: name})
// TODO: Update watchBuild function to take this as parameter depending on test requirements

// Set build timeout to 120 seconds. This will trigger watch timeout error
var timeout int64 = 120
ls.TimeoutSeconds = &timeout
Expand Down
47 changes: 46 additions & 1 deletion test/e2e/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,51 @@ func TestPendingBuild(t *testing.T) {
}

if _, err := clients.buildClient.watchBuild(buildName); err == nil {
t.Fatalf("watchBuild did not return watch timeout error")
t.Fatalf("watchBuild did not return expected `watch timeout` error")
}
}

// TestPodAffinity tests that a build with non existent pod affinity does not scheduled
// and fails after watch timeout
func TestPodAffinity(t *testing.T) {
clients := setup(t)

buildName := "affinity-build"
if _, err := clients.buildClient.builds.Create(&v1alpha1.Build{
ObjectMeta: metav1.ObjectMeta{
Namespace: buildTestNamespace,
Name: buildName,
},
Spec: v1alpha1.BuildSpec{
Affinity: &corev1.Affinity{
NodeAffinity: &corev1.NodeAffinity{
// This node affinity rule says the pod can only be placed on a node with a label whose key is kubernetes.io/e2e-az-name
// and whose value is either e2e-az1 or e2e-az2. Test cluster does not have any nodes that meets this constraint so the build
// will wait for pod to scheduled until timeout.
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
NodeSelectorTerms: []corev1.NodeSelectorTerm{
corev1.NodeSelectorTerm{
MatchExpressions: []corev1.NodeSelectorRequirement{
corev1.NodeSelectorRequirement{
Key: "kubernetes.io/e2e-az-name",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe in words why this affinity makes the build unscheduleable?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Operator: corev1.NodeSelectorOpIn,
Values: []string{"e2e-az1", "e2e-az2"},
}},
},
},
},
},
},
Steps: []corev1.Container{{
Image: "busybox",
Args: []string{"true"},
}},
},
}); err != nil {
t.Fatalf("Error creating build: %v", err)
}

if _, err := clients.buildClient.watchBuild(buildName); err == nil {
t.Fatalf("watchBuild did not return expected `watch timeout` error")
}
}