Skip to content

Add --node-selector Flag for shp build/buildrun Commands #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
1 change: 1 addition & 0 deletions docs/shp_build_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ shp build create <name> [flags]
```
-e, --env stringArray specify a key-value pair for an environment variable to set for the build container (default [])
-h, --help help for create
--node-selector stringArray set of key-value pairs that correspond to labels of a node to match (default [])
--output-image string image employed during the building process
--output-image-annotation stringArray specify a set of key-value pairs that correspond to annotations to set on the output image (default [])
--output-image-label stringArray specify a set of key-value pairs that correspond to labels to set on the output image (default [])
Expand Down
1 change: 1 addition & 0 deletions docs/shp_build_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ shp build run <name> [flags]
-e, --env stringArray specify a key-value pair for an environment variable to set for the build container (default [])
-F, --follow Start a build and watch its log until it completes or fails.
-h, --help help for run
--node-selector stringArray set of key-value pairs that correspond to labels of a node to match (default [])
--output-image string image employed during the building process
--output-image-annotation stringArray specify a set of key-value pairs that correspond to annotations to set on the output image (default [])
--output-image-label stringArray specify a set of key-value pairs that correspond to labels to set on the output image (default [])
Expand Down
1 change: 1 addition & 0 deletions docs/shp_build_upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ shp build upload <build-name> [path/to/source|.] [flags]
-e, --env stringArray specify a key-value pair for an environment variable to set for the build container (default [])
-F, --follow Start a build and watch its log until it completes or fails.
-h, --help help for upload
--node-selector stringArray set of key-value pairs that correspond to labels of a node to match (default [])
--output-image string image employed during the building process
--output-image-annotation stringArray specify a set of key-value pairs that correspond to annotations to set on the output image (default [])
--output-image-label stringArray specify a set of key-value pairs that correspond to labels to set on the output image (default [])
Expand Down
1 change: 1 addition & 0 deletions docs/shp_buildrun_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ shp buildrun create <name> [flags]
--buildref-name string name of build resource to reference
-e, --env stringArray specify a key-value pair for an environment variable to set for the build container (default [])
-h, --help help for create
--node-selector stringArray set of key-value pairs that correspond to labels of a node to match (default [])
--output-image string image employed during the building process
--output-image-annotation stringArray specify a set of key-value pairs that correspond to annotations to set on the output image (default [])
--output-image-label stringArray specify a set of key-value pairs that correspond to labels to set on the output image (default [])
Expand Down
3 changes: 2 additions & 1 deletion pkg/shp/flags/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func BuildSpecFromFlags(flags *pflag.FlagSet) (*buildv1beta1.BuildSpec, *string,
TTLAfterFailed: &metav1.Duration{},
TTLAfterSucceeded: &metav1.Duration{},
},
NodeSelector: map[string]string{},
}

sourceFlags(flags, spec.Source)
Expand All @@ -55,7 +56,7 @@ func BuildSpecFromFlags(flags *pflag.FlagSet) (*buildv1beta1.BuildSpec, *string,
imageLabelsFlags(flags, spec.Output.Labels)
imageAnnotationsFlags(flags, spec.Output.Annotations)
buildRetentionFlags(flags, spec.Retention)

buildNodeSelectorFlags(flags, spec.NodeSelector)
var dockerfile, builderImage string
dockerfileFlags(flags, &dockerfile)
builderImageFlag(flags, &builderImage)
Expand Down
8 changes: 8 additions & 0 deletions pkg/shp/flags/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func TestBuildSpecFromFlags(t *testing.T) {
Duration: 30 * time.Minute,
},
},
NodeSelector: map[string]string{"kubernetes.io/hostname": "worker-1"},
}

cmd := &cobra.Command{}
Expand Down Expand Up @@ -115,6 +116,13 @@ func TestBuildSpecFromFlags(t *testing.T) {
g.Expect(expected.Output).To(o.Equal(spec.Output), "spec.output")
})

t.Run(".spec.nodeSelector", func(_ *testing.T) {
err := flags.Set(NodeSelectorFlag, "kubernetes.io/hostname=worker-1")
g.Expect(err).To(o.BeNil())
// g.Expect(expected.NodeSelector).To(o.HaveKeyWithValue("kubernetes.io/hostname",spec.NodeSelector["kubernetes.io/hostname"]), ".spec.nodeSelector")
g.Expect(expected.NodeSelector).To(o.Equal(spec.NodeSelector), ".spec.nodeSelector")
})

t.Run(".spec.timeout", func(_ *testing.T) {
err := flags.Set(TimeoutFlag, expected.Timeout.Duration.String())
g.Expect(err).To(o.BeNil())
Expand Down
3 changes: 2 additions & 1 deletion pkg/shp/flags/buildrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func BuildRunSpecFromFlags(flags *pflag.FlagSet) *buildv1beta1.BuildRunSpec {
TTLAfterFailed: &metav1.Duration{},
TTLAfterSucceeded: &metav1.Duration{},
},
NodeSelector: map[string]string{},
}

buildRefFlags(flags, &spec.Build)
Expand All @@ -39,7 +40,7 @@ func BuildRunSpecFromFlags(flags *pflag.FlagSet) *buildv1beta1.BuildRunSpec {
imageLabelsFlags(flags, spec.Output.Labels)
imageAnnotationsFlags(flags, spec.Output.Annotations)
buildRunRetentionFlags(flags, spec.Retention)

buildNodeSelectorFlags(flags, spec.NodeSelector)
return spec
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/shp/flags/buildrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func TestBuildRunSpecFromFlags(t *testing.T) {
Duration: 30 * time.Minute,
},
},
NodeSelector: map[string]string{"kubernetes.io/hostname": "worker-1"},
}

cmd := &cobra.Command{}
Expand Down Expand Up @@ -75,6 +76,13 @@ func TestBuildRunSpecFromFlags(t *testing.T) {
g.Expect(*expected.Output).To(o.Equal(*spec.Output), "spec.output")
})

t.Run(".spec.nodeSelector", func(_ *testing.T) {
err := flags.Set(NodeSelectorFlag, "kubernetes.io/hostname=worker-1")
g.Expect(err).To(o.BeNil())
// g.Expect(expected.NodeSelector).To(o.HaveKeyWithValue("kubernetes.io/hostname",spec.NodeSelector["kubernetes.io/hostname"]), ".spec.nodeSelector")
g.Expect(expected.NodeSelector).To(o.Equal(spec.NodeSelector), ".spec.nodeSelector")
})

t.Run(".spec.retention.ttlAfterFailed", func(_ *testing.T) {
err := flags.Set(RetentionTTLAfterFailedFlag, expected.Retention.TTLAfterFailed.Duration.String())
g.Expect(err).To(o.BeNil())
Expand Down
7 changes: 7 additions & 0 deletions pkg/shp/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ const (
RetentionTTLAfterFailedFlag = "retention-ttl-after-failed"
// RetentionTTLAfterSucceededFlag command-line flag.
RetentionTTLAfterSucceededFlag = "retention-ttl-after-succeeded"
// NodeSelectorFlag command-line flag.
NodeSelectorFlag = "node-selector"
)

// sourceFlags flags for ".spec.source"
Expand Down Expand Up @@ -259,6 +261,11 @@ func serviceAccountFlags(flags *pflag.FlagSet, sa *string) {

}

// buildNodeSelectorFlags registers flags for adding BuildSpec.NodeSelector
func buildNodeSelectorFlags(flags *pflag.FlagSet, nodeSelectorLabels map[string]string) {
flags.Var(NewMapValue(nodeSelectorLabels), NodeSelectorFlag, "set of key-value pairs that correspond to labels of a node to match")
}

// envFlags registers flags for adding corev1.EnvVars.
func envFlags(flags *pflag.FlagSet, envs *[]corev1.EnvVar) {
flags.VarP(
Expand Down
114 changes: 114 additions & 0 deletions test/e2e/node-selector.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env bats

source test/e2e/helpers.sh

setup() {
load 'bats/support/load'
load 'bats/assert/load'
load 'bats/file/load'
}

teardown() {
run kubectl delete builds.shipwright.io --all
run kubectl delete buildruns.shipwright.io --all
}

@test "shp build create --node-selector single label" {
# generate random names for our build
build_name=$(random_name)

# create a Build with node selector
run shp build create ${build_name} --source-git-url=https://github.com/shipwright-io/sample-go --output-image=my-fake-image --node-selector="kubernetes.io/hostname=node-1"
assert_success

# ensure that the build was successfully created
assert_output --partial "Created build \"${build_name}\""

# get the jsonpath of Build object .spec.nodeSelector
run kubectl get builds.shipwright.io/${build_name} -ojsonpath="{.spec.nodeSelector}"
assert_success

assert_output '{"kubernetes.io/hostname":"node-1"}'
}

@test "shp build create --node-selector multiple labels" {
# generate random names for our build
build_name=$(random_name)

# create a Build with node selector
run shp build create ${build_name} --source-git-url=https://github.com/shipwright-io/sample-go --output-image=my-fake-image --node-selector="kubernetes.io/hostname=node-1" --node-selector="kubernetes.io/os=linux"
assert_success

# ensure that the build was successfully created
assert_output --partial "Created build \"${build_name}\""

# get the jsonpath of Build object .spec.nodeSelector
run kubectl get builds.shipwright.io/${build_name} -ojsonpath="{.spec.nodeSelector}"
assert_success

assert_output --partial '"kubernetes.io/hostname":"node-1"'
assert_output --partial '"kubernetes.io/os":"linux"'
}

@test "shp buildrun create --node-selector single label" {
# generate random names for our buildrun
buildrun_name=$(random_name)
build_name=$(random_name)

# create a Build with node selector
run shp buildrun create ${buildrun_name} --buildref-name=${build_name} --node-selector="kubernetes.io/hostname=node-1"
assert_success

# ensure that the build was successfully created
assert_output --partial "BuildRun created \"${buildrun_name}\" for Build \"${build_name}\""

# get the jsonpath of Build object .spec.nodeSelector
run kubectl get buildruns.shipwright.io/${buildrun_name} -ojsonpath="{.spec.nodeSelector}"
assert_success

assert_output '{"kubernetes.io/hostname":"node-1"}'
}

@test "shp buildrun create --node-selector multiple labels" {
# generate random names for our buildrun
buildrun_name=$(random_name)
build_name=$(random_name)

# create a Build with node selector
run shp buildrun create ${buildrun_name} --buildref-name=${build_name} --node-selector="kubernetes.io/hostname=node-1" --node-selector="kubernetes.io/os=linux"
assert_success

# ensure that the build was successfully created
assert_output --partial "BuildRun created \"${buildrun_name}\" for Build \"${build_name}\""

# get the jsonpath of Build object .spec.nodeSelector
run kubectl get buildruns.shipwright.io/${buildrun_name} -ojsonpath="{.spec.nodeSelector}"
assert_success

assert_output --partial '"kubernetes.io/hostname":"node-1"'
assert_output --partial '"kubernetes.io/os":"linux"'
}


@test "shp build run --node-selector set" {
# generate random names for our build
build_name=$(random_name)

# create a Build with node selector
run shp build create ${build_name} --source-git-url=https://github.com/shipwright-io/sample-go --output-image=my-fake-image
assert_success

# ensure that the build was successfully created
assert_output --partial "Created build \"${build_name}\""

# get the build object
run kubectl get builds.shipwright.io/${build_name}
assert_success

run shp build run ${build_name} --node-selector="kubernetes.io/hostname=node-1"

# get the jsonpath of Build object .spec.nodeSelector
run kubectl get buildruns.shipwright.io -ojsonpath='{.items[*].spec.nodeSelector}'
assert_success
assert_output --partial '"kubernetes.io/hostname":"node-1"'
}