jiebi/CodeConvo huggingface dataset:
Done(types.UID) Update(logger klog.Logger, oldPod, newPod *v1.Pod) Delete(pod *v1.Pod) <del> // TODO(sanposhiho): move all PreEnqueueCheck to Requeue and delete it from this parameter eventually. // Some PreEnqueueCheck include event filtering logic based on some in-tree plugins // and it affect badly to other plugins. // See https://github.com/kubernetes/kubernetes/issues/110175 </del> <ins> // Important Note: preCheck shouldn't include anything that depends on the in-tree plugins' logic. // (e.g., filter Pods based on added/updated Node's capacity, etc.) // We know currently some do, but we'll eventually remove them in favor of the scheduling queue hint. </ins> MoveAllToActiveOrBackoffQueue(logger klog.Logger, event framework.ClusterEvent, oldObj, newObj interface{}, preCheck PreEnqueueCheck) AssignedPodAdded(logger klog.Logger, pod *v1.Pod) AssignedPodUpdated(logger klog.Logger, oldPod, newPod *v1.Pod, event framework.ClusterEvent)
} func preCheckForNode(nodeInfo *framework.NodeInfo) queue.PreEnqueueCheck { <ins> if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { // QHint is initially created from the motivation of replacing this preCheck. // It assumes that the scheduler only has in-tree plugins, which is problematic for our extensibility. // Here, we skip preCheck if QHint is enabled, and we eventually remove it after QHint is graduated. return nil } </ins> // Note: the following checks doesn't take preemption into considerations, in very rare // cases (e.g., node resizing), "pod" may still fail a check but preemption helps. We deliberately // chose to ignore those cases as unschedulable pods will be re-queued eventually.
want: []bool{true, false, false, true, false, true, false, true, false}, }, { <ins> name: "no filtering when QHint is enabled", nodeFn: func() *v1.Node { return st.MakeNode().Name("fake-node").Label("hostname", "fake-node").Capacity(cpu8).Obj() }, existingPods: []*v1.Pod{ st.MakePod().Name("p").HostPort(80).Obj(), }, pods: []*v1.Pod{ st.MakePod().Name("p1").Req(cpu4).Obj(), st.MakePod().Name("p2").Req(cpu16).Obj(), st.MakePod().Name("p3").Req(cpu4).Req(cpu8).Obj(), st.MakePod().Name("p4").NodeAffinityIn("hostname", []string{"fake-node"}).Obj(), st.MakePod().Name("p5").NodeAffinityNotIn("hostname", []string{"fake-node"}).Obj(), st.MakePod().Name("p6").Obj(), st.MakePod().Name("p7").Node("invalid-node").Obj(), st.MakePod().Name("p8").HostPort(8080).Obj(), st.MakePod().Name("p9").HostPort(80).Obj(), }, qHintEnabled: true, want:         []bool{true, true, true, true, true, true, true, true, true}, }, { </ins> name: "tainted node, pods with a single constraint", nodeFn: func() *v1.Node { node := st.MakeNode().Name("fake-node").Obj()
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { <ins> featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerQueueingHints, tt.qHintEnabled) </ins> nodeInfo := framework.NewNodeInfo(tt.existingPods...) nodeInfo.SetNode(tt.nodeFn()) preCheckFn := preCheckForNode(nodeInfo) <del> var got []bool </del> <ins> got := make([]bool, 0, len(tt.pods)) </ins> for _, pod := range tt.pods { <del> got = append(got, preCheckFn(pod)) </del> <ins> got = append(got, preCheckFn == nil || preCheckFn(pod)) </ins> } if diff := cmp.Diff(tt.want, got); diff != "" {
} // newPodInformer creates a shared index informer that returns only non-terminal pods. <ins> // The PodInformer allows indexers to be added, but note that only non-conflict indexers are allowed. </ins> func newPodInformer(cs clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { selector := fmt.Sprintf("status.phase!=%v,status.phase!=%v", v1.PodSucceeded, v1.PodFailed) tweakListOptions := func(options *metav1.ListOptions) { options.FieldSelector = selector } <del> return coreinformers.NewFilteredPodInformer(cs, metav1.NamespaceAll, resyncPeriod, nil, tweakListOptions) </del> <ins> return coreinformers.NewFilteredPodInformer(cs, metav1.NamespaceAll, resyncPeriod, cache.Indexers{}, tweakListOptions) </ins> }
v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" <ins> "k8s.io/apimachinery/pkg/runtime" </ins> "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes"
visible at runtime in the container. release: v1.9 file: test/e2e/common/node/downwardapi.go <ins> - testname: Ephemeral Container Creation codename: '[sig-node] Ephemeral Containers [NodeConformance] will start an ephemeral container in an existing pod [Conformance]' description: Adding an ephemeral container to pod.spec MUST result in the container running. release: "1.25" file: test/e2e/common/node/ephemeral_containers.go </ins> - testname: init-container-starts-app-restartalways-pod codename: '[sig-node] InitContainer [NodeConformance] should invoke init containers on a RestartAlways pod [Conformance]'
podClient = f.PodClient() }) <del> ginkgo.It("will start an ephemeral container in an existing pod", func() { </del> <ins> // Release: 1.25 // Testname: Ephemeral Container Creation // Description: Adding an ephemeral container to pod.spec MUST result in the container running. framework.ConformanceIt("will start an ephemeral container in an existing pod", func() { </ins> ginkgo.By("creating a target pod") pod := podClient.CreateSync(&v1.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "ephemeral-containers-target-pod"},
ErrCacheNotFound = errors.New("not found") ) <ins> // Server returning empty ResourceList for Group/Version. type emptyResponseError struct { gv string } func (e *emptyResponseError) Error() string { return fmt.Sprintf("received empty response for: %s", e.gv) } </ins> var _ discovery.CachedDiscoveryInterface = &memCacheClient{} // isTransientConnectionError checks whether given error is "Connection refused" or
if cachedVal.err != nil && isTransientError(cachedVal.err) { r, err := d.serverResourcesForGroupVersion(groupVersion) if err != nil { <del> utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) </del> <ins> // Don't log "empty response" as an error; it is a common response for metrics. if _, emptyErr := err.(*emptyResponseError); emptyErr { // Log at same verbosity as disk cache. klog.V(3).Infof("%v", err) } else { utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) } </ins> } cachedVal = &cacheEntry{r, err} d.groupToServerResources[groupVersion] = cachedVal
r, err := d.serverResourcesForGroupVersion(gv) if err != nil { <del> utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) </del> <ins> // Don't log "empty response" as an error; it is a common response for metrics. if _, emptyErr := err.(*emptyResponseError); emptyErr { // Log at same verbosity as disk cache. klog.V(3).Infof("%v", err) } else { utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) } </ins> } resultLock.Lock()
return finalURL } <ins> // finalURLTemplate is similar to URL(), but will make all specific parameter values equal // - instead of name or namespace, "{name}" and "{namespace}" will be used, and all query // parameters will be reset. This creates a copy of the url so as not to change the // underlying object. func (r Request) finalURLTemplate() url.URL { newParams := url.Values{} v := []string{"{value}"} for k := range r.params { newParams[k] = v } r.params = newParams u := r.URL() if u == nil { return url.URL{} } segments := strings.Split(u.Path, "/") groupIndex := 0 index := 0 trimmedBasePath := "" if r.c.base != nil && strings.Contains(u.Path, r.c.base.Path) { p := strings.TrimPrefix(u.Path, r.c.base.Path) if !strings.HasPrefix(p, "/") { p = "/" + p } // store the base path that we have trimmed so we can append it // before returning the URL trimmedBasePath = r.c.base.Path segments = strings.Split(p, "/") groupIndex = 1 } if len(segments) <= 2 { return *u } const CoreGroupPrefix = "api" const NamedGroupPrefix = "apis" isCoreGroup := segments[groupIndex] == CoreGroupPrefix isNamedGroup := segments[groupIndex] == NamedGroupPrefix if isCoreGroup { // checking the case of core group with /api/v1/... format index = groupIndex + 2 } else if isNamedGroup { // checking the case of named group with /apis/apps/v1/... format index = groupIndex + 3 } else { // this should not happen that the only two possibilities are /api... and /apis..., just want to put an // outlet here in case more API groups are added in future if ever possible: // https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups // if a wrong API groups name is encountered, return the {prefix} for url.Path u.Path = "/{prefix}" u.RawQuery = "" return *u } // switch segLength := len(segments) - index; segLength { switch { // case len(segments) - index == 1: // resource (with no name) do nothing case len(segments)-index == 2: // /$RESOURCE/$NAME: replace $NAME with {name} segments[index+1] = "{name}" case len(segments)-index == 3: if segments[index+2] == "finalize" || segments[index+2] == "status" { // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name} segments[index+1] = "{name}" } else { // /namespace/$NAMESPACE/$RESOURCE: replace $NAMESPACE with {namespace} segments[index+1] = "{namespace}" } case len(segments)-index >= 4: segments[index+1] = "{namespace}" // /namespace/$NAMESPACE/$RESOURCE/$NAME: replace $NAMESPACE with {namespace},  $NAME with {name} if segments[index+3] != "finalize" && segments[index+3] != "status" { // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name} segments[index+3] = "{name}" } } u.Path = path.Join(trimmedBasePath, path.Join(segments...)) return *u } </ins> func (r *Request) tryThrottleWithInfo(ctx context.Context, retryInfo string) error { if r.rateLimiter == nil { return nil
"k8s.io/apiserver/pkg/storage/value" kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" <ins> "k8s.io/klog/v2" </ins> "k8s.io/utils/lru" )
value.RecordCacheMiss() } uid := string(uuid.NewUUID()) <ins> klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) </ins> key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{ Ciphertext:  encryptedObject.EncryptedDEK, KeyID:       encryptedObject.KeyID,
} uid := string(uuid.NewUUID()) <ins> klog.V(6).InfoS("Encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) </ins> resp, err := t.envelopeService.Encrypt(ctx, uid, newKey) if err != nil { return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
"k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" <ins> genericapirequest "k8s.io/apiserver/pkg/endpoints/request" </ins> "k8s.io/apiserver/pkg/storage/value" kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics"
if transformer == nil { value.RecordCacheMiss() <ins> requestInfo := getRequestInfoFromContext(ctx) </ins> uid := string(uuid.NewUUID()) <del> klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) </del> <ins> klog.V(6).InfoS("decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()), "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) </ins> key, err := t.envelopeService.Decrypt(ctx, uid, &kmsservice.DecryptRequest{ Ciphertext:  encryptedObject.EncryptedDEK, KeyID:       encryptedObject.KeyID,
return nil, err } <ins> requestInfo := getRequestInfoFromContext(ctx) </ins> uid := string(uuid.NewUUID()) <del> klog.V(6).InfoS("encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) </del> <ins> klog.V(6).InfoS("encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()), "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) </ins> resp, err := t.envelopeService.Encrypt(ctx, uid, newKey) if err != nil { return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
"bytes" "context" "encoding/base64" <ins> "flag" </ins> "fmt" "reflect" <ins> "regexp" </ins> "strconv" "strings" "testing" "time" <ins> genericapirequest "k8s.io/apiserver/pkg/endpoints/request" </ins> "k8s.io/apiserver/pkg/storage/value" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" "k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/metrics/testutil" <ins> "k8s.io/klog/v2" </ins> kmsservice "k8s.io/kms/pkg/service" testingclock "k8s.io/utils/clock/testing" )
}) } } <ins> func TestEnvelopeLogging(t *testing.T) { klog.InitFlags(nil) flag.Set("v", "6") flag.Parse() testCases := []struct { desc     string ctx      context.Context wantLogs []string }{ { desc: "no request info in context", ctx:  testContext(t), wantLogs: []string{ `"encrypting content using envelope service" uid="UID" key="0123456789" group="" version="" resource="" subresource="" verb="" namespace="" name=""`, `"decrypting content using envelope service" uid="UID" key="0123456789" group="" version="" resource="" subresource="" verb="" namespace="" name=""`, }, }, { desc: "request info in context", ctx: genericapirequest.WithRequestInfo(testContext(t), &genericapirequest.RequestInfo{ APIGroup:    "awesome.bears.com", APIVersion:  "v1", Resource:    "pandas", Subresource: "status", Namespace:   "kube-system", Name:        "panda", Verb:        "update", }), wantLogs: []string{ `"encrypting content using envelope service" uid="UID" key="0123456789" group="awesome.bears.com" version="v1" resource="pandas" subresource="status" verb="update" namespace="kube-system" name="panda"`, `"decrypting content using envelope service" uid="UID" key="0123456789" group="awesome.bears.com" version="v1" resource="pandas" subresource="status" verb="update" namespace="kube-system" name="panda"`, }, }, } for _, tc := range testCases { tc := tc t.Run(tc.desc, func(t *testing.T) { var buf bytes.Buffer klog.SetOutput(&buf) klog.LogToStderr(false) defer klog.LogToStderr(true) envelopeService := newTestEnvelopeService() fakeClock := testingclock.NewFakeClock(time.Now()) envelopeTransformer := newEnvelopeTransformerWithClock(envelopeService, testProviderName, func(ctx context.Context) (string, error) { return "1", nil }, func(ctx context.Context) error { return nil }, aestransformer.NewGCMTransformer, 1*time.Second, fakeClock) dataCtx := value.DefaultContext([]byte(testContextText)) originalText := []byte(testText) transformedData, err := envelopeTransformer.TransformToStorage(tc.ctx, originalText, dataCtx) if err != nil { t.Fatalf("envelopeTransformer: error while transforming data to storage: %v", err) } // advance the clock to trigger cache to expire, so we make a decrypt call that will log fakeClock.Step(2 * time.Second) _, _, err = envelopeTransformer.TransformFromStorage(tc.ctx, transformedData, dataCtx) if err != nil { t.Fatalf("could not decrypt Envelope transformer's encrypted data even once: %v", err) } klog.Flush() klog.SetOutput(&bytes.Buffer{}) // prevent further writes into buf capturedOutput := buf.String() // replace the uid with a constant to make the test output stable and assertable capturedOutput = regexp.MustCompile(`uid="[^"]+"`).ReplaceAllString(capturedOutput, `uid="UID"`) for _, wantLog := range tc.wantLogs { if !strings.Contains(capturedOutput, wantLog) { t.Errorf("expected log %q, got %q", wantLog, capturedOutput) } } }) } } </ins>
import ( "context" <ins> "encoding/json" </ins> "fmt" "reflect" "strconv" "time" v1 "k8s.io/api/core/v1" <ins> apiequality "k8s.io/apimachinery/pkg/api/equality" </ins> "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" <ins> "k8s.io/apimachinery/pkg/types" utilrand "k8s.io/apimachinery/pkg/util/rand" </ins> "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch"
}, } } <ins> func checkLimitRangeListQuantity(f *framework.Framework, label string, quantity int) func() (bool, error) { return func() (bool, error) { framework.Logf("Requesting list of LimitRange to confirm quantity") list, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{LabelSelector: label}) if err != nil { return false, err } if len(list.Items) != quantity { return false, nil } framework.Logf("Found %d LimitRange with label %q", quantity, label) return true, nil } } </ins>
validate the pod resources are applied to the Limitrange release: v1.18 file: test/e2e/scheduling/limit_range.go <ins> - testname: LimitRange, list, patch and delete a LimitRange by collection codename: '[sig-scheduling] LimitRange should list, patch and delete a LimitRange by collection [Conformance]' description: When two limitRanges are created in different namespaces, both MUST succeed. Listing limitRanges across all namespaces with a labelSelector MUST find both limitRanges. When patching the first limitRange it MUST succeed and the fields MUST equal the new values. When deleting the limitRange by collection with a labelSelector it MUST delete only one limitRange. release: v1.26 file: test/e2e/scheduling/limit_range.go </ins> - testname: Scheduler, resource limits codename: '[sig-scheduling] SchedulerPredicates [Serial] validates resource limits of pods that are allowed to run  [Conformance]'
framework.ExpectNoError(err) }) <del> ginkgo.It("should list, patch and delete a LimitRange by collection", func() { </del> <ins> /* Release: v1.26 Testname: LimitRange, list, patch and delete a LimitRange by collection Description: When two limitRanges are created in different namespaces, both MUST succeed. Listing limitRanges across all namespaces with a labelSelector MUST find both limitRanges. When patching the first limitRange it MUST succeed and the fields MUST equal the new values. When deleting the limitRange by collection with a labelSelector it MUST delete only one limitRange. */ framework.ConformanceIt("should list, patch and delete a LimitRange by collection", func() { </ins> ns := f.Namespace.Name lrClient := f.ClientSet.CoreV1().LimitRanges(ns)
if _, err := dc.coreClient.CoreV1().Pods(tc.pod.Namespace).Create(ctx, tc.pod, metav1.CreateOptions{}); err != nil { t.Fatalf("Failed to create pod: %v", err) } <ins> dc.clock.Sleep(tc.timePassed) </ins> if err := dc.informerFactory.Core().V1().Pods().Informer().GetIndexer().Add(tc.pod); err != nil { t.Fatalf("Failed adding pod to indexer: %v", err) } <del> dc.clock.Sleep(tc.timePassed) </del> <ins> diff := "" </ins> if err := wait.Poll(100*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { <del> return dc.stalePodDisruptionQueue.Len() == 0, nil </del> <ins> pod, err := dc.kubeClient.CoreV1().Pods(tc.pod.Namespace).Get(ctx, tc.pod.Name, metav1.GetOptions{}) if err != nil { t.Fatalf("Failed getting updated pod: %v", err) } diff = cmp.Diff(tc.wantConditions, pod.Status.Conditions, cmpopts.IgnoreFields(v1.PodCondition{}, "LastTransitionTime")) return diff == "", nil </ins> }); err != nil { <del> t.Fatalf("Failed waiting for worker to sync: %v", err) } pod, err := dc.kubeClient.CoreV1().Pods(tc.pod.Namespace).Get(ctx, tc.pod.Name, metav1.GetOptions{}) if err != nil { t.Fatalf("Failed getting updated pod: %v", err) } diff := cmp.Diff(tc.wantConditions, pod.Status.Conditions, cmpopts.IgnoreFields(v1.PodCondition{}, "LastTransitionTime")) if diff != "" { t.Errorf("Obtained pod conditions (-want,+got):n%s", diff) </del> <ins> t.Fatalf("Failed waiting for worker to sync: %v, (-want,+got):n%s", err, diff) </ins> } }) }
} else { klog.V(3).InfoS("Skipped creating Hns LoadBalancer for loadBalancer Ingress resources", "lbIngressIP", lbIngressIP) } <del> lbIngressIP.hnsID = hnsLoadBalancer.hnsID klog.V(3).InfoS("Hns LoadBalancer resource created for loadBalancer Ingress resources", "lbIngressIP", lbIngressIP) </del> if proxier.forwardHealthCheckVip && gatewayHnsendpoint != nil { nodeport := proxier.healthzPort
job.Status.CompletedIndexes = succeededIndexes.String() } job.Status.UncountedTerminatedPods = nil <del> jm.enactJobFinished(&job, finishedCondition) </del> <ins> jobFinished := jm.enactJobFinished(&job, finishedCondition) </ins> if _, err := jm.updateStatusHandler(ctx, &job); err != nil { return forget, err } <ins> if jobFinished { jm.recordJobFinished(&job, finishedCondition) } </ins> if jobHasNewFailure && !IsJobFinished(&job) { // returning an error will re-enqueue Job after the backoff period
if job, needsFlush, err = jm.flushUncountedAndRemoveFinalizers(ctx, job, podsToRemoveFinalizer, uidsWithFinalizer, &oldCounters, needsFlush); err != nil { return err } <del> if jm.enactJobFinished(job, finishedCond) { </del> <ins> jobFinished := jm.enactJobFinished(job, finishedCond) if jobFinished { </ins> needsFlush = true } if needsFlush { if _, err := jm.updateStatusHandler(ctx, job); err != nil { return fmt.Errorf("removing uncounted pods from status: %w", err) } <ins> if jobFinished { jm.recordJobFinished(job, finishedCond) } </ins> recordJobPodFinished(job, oldCounters) } return nil
return false } } <del> completionMode := string(batch.NonIndexedCompletion) if isIndexedJob(job) { completionMode = string(*job.Spec.CompletionMode) } </del> job.Status.Conditions, _ = ensureJobConditionStatus(job.Status.Conditions, finishedCond.Type, finishedCond.Status, finishedCond.Reason, finishedCond.Message) if finishedCond.Type == batch.JobComplete { <ins> job.Status.CompletionTime = &finishedCond.LastTransitionTime } return true } // recordJobFinished records events and the job_finished_total metric for a finished job. func (jm *Controller) recordJobFinished(job *batch.Job, finishedCond *batch.JobCondition) bool { completionMode := getCompletionMode(job) if finishedCond.Type == batch.JobComplete { </ins> if job.Spec.Completions != nil && job.Status.Succeeded > *job.Spec.Completions { jm.recorder.Event(job, v1.EventTypeWarning, "TooManySucceededPods", "Too many succeeded pods running after completion count reached") } <del> job.Status.CompletionTime = &finishedCond.LastTransitionTime </del> jm.recorder.Event(job, v1.EventTypeNormal, "Completed", "Job completed") metrics.JobFinishedNum.WithLabelValues(completionMode, "succeeded").Inc() } else {
return result } <ins> // getCompletionMode returns string representation of the completion mode. Used as a label value for metrics. func getCompletionMode(job *batch.Job) string { if isIndexedJob(job) { return string(batch.IndexedCompletion) } return string(batch.NonIndexedCompletion) } </ins> func trackingUncountedPods(job *batch.Job) bool { return feature.DefaultFeatureGate.Enabled(features.JobTrackingWithFinalizers) && hasJobTrackingAnnotation(job) }
"k8s.io/client-go/restmapper" "k8s.io/client-go/util/retry" featuregatetesting "k8s.io/component-base/featuregate/testing" <ins> basemetrics "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/testutil" </ins> "k8s.io/controller-manager/pkg/informerfactory" "k8s.io/klog/v2" kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/controller/garbagecollector" jobcontroller "k8s.io/kubernetes/pkg/controller/job" <ins> "k8s.io/kubernetes/pkg/controller/job/metrics" </ins> "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/test/integration/framework" "k8s.io/utils/pointer"
componentbaseconfig "k8s.io/component-base/config" "k8s.io/component-base/configz" "k8s.io/component-base/logs" <ins> metricsfeatures "k8s.io/component-base/metrics/features" </ins> "k8s.io/component-base/metrics/legacyregistry" <ins> "k8s.io/component-base/metrics/prometheus/slis" </ins> "k8s.io/component-base/version" "k8s.io/component-base/version/verflag" "k8s.io/klog/v2"