Skip to content

[cherry-pick] prevent dynamic service deletion during upgrade#16153

Merged
bhardwaj-priyanshu merged 1 commit into
release/6.11from
fix/service-creation-cherry-pick
May 29, 2026
Merged

[cherry-pick] prevent dynamic service deletion during upgrade#16153
bhardwaj-priyanshu merged 1 commit into
release/6.11from
fix/service-creation-cherry-pick

Conversation

@bhardwaj-priyanshu
Copy link
Copy Markdown
Contributor

Cherry Pick of #16151

@bhardwaj-priyanshu bhardwaj-priyanshu added the build Triggers github actions build label May 29, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates KubeDiscoveryService to skip service registration if the current pod is terminating, and to trigger service updates if the owner references of a service have changed. The review feedback identifies a potential NullPointerException when handling nullable expected owner references, and suggests making the pod termination check more robust by handling non-404 ApiExceptions (such as RBAC or transient errors) and guarding against a null podName.

Comment on lines +384 to +390
private boolean hasOwnerReferencesChanged(V1Service currentService,
@Nullable List<V1OwnerReference> expectedOwners) {
List<V1OwnerReference> currentOwners = Optional.ofNullable(currentService.getMetadata())
.map(V1ObjectMeta::getOwnerReferences).orElse(Collections.emptyList());

return !new HashSet<>(currentOwners).equals(new HashSet<>(expectedOwners));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The expectedOwners parameter is annotated with @Nullable, but passing a null value to new HashSet<>(expectedOwners) will throw a NullPointerException. We should safely handle the case where expectedOwners is null by defaulting to an empty list.

Suggested change
private boolean hasOwnerReferencesChanged(V1Service currentService,
@Nullable List<V1OwnerReference> expectedOwners) {
List<V1OwnerReference> currentOwners = Optional.ofNullable(currentService.getMetadata())
.map(V1ObjectMeta::getOwnerReferences).orElse(Collections.emptyList());
return !new HashSet<>(currentOwners).equals(new HashSet<>(expectedOwners));
}
private boolean hasOwnerReferencesChanged(V1Service currentService,
@Nullable List<V1OwnerReference> expectedOwners) {
List<V1OwnerReference> currentOwners = Optional.ofNullable(currentService.getMetadata())
.map(V1ObjectMeta::getOwnerReferences).orElse(Collections.emptyList());
List<V1OwnerReference> expected = expectedOwners == null ? Collections.emptyList() : expectedOwners;
return !new HashSet<>(currentOwners).equals(new HashSet<>(expected));
}

Comment on lines +392 to +405
private boolean isPodTerminating(CoreV1Api api) throws ApiException {
try {
V1Pod pod = api.readNamespacedPod(podName, namespace, null);
return Optional.ofNullable(pod.getMetadata()).map(V1ObjectMeta::getDeletionTimestamp)
.isPresent();

} catch (ApiException e) {
// If it is a 404 ApiException, the pod is already gone. Treat as terminating.
if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) {
return true;
}
throw e;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

If the Kubernetes service account lacks permissions to read pods (e.g., due to RBAC restrictions returning 403 Forbidden) or if there is a transient API error, readNamespacedPod will throw an ApiException. Currently, this exception is rethrown, which will cause the entire service registration to fail. To make this more robust, we should catch ApiException, log a warning, and return false (assuming the pod is not terminating) so that service registration can still proceed. Additionally, we should guard against podName being null.

  private boolean isPodTerminating(CoreV1Api api) {
    if (podName == null) {
      return false;
    }
    try {
      V1Pod pod = api.readNamespacedPod(podName, namespace, null);
      return Optional.ofNullable(pod.getMetadata()).map(V1ObjectMeta::getDeletionTimestamp)
          .isPresent();
    } catch (ApiException e) {
      // If it is a 404 ApiException, the pod is already gone. Treat as terminating.
      if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) {
        return true;
      }
      LOG.warn("Failed to read pod status for {}. Assuming pod is not terminating.", podName, e);
      return false;
    }
  }

@bhardwaj-priyanshu bhardwaj-priyanshu force-pushed the fix/service-creation-cherry-pick branch from d25bff8 to 312e3cd Compare May 29, 2026 11:42
@bhardwaj-priyanshu bhardwaj-priyanshu marked this pull request as ready for review May 29, 2026 11:44
@sahusanket sahusanket changed the title prevent dynamic service deletion during upgrade [cherry-pick] prevent dynamic service deletion during upgrade May 29, 2026
@bhardwaj-priyanshu bhardwaj-priyanshu merged commit d1813c3 into release/6.11 May 29, 2026
10 checks passed
@bhardwaj-priyanshu bhardwaj-priyanshu deleted the fix/service-creation-cherry-pick branch May 29, 2026 13:28
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
37.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Triggers github actions build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants