Skip to content
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

Propagate job labels and annotations #737

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions pkg/controllers/jobset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ func labelAndAnnotateObject(obj metav1.Object, js *jobset.JobSet, rjob *jobset.R

// Set labels on the object.
labels := make(map[string]string)
maps.Copy(labels, obj.GetLabels())
labels[jobset.JobSetNameKey] = js.Name
labels[jobset.ReplicatedJobNameKey] = rjob.Name
labels[constants.RestartsKey] = strconv.Itoa(int(js.Status.Restarts))
Expand All @@ -748,6 +749,7 @@ func labelAndAnnotateObject(obj metav1.Object, js *jobset.JobSet, rjob *jobset.R
labels[jobset.JobGlobalIndexKey] = globalJobIndex(js, rjob.Name, jobIdx)

annotations := make(map[string]string)
maps.Copy(annotations, obj.GetAnnotations())
annotations[jobset.JobSetNameKey] = js.Name
annotations[jobset.ReplicatedJobNameKey] = rjob.Name
annotations[constants.RestartsKey] = strconv.Itoa(int(js.Status.Restarts))
Expand Down
75 changes: 71 additions & 4 deletions pkg/controllers/jobset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"context"
"errors"
"fmt"
"maps"
ahg-g marked this conversation as resolved.
Show resolved Hide resolved
"strconv"
"strings"
"testing"
Expand Down Expand Up @@ -127,10 +128,26 @@ func TestIsJobFinished(t *testing.T) {

func TestConstructJobsFromTemplate(t *testing.T) {
var (
jobSetName = "test-jobset"
replicatedJobName = "replicated-job"
jobName = "test-job"
ns = "default"
jobSetName = "test-jobset"
replicatedJobName = "replicated-job"
jobName = "test-job"
ns = "default"
jobAnnotations = map[string]string{
Copy link
Contributor

Choose a reason for hiding this comment

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

Reading #729, are we not expecting top level labels/annotations to propagate down into the Jobs/Pods?

We should maybe comment on that ticket that top-level labels/annotations won't be passed down but they should be set on the Job/Pod?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From the current implementation, only certain top level labels/annotations are explicitly passed down - see https://github.com/kubernetes-sigs/jobset/blob/main/pkg/controllers/jobset_controller.go#L767

So yes I think by design the user needs to set labels on the ReplicatedJob spec in order to be passed down to the Job/Pod. Is my understanding correct @ahg-g ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Correct

"job-annotation-key1": "job-annotation-value1",
"job-annotation-key2": "job-annotation-value2",
}
jobLabels = map[string]string{
"job-label-key1": "job-label-value1",
"job-label-key2": "job-label-value2",
}
podAnnotations = map[string]string{
"pod-annotation-key1": "pod-annotation-value1",
"pod-annotation-key2": "pod-annotation-value2",
}
podLabels = map[string]string{
"pod-label-key1": "pod-label-value1",
"pod-label-key2": "pod-label-value2",
}
ahg-g marked this conversation as resolved.
Show resolved Hide resolved
topologyDomain = "test-topology-domain"
coordinatorKeyValue = map[string]string{
jobset.CoordinatorKey: fmt.Sprintf("%s-%s-%d-%d.%s", jobSetName, replicatedJobName, 0, 0, jobSetName),
Expand Down Expand Up @@ -183,6 +200,46 @@ func TestConstructJobsFromTemplate(t *testing.T) {
Suspend(false).Obj(),
},
},
{
name: "all jobs/pods created with labels and annotations",
js: testutils.MakeJobSet(jobSetName, ns).
ReplicatedJob(testutils.MakeReplicatedJob(replicatedJobName).
Job(testutils.MakeJobTemplate(jobName, ns).
SetLabels(jobLabels).
SetPodLabels(podLabels).
SetAnnotations(jobAnnotations).
SetPodAnnotations(podAnnotations).
Obj()).
Replicas(2).
Obj()).Obj(),
ownedJobs: &childJobs{},
want: []*batchv1.Job{
makeJob(&makeJobArgs{
jobSetName: jobSetName,
replicatedJobName: replicatedJobName,
jobName: "test-jobset-replicated-job-0",
ns: ns,
jobLabels: jobLabels,
jobAnnotations: jobAnnotations,
podLabels: podLabels,
podAnnotations: podAnnotations,
replicas: 2,
jobIdx: 0}).
Suspend(false).Obj(),
makeJob(&makeJobArgs{
jobSetName: jobSetName,
replicatedJobName: replicatedJobName,
jobName: "test-jobset-replicated-job-1",
ns: ns,
jobLabels: jobLabels,
jobAnnotations: jobAnnotations,
podLabels: podLabels,
podAnnotations: podAnnotations,
replicas: 2,
jobIdx: 1}).
Suspend(false).Obj(),
},
},
{
name: "one job created, one job not created (already active)",
js: testutils.MakeJobSet(jobSetName, ns).
Expand Down Expand Up @@ -1251,6 +1308,10 @@ type makeJobArgs struct {
replicatedJobName string
jobName string
ns string
jobLabels map[string]string
jobAnnotations map[string]string
podLabels map[string]string
podAnnotations map[string]string
replicas int
jobIdx int
restarts int
Expand All @@ -1276,6 +1337,7 @@ func makeJob(args *makeJobArgs) *testutils.JobWrapper {
constants.RestartsKey: strconv.Itoa(args.restarts),
jobset.JobKey: jobHashKey(args.ns, args.jobName),
}

ahg-g marked this conversation as resolved.
Show resolved Hide resolved
// Only set exclusive key if we are using exclusive placement per topology.
if args.topology != "" {
annotations[jobset.ExclusiveKey] = args.topology
Expand All @@ -1284,10 +1346,15 @@ func makeJob(args *makeJobArgs) *testutils.JobWrapper {
annotations[jobset.NodeSelectorStrategyKey] = "true"
}
}


ahg-g marked this conversation as resolved.
Show resolved Hide resolved
jobWrapper := testutils.MakeJob(args.jobName, args.ns).
JobLabels(labels).
JobLabels(args.jobLabels).
JobAnnotations(annotations).
JobAnnotations(args.jobAnnotations).
PodLabels(labels).
PodLabels(args.podLabels).
ahg-g marked this conversation as resolved.
Show resolved Hide resolved
ahg-g marked this conversation as resolved.
Show resolved Hide resolved
PodAnnotations(annotations)
return jobWrapper
}
Expand Down
18 changes: 18 additions & 0 deletions pkg/util/testing/wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,30 @@ func (j *JobTemplateWrapper) PodSpec(podSpec corev1.PodSpec) *JobTemplateWrapper
return j
}

// SetAnnotations sets the annotations on the Pod template.
func (j *JobTemplateWrapper) SetPodAnnotations(annotations map[string]string) *JobTemplateWrapper {
j.Spec.Template.SetAnnotations(annotations)
return j
}

// SetLabels sets the labels on the Pod template.
func (j *JobTemplateWrapper) SetPodLabels(labels map[string]string) *JobTemplateWrapper {
j.Spec.Template.SetLabels(labels)
return j
}

// SetAnnotations sets the annotations on the Job template.
func (j *JobTemplateWrapper) SetAnnotations(annotations map[string]string) *JobTemplateWrapper {
j.Annotations = annotations
return j
}

// SetLabels sets the labels on the Job template.
func (j *JobTemplateWrapper) SetLabels(labels map[string]string) *JobTemplateWrapper {
j.Labels = labels
return j
}

// Obj returns the inner batchv1.JobTemplateSpec
func (j *JobTemplateWrapper) Obj() batchv1.JobTemplateSpec {
return j.JobTemplateSpec
Expand Down