-
Notifications
You must be signed in to change notification settings - Fork 262
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
Copy some labels from Pods/Jobs into the Workload object #1959
Conversation
Hi @pajakd. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
✅ Deploy Preview for kubernetes-sigs-kueue canceled.
|
/ok-to-test |
@@ -301,6 +301,10 @@ type Integrations struct { | |||
Frameworks []string `json:"frameworks,omitempty"` | |||
// PodOptions defines kueue controller behaviour for pod objects | |||
PodOptions *PodIntegrationOptions `json:"podOptions,omitempty"` | |||
|
|||
// A list of label keys that should be copied from job | |||
// into the workload object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain what happens if the job doesn't have the label.
And, in the case of composable jobs, what happens if there are different values in different objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the label is not there it is not copied (no error, no warning). Added an explanation in the comment (also about the case of mismatched labels).
- "@alculquicondor" | ||
- "@gabesaba" | ||
approvers: | ||
- TBD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
|
||
# The target maturity stage in the current dev cycle for this KEP. | ||
stage: alpha |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is no feature gate, maybe we should call this as beta (to match the API version).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
# The following PRR answers are required at alpha release | ||
# List the feature gate name and the components for which it must be enabled | ||
disable-supported: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it?
There is no feature gate (I wouldn't add one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry. Removed the disable-supported
and the comments.
workloadLabels := make(map[string]string) | ||
if r.labelKeysToCopy == nil { | ||
return workloadLabels | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reducing allocations:
workloadLabels := make(map[string]string) | |
if r.labelKeysToCopy == nil { | |
return workloadLabels | |
} | |
if len(r.labelKeysToCopy) == 0 { | |
return nil | |
} | |
workloadLabels := make(map[string]string, len(r.labelKeysToCopy)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workload must have the Labels
field initialized because later we use it (assigning JobUIDLabel) for every workload (that has a valid jobuid).
Since output of this function is used directly as Labels
in the workload object we (probably) should not return nil
.
I did apply the suggested change (but returning empty list instead of nil).
func (p *Pod) getWorkloadLabels(labelKeysToCopy []string) (map[string]string, error) { | ||
jobLabels := p.Object().GetLabels() | ||
workloadLabels := make(map[string]string) | ||
if labelKeysToCopy == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar recommendation as the job controller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we can return nil, so I'm applying the suggestion entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the comments. I think I addressed them. Please take a look if everything looks ok.
- "@alculquicondor" | ||
- "@gabesaba" | ||
approvers: | ||
- TBD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
|
||
# The target maturity stage in the current dev cycle for this KEP. | ||
stage: alpha |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
# The following PRR answers are required at alpha release | ||
# List the feature gate name and the components for which it must be enabled | ||
disable-supported: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry. Removed the disable-supported
and the comments.
workloadLabels := make(map[string]string) | ||
if r.labelKeysToCopy == nil { | ||
return workloadLabels | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workload must have the Labels
field initialized because later we use it (assigning JobUIDLabel) for every workload (that has a valid jobuid).
Since output of this function is used directly as Labels
in the workload object we (probably) should not return nil
.
I did apply the suggested change (but returning empty list instead of nil).
func (p *Pod) getWorkloadLabels(labelKeysToCopy []string) (map[string]string, error) { | ||
jobLabels := p.Object().GetLabels() | ||
workloadLabels := make(map[string]string) | ||
if labelKeysToCopy == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we can return nil, so I'm applying the suggestion entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some questions to the KEP for now.
|
||
A case that requires more attention is creating workloads from pod groups because in that case a single workload is based on multiple pods (each of which might have labels). We propose: | ||
* When a label from the `labelKeysToCopy` list will be present at some of the pods from the group and the value of this label on all these pods will be identical then this label will be copied into the workload. Note that we do not require that all the pods have the label but all that do have must have the same value. | ||
* When multiple pods from the group will have the label with different values, we will raise an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the Workload object created only when we have all the pods in a group created? If it is created when the first pod is created, then we may not have a chance to raise the exception.
Also, related:
- when is the exception raised, it is during workload creation, or later? If later, how is the error communicated to the user?
- what happens when the workload already exists, and the user creates a new pod with a non-matching value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know the workload object is created when all the pods are created.
The exception is raised during workload creation.
The new feature is only applied during the creation of a new workload so if the user creates another pod later it will have no effect on the labels on the running workload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know the workload object is created when all the pods are created.
This would simplify this indeed. Could you please double check on a running system?
The exception is raised during workload creation.
The new feature is only applied during the creation of a new workload so if the user creates another pod later it will have no effect on the labels on the running workload.
sgtm, please add a sentence along the lines to clarify in KEP for future readers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know the workload object is created when all the pods are created.
That is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added a sentence to KEP clarifying this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clarifying and the update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the comments!
|
||
A case that requires more attention is creating workloads from pod groups because in that case a single workload is based on multiple pods (each of which might have labels). We propose: | ||
* When a label from the `labelKeysToCopy` list will be present at some of the pods from the group and the value of this label on all these pods will be identical then this label will be copied into the workload. Note that we do not require that all the pods have the label but all that do have must have the same value. | ||
* When multiple pods from the group will have the label with different values, we will raise an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know the workload object is created when all the pods are created.
The exception is raised during workload creation.
The new feature is only applied during the creation of a new workload so if the user creates another pod later it will have no effect on the labels on the running workload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed only proposal.
kep-number: 1834 | ||
authors: | ||
- "@pajakd" | ||
status: draft |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
status: draft | |
status: implementable |
Isn't this implementable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
## Design Details | ||
|
||
We believe that the KEP is rather straightforward and the [Proposal](#proposal) section contains sufficient details of the implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add the configuration API detail here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
// constructed workload object will be created without this label. In the case | ||
// of creating a workload from a composable job (pod group), if multiple objects | ||
// have labels with some key form the list, the values of these labels must | ||
// agree or otherwise the workload creation would fail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also mention that if the Job labels change after the first Workload object is created, the Workload will not be updated.
@@ -784,16 +794,29 @@ func (r *JobReconciler) finalizeJob(ctx context.Context, job GenericJob) error { | |||
return nil | |||
} | |||
|
|||
func (r *JobReconciler) getWorkloadLabels(job GenericJob) map[string]string { | |||
jobLabels := job.Object().GetLabels() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this line after the check for len(r.labelKeysToCopy)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -569,6 +573,9 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu | |||
}, | |||
wlConditionCmpOpts..., | |||
)) | |||
ginkgo.By("checking the workload gets assigned the correct labels") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ginkgo.By("checking the workload gets assigned the correct labels") | |
// Checking the workload gets assigned the correct labels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -898,7 +900,36 @@ func (p *Pod) ensureWorkloadOwnedByAllMembers(ctx context.Context, c client.Clie | |||
return nil | |||
} | |||
|
|||
func (p *Pod) ConstructComposableWorkload(ctx context.Context, c client.Client, r record.EventRecorder) (*kueue.Workload, error) { | |||
func (p *Pod) getWorkloadLabels(labelKeysToCopy []string) (map[string]string, error) { | |||
jobLabels := p.Object().GetLabels() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: here also move below the len check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
for _, labelKey := range labelKeysToCopy { | ||
if labelValue, found := jobLabels[labelKey]; found { | ||
workloadLabels[labelKey] = labelValue | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move this pass under the !p.isGroup
check? It seems the case when this is a group is handled below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is handling the case when the object is a single pod. We have to copy the labels from the single pod into the workload in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, my idea was:
workloadLabels := make(map[string]string, len(labelKeysToCopy))
if !p.isGroup {
for _, labelKey := range labelKeysToCopy {
if labelValue, found := jobLabels[labelKey]; found {
workloadLabels[labelKey] = labelValue
}
}
return workloadLabels, nil
}
// the code for group handling
would it work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I think its correct. Applied the suggested changes
Obj()}, | ||
wantPods: nil, | ||
reconcilerOptions: []jobframework.Option{ | ||
jobframework.WithLabelKeysToCopy([]string{"toCopyKey"}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add also a label key name that is absent in the pod.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
design, implementation and tests LGTM.
The API comment needs a bit of work.
@tenzen-y anything to add?
// a job does not have some label with the given key from this list, the | ||
// constructed workload object will be created without this label. In the case | ||
// of creating a workload from a composable job (pod group), if multiple objects | ||
// have labels with some key form the list, the values of these labels must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// have labels with some key form the list, the values of these labels must | |
// have labels with some key from the list, the values of these labels must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
// constructed workload object will be created without this label. In the case | ||
// of creating a workload from a composable job (pod group), if multiple objects | ||
// have labels with some key form the list, the values of these labels must | ||
// agree or otherwise the workload creation would fail. The labels are copied only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// agree or otherwise the workload creation would fail. The labels are copied only | |
// match or otherwise the workload creation would fail. The labels are copied only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -301,6 +301,17 @@ type Integrations struct { | |||
Frameworks []string `json:"frameworks,omitempty"` | |||
// PodOptions defines kueue controller behaviour for pod objects | |||
PodOptions *PodIntegrationOptions `json:"podOptions,omitempty"` | |||
|
|||
// A list of label keys that should be copied from the job into the workload | |||
// object. We don't require the job to have all the labels from this list. If |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// object. We don't require the job to have all the labels from this list. If | |
// object. It is not required for the job to have all the labels from this list. If |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -301,6 +301,17 @@ type Integrations struct { | |||
Frameworks []string `json:"frameworks,omitempty"` | |||
// PodOptions defines kueue controller behaviour for pod objects | |||
PodOptions *PodIntegrationOptions `json:"podOptions,omitempty"` | |||
|
|||
// A list of label keys that should be copied from the job into the workload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One general recommendation when writing documentation and API comments, is to use active voice https://kubernetes.io/docs/contribute/style/style-guide/#use-active-voice
Try to adhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'll read and follow the style guide. But here I don't see any good way of rephrasing "should be copied" into active voice...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, there is the exception Use passive voice if active voice leads to an awkward construction
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
Leaving LGTM to @tenzen-y
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this update!
Basically, lgtm. I left a few minor comments.
@@ -301,6 +301,17 @@ type Integrations struct { | |||
Frameworks []string `json:"frameworks,omitempty"` | |||
// PodOptions defines kueue controller behaviour for pod objects | |||
PodOptions *PodIntegrationOptions `json:"podOptions,omitempty"` | |||
|
|||
// A list of label keys that should be copied from the job into the workload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// A list of label keys that should be copied from the job into the workload | |
// labelKeysToCopy is a list of label keys that should be copied from the job into the workload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
``` go | ||
type Integrations struct { | ||
... | ||
// A list of label keys that should be copied from the job into the workload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// A list of label keys that should be copied from the job into the workload | |
// labelKeysToCopy is a list of label keys that should be copied from the job into the workload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
alpha: "v0.7" | ||
beta: "v0.8" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alpha: "v0.7" | |
beta: "v0.8" | |
beta: "v0.7" |
I'm wondering if we should declare this feature as a beta in v0.7, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok without a feature gate since the risk is minimal, but if there is no feature gate, should we declare "beta", or "stable" already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know (I'll let you decide). For the time being I applied the suggestion above.
"toCopyKey": "toCopyValue"}). | ||
Obj(), | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -784,16 +794,29 @@ func (r *JobReconciler) finalizeJob(ctx context.Context, job GenericJob) error { | |||
return nil | |||
} | |||
|
|||
func (r *JobReconciler) getWorkloadLabels(job GenericJob) map[string]string { | |||
if len(r.labelKeysToCopy) == 0 { | |||
return map[string]string{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about if we can return just nil
. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworked this logic (see the comment below).
for _, labelKey := range labelKeysToCopy { | ||
if labelValue, found := podLabels[labelKey]; found { | ||
workloadLabels[labelKey] = labelValue | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is completely the same logic as the generic reconciler:
So, could we commonize them?
jobLabels := job.Object().GetLabels()
workloadLabels := make(map[string]string, len(r.labelKeysToCopy))
for _, labelKey := range r.labelKeysToCopy {
if labelValue, found := jobLabels[labelKey]; found {
workloadLabels[labelKey] = labelValue
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, good idea. So this is in fact filtering a map with a certain list of keys. I extracted this into maps
library (added a generic maps.FilterKeys
function and a bunch of unit tests). And I'm using it here and in the generic reconciler. Please take a look if it looks better.
@@ -569,6 +573,9 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu | |||
}, | |||
wlConditionCmpOpts..., | |||
)) | |||
// Checking the workload gets assigned the correct labels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Checking the workload gets assigned the correct labels. | |
ginkgo.By("Checking the workload gets assigned the correct labels") |
This comment is helpful for the debug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Message: "Created Workload: ns/" + GetWorkloadNameForJob(baseJobWrapper.Name, types.UID("test-uid")), | ||
}, | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add another case to verify if the labels are not populated to Workloads after the Workload is already created?
I'd like to prove this comment: "The labels are copied only during the workload creation and are not updated even if the labels of the underlying job are changed."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a check in the job_controller integration test. Please take a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
/approve
LGTM label has been added. Git tree hash: eb17443205045edb36e8a055bd337161a9d89c32
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alculquicondor, pajakd The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
…sigs#1959) * Copy labels for a single job into the workload. * Copying of the labels from pod (and pod groups) * KEP first draft * Unit tests for pod reconciler * Unit test for label copying from job to workload * Unit test for the case of label mismatch * Typos fix * Fix typos * Update the autogenerated file * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments
…sigs#1959) * Copy labels for a single job into the workload. * Copying of the labels from pod (and pod groups) * KEP first draft * Unit tests for pod reconciler * Unit test for label copying from job to workload * Unit test for the case of label mismatch * Typos fix * Fix typos * Update the autogenerated file * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments * Addressing PR comments
What type of PR is this?
/kind feature
What this PR does / why we need it:
When creating a Workload object from Pod/Job, copy labels of the Pod/Job into the Workload object. It will allow to easily identify and filter the Workload objects.
Which issue(s) this PR fixes:
Fixes #1834
Special notes for your reviewer:
Does this PR introduce a user-facing change?