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

Add Trial Labels During Pod Mutation #2047

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
2 changes: 2 additions & 0 deletions pkg/controller.v1beta1/consts/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ const (
LabelExperimentName = "katib.kubeflow.org/experiment"
// LabelSuggestionName is the label of suggestion name.
LabelSuggestionName = "katib.kubeflow.org/suggestion"
// LabelTrialName is the label of trial name.
LabelTrialName = "katib.kubeflow.org/trial"
// LabelDeploymentName is the label of deployment name.
LabelDeploymentName = "katib.kubeflow.org/deployment"

Expand Down
28 changes: 16 additions & 12 deletions pkg/webhook/v1beta1/pod/inject_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (s *SidecarInjector) Handle(ctx context.Context, req admission.Request) adm
// Do mutation
mutatedPod, err := s.Mutate(pod, namespace)
if err != nil {
log.Error(err, "Failed to inject metrics collector")
log.Error(err, "Failed to mutate Trial's pod")
return admission.Errored(http.StatusBadRequest, err)
}

Expand Down Expand Up @@ -124,17 +124,6 @@ func (s *SidecarInjector) MutationRequired(pod *v1.Pod, ns string) (bool, error)
return false, err
}

// If PrimaryPodLabel is not set we mutate all pods which are related to Trial job
// Otherwise mutate pod only with appropriate labels
if trial.Spec.PrimaryPodLabels != nil {
if !isPrimaryPod(pod.Labels, trial.Spec.PrimaryPodLabels) {
return false, nil
}
}

if trial.Spec.MetricsCollector.Collector.Kind == common.NoneCollector {
return false, nil
}
return true, nil
}

Expand All @@ -155,6 +144,21 @@ func (s *SidecarInjector) Mutate(pod *v1.Pod, namespace string) (*v1.Pod, error)
return nil, err
}

// Add Katib Trial labels to the Pod metadata.
mutatePodMetadata(mutatedPod, trial)

// Do the following mutation only for the Primary pod.
// If PrimaryPodLabel is not set we mutate all pods which are related to Trial job.
// Otherwise, mutate pod only with the appropriate labels.
if trial.Spec.PrimaryPodLabels != nil && !isPrimaryPod(pod.Labels, trial.Spec.PrimaryPodLabels) {
return mutatedPod, nil
}

// If Metrics Collector in None, skip the mutation.
if trial.Spec.MetricsCollector.Collector.Kind == common.NoneCollector {
return mutatedPod, nil
}

// Create metrics sidecar container spec
injectContainer, err := s.getMetricsCollectorContainer(trial, pod)
if err != nil {
Expand Down
46 changes: 46 additions & 0 deletions pkg/webhook/v1beta1/pod/inject_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1019,3 +1019,49 @@ func TestIsPrimaryPod(t *testing.T) {
}
}
}

func TestMutatePodMetadata(t *testing.T) {
mutatedPodLabels := map[string]string{
"custom-pod-label": "custom-value",
"katib-experiment": "katib-value",
consts.LabelTrialName: "test-trial",
}

testCases := []struct {
pod *v1.Pod
trial *trialsv1beta1.Trial
mutatedPod *v1.Pod
testDescription string
}{
{
pod: &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"custom-pod-label": "custom-value",
},
},
},
trial: &trialsv1beta1.Trial{
ObjectMeta: metav1.ObjectMeta{
Name: "test-trial",
Labels: map[string]string{
"katib-experiment": "katib-value",
},
},
},
mutatedPod: &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Labels: mutatedPodLabels,
},
},
testDescription: "Mutated Pod should contain label from the origin Pod and Trial",
},
}

for _, tc := range testCases {
mutatePodMetadata(tc.pod, tc.trial)
if !reflect.DeepEqual(tc.mutatedPod, tc.pod) {
t.Errorf("Case %v. Expected Pod %v, got %v", tc.testDescription, tc.mutatedPod, tc.pod)
}
}
}
21 changes: 21 additions & 0 deletions pkg/webhook/v1beta1/pod/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

common "github.com/kubeflow/katib/pkg/apis/controller/common/v1beta1"
trialsv1beta1 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1beta1"
"github.com/kubeflow/katib/pkg/controller.v1beta1/consts"
mccommon "github.com/kubeflow/katib/pkg/metricscollector/v1beta1/common"
)

Expand Down Expand Up @@ -260,6 +261,26 @@ func mutateMetricsCollectorVolume(pod *v1.Pod, mountPath, sidecarContainerName,
return nil
}

func mutatePodMetadata(pod *v1.Pod, trial *trialsv1beta1.Trial) {
podLabels := map[string]string{}

// Get labels from the created pod.
if pod.Labels != nil {
podLabels = pod.Labels
}

// Get labels from Trial.
for k, v := range trial.Labels {
podLabels[k] = v
}

// Add Trial name label.
podLabels[consts.LabelTrialName] = trial.GetName()

// Append label to the Pod metadata.
pod.Labels = podLabels
}

func getSidecarContainerName(cKind common.CollectorKind) string {
if cKind == common.StdOutCollector || cKind == common.FileCollector {
return mccommon.MetricLoggerCollectorContainerName
Expand Down