diff --git a/kubernetes_platform/go/kubernetesplatform/kubernetes_executor_config.pb.go b/kubernetes_platform/go/kubernetesplatform/kubernetes_executor_config.pb.go index bff68860500..c536b54152a 100644 --- a/kubernetes_platform/go/kubernetesplatform/kubernetes_executor_config.pb.go +++ b/kubernetes_platform/go/kubernetesplatform/kubernetes_executor_config.pb.go @@ -44,6 +44,7 @@ type KubernetesExecutorConfig struct { SecretAsEnv []*SecretAsEnv `protobuf:"bytes,2,rep,name=secret_as_env,json=secretAsEnv,proto3" json:"secret_as_env,omitempty"` PvcMount []*PvcMount `protobuf:"bytes,3,rep,name=pvc_mount,json=pvcMount,proto3" json:"pvc_mount,omitempty"` NodeSelector *NodeSelector `protobuf:"bytes,4,opt,name=node_selector,json=nodeSelector,proto3" json:"node_selector,omitempty"` + PodMetadata *PodMetadata `protobuf:"bytes,5,opt,name=pod_metadata,json=podMetadata,proto3" json:"pod_metadata,omitempty"` } func (x *KubernetesExecutorConfig) Reset() { @@ -106,6 +107,13 @@ func (x *KubernetesExecutorConfig) GetNodeSelector() *NodeSelector { return nil } +func (x *KubernetesExecutorConfig) GetPodMetadata() *PodMetadata { + if x != nil { + return x.PodMetadata + } + return nil +} + type SecretAsVolume struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -674,6 +682,63 @@ func (x *NodeSelector) GetLabels() map[string]string { return nil } +type PodMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // values of metadata spec such as labels and annotations for the pod object + // corresponds to Pod.metadata field https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#Pod + Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Annotations map[string]string `protobuf:"bytes,2,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PodMetadata) Reset() { + *x = PodMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_kubernetes_executor_config_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodMetadata) ProtoMessage() {} + +func (x *PodMetadata) ProtoReflect() protoreflect.Message { + mi := &file_kubernetes_executor_config_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodMetadata.ProtoReflect.Descriptor instead. +func (*PodMetadata) Descriptor() ([]byte, []int) { + return file_kubernetes_executor_config_proto_rawDescGZIP(), []int{8} +} + +func (x *PodMetadata) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *PodMetadata) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + type SecretAsEnv_SecretKeyToEnvMap struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -688,7 +753,7 @@ type SecretAsEnv_SecretKeyToEnvMap struct { func (x *SecretAsEnv_SecretKeyToEnvMap) Reset() { *x = SecretAsEnv_SecretKeyToEnvMap{} if protoimpl.UnsafeEnabled { - mi := &file_kubernetes_executor_config_proto_msgTypes[8] + mi := &file_kubernetes_executor_config_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -701,7 +766,7 @@ func (x *SecretAsEnv_SecretKeyToEnvMap) String() string { func (*SecretAsEnv_SecretKeyToEnvMap) ProtoMessage() {} func (x *SecretAsEnv_SecretKeyToEnvMap) ProtoReflect() protoreflect.Message { - mi := &file_kubernetes_executor_config_proto_msgTypes[8] + mi := &file_kubernetes_executor_config_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -739,7 +804,7 @@ var file_kubernetes_executor_config_proto_rawDesc = []byte{ 0x74, 0x6f, 0x12, 0x0e, 0x6b, 0x66, 0x70, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x9f, 0x02, 0x0a, 0x18, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x45, + 0x22, 0xdf, 0x02, 0x0a, 0x18, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x48, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x61, 0x73, 0x5f, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6b, 0x66, 0x70, 0x5f, 0x6b, 0x75, @@ -757,7 +822,11 @@ var file_kubernetes_executor_config_proto_rawDesc = []byte{ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6b, 0x66, 0x70, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x22, 0x50, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x41, 0x73, 0x56, 0x6f, + 0x6f, 0x72, 0x12, 0x3e, 0x0a, 0x0c, 0x70, 0x6f, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6b, 0x66, 0x70, 0x5f, 0x6b, + 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x50, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x41, 0x73, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, @@ -841,12 +910,30 @@ var file_kubernetes_executor_config_proto_rawDesc = []byte{ 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x73, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x75, 0x62, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x02, 0x38, 0x01, 0x22, 0x99, 0x02, 0x0a, 0x0b, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6b, 0x66, 0x70, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6b, 0x66, 0x70, 0x5f, + 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, + 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, + 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, + 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x65, 0x73, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -861,7 +948,7 @@ func file_kubernetes_executor_config_proto_rawDescGZIP() []byte { return file_kubernetes_executor_config_proto_rawDescData } -var file_kubernetes_executor_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_kubernetes_executor_config_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_kubernetes_executor_config_proto_goTypes = []interface{}{ (*KubernetesExecutorConfig)(nil), // 0: kfp_kubernetes.KubernetesExecutorConfig (*SecretAsVolume)(nil), // 1: kfp_kubernetes.SecretAsVolume @@ -871,25 +958,31 @@ var file_kubernetes_executor_config_proto_goTypes = []interface{}{ (*CreatePvc)(nil), // 5: kfp_kubernetes.CreatePvc (*DeletePvc)(nil), // 6: kfp_kubernetes.DeletePvc (*NodeSelector)(nil), // 7: kfp_kubernetes.NodeSelector - (*SecretAsEnv_SecretKeyToEnvMap)(nil), // 8: kfp_kubernetes.SecretAsEnv.SecretKeyToEnvMap - nil, // 9: kfp_kubernetes.NodeSelector.LabelsEntry - (*structpb.Struct)(nil), // 10: google.protobuf.Struct + (*PodMetadata)(nil), // 8: kfp_kubernetes.PodMetadata + (*SecretAsEnv_SecretKeyToEnvMap)(nil), // 9: kfp_kubernetes.SecretAsEnv.SecretKeyToEnvMap + nil, // 10: kfp_kubernetes.NodeSelector.LabelsEntry + nil, // 11: kfp_kubernetes.PodMetadata.LabelsEntry + nil, // 12: kfp_kubernetes.PodMetadata.AnnotationsEntry + (*structpb.Struct)(nil), // 13: google.protobuf.Struct } var file_kubernetes_executor_config_proto_depIdxs = []int32{ 1, // 0: kfp_kubernetes.KubernetesExecutorConfig.secret_as_volume:type_name -> kfp_kubernetes.SecretAsVolume 2, // 1: kfp_kubernetes.KubernetesExecutorConfig.secret_as_env:type_name -> kfp_kubernetes.SecretAsEnv 4, // 2: kfp_kubernetes.KubernetesExecutorConfig.pvc_mount:type_name -> kfp_kubernetes.PvcMount 7, // 3: kfp_kubernetes.KubernetesExecutorConfig.node_selector:type_name -> kfp_kubernetes.NodeSelector - 8, // 4: kfp_kubernetes.SecretAsEnv.key_to_env:type_name -> kfp_kubernetes.SecretAsEnv.SecretKeyToEnvMap - 3, // 5: kfp_kubernetes.PvcMount.task_output_parameter:type_name -> kfp_kubernetes.TaskOutputParameterSpec - 10, // 6: kfp_kubernetes.CreatePvc.annotations:type_name -> google.protobuf.Struct - 3, // 7: kfp_kubernetes.DeletePvc.task_output_parameter:type_name -> kfp_kubernetes.TaskOutputParameterSpec - 9, // 8: kfp_kubernetes.NodeSelector.labels:type_name -> kfp_kubernetes.NodeSelector.LabelsEntry - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 8, // 4: kfp_kubernetes.KubernetesExecutorConfig.pod_metadata:type_name -> kfp_kubernetes.PodMetadata + 9, // 5: kfp_kubernetes.SecretAsEnv.key_to_env:type_name -> kfp_kubernetes.SecretAsEnv.SecretKeyToEnvMap + 3, // 6: kfp_kubernetes.PvcMount.task_output_parameter:type_name -> kfp_kubernetes.TaskOutputParameterSpec + 13, // 7: kfp_kubernetes.CreatePvc.annotations:type_name -> google.protobuf.Struct + 3, // 8: kfp_kubernetes.DeletePvc.task_output_parameter:type_name -> kfp_kubernetes.TaskOutputParameterSpec + 10, // 9: kfp_kubernetes.NodeSelector.labels:type_name -> kfp_kubernetes.NodeSelector.LabelsEntry + 11, // 10: kfp_kubernetes.PodMetadata.labels:type_name -> kfp_kubernetes.PodMetadata.LabelsEntry + 12, // 11: kfp_kubernetes.PodMetadata.annotations:type_name -> kfp_kubernetes.PodMetadata.AnnotationsEntry + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_kubernetes_executor_config_proto_init() } @@ -995,6 +1088,18 @@ func file_kubernetes_executor_config_proto_init() { } } file_kubernetes_executor_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_kubernetes_executor_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SecretAsEnv_SecretKeyToEnvMap); i { case 0: return &v.state @@ -1027,7 +1132,7 @@ func file_kubernetes_executor_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_kubernetes_executor_config_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/kubernetes_platform/proto/kubernetes_executor_config.proto b/kubernetes_platform/proto/kubernetes_executor_config.proto index 8bba56463c8..8b215c8ae12 100644 --- a/kubernetes_platform/proto/kubernetes_executor_config.proto +++ b/kubernetes_platform/proto/kubernetes_executor_config.proto @@ -25,6 +25,7 @@ message KubernetesExecutorConfig { repeated SecretAsEnv secret_as_env = 2; repeated PvcMount pvc_mount = 3; NodeSelector node_selector = 4; + PodMetadata pod_metadata = 5; } message SecretAsVolume { @@ -114,3 +115,10 @@ message NodeSelector { // corresponds to Pod.spec.nodeSelector field https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling map labels = 1; } + +message PodMetadata { + // values of metadata spec such as labels and annotations for the pod object + // corresponds to Pod.metadata field https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#Pod + map labels = 1; + map annotations = 2; +} diff --git a/kubernetes_platform/python/kfp/kubernetes/__init__.py b/kubernetes_platform/python/kfp/kubernetes/__init__.py index 587e5132b07..c2c266becf0 100644 --- a/kubernetes_platform/python/kfp/kubernetes/__init__.py +++ b/kubernetes_platform/python/kfp/kubernetes/__init__.py @@ -21,8 +21,12 @@ 'use_secret_as_env', 'use_secret_as_volume', 'add_node_selector', + 'add_pod_label', + 'add_pod_annotation', ] +from kfp.kubernetes.pod_metadata import add_pod_label +from kfp.kubernetes.pod_metadata import add_pod_annotation from kfp.kubernetes.node_selector import add_node_selector from kfp.kubernetes.secret import use_secret_as_env from kfp.kubernetes.secret import use_secret_as_volume diff --git a/kubernetes_platform/python/kfp/kubernetes/pod_metadata.py b/kubernetes_platform/python/kfp/kubernetes/pod_metadata.py new file mode 100644 index 00000000000..dc8571b1284 --- /dev/null +++ b/kubernetes_platform/python/kfp/kubernetes/pod_metadata.py @@ -0,0 +1,69 @@ +# Copyright 2024 The Kubeflow Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from google.protobuf import json_format +from kfp.dsl import PipelineTask +from kfp.kubernetes import common + + +def add_pod_label( + task: PipelineTask, + label_key: str, + label_value: str, +) -> PipelineTask: + """Add a label to the task Pod's `metadata + `_. + + Each label is a key-value pair, corresponding to the metadata's `ObjectMeta PipelineTask: + """Add an annotation to the task Pod's `metadata + `_. + + Each annotation is a key-value pair, corresponding to the metadata's `ObjectMeta