This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 4438d99c4d Review "Fail the start when the Kubernetes service account 
token..."
4438d99c4d is described below

commit 4438d99c4d6146f8772274b03bdefc66701e76a1
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Oct 22 19:43:48 2026 +0100

    Review "Fail the start when the Kubernetes service account token..."
    
    Handle additional failure modes
    Leave failed start in clean state
    
    Co-authored by: Claude / Sonnet 5.5
---
 .../tribes/membership/cloud/KubernetesMembershipProvider.java | 11 +++++++----
 .../membership/cloud/TestKubernetesMembershipProvider.java    | 10 +++++++++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git 
a/java/org/apache/catalina/tribes/membership/cloud/KubernetesMembershipProvider.java
 
b/java/org/apache/catalina/tribes/membership/cloud/KubernetesMembershipProvider.java
index b0c76371f5..9410e90f87 100644
--- 
a/java/org/apache/catalina/tribes/membership/cloud/KubernetesMembershipProvider.java
+++ 
b/java/org/apache/catalina/tribes/membership/cloud/KubernetesMembershipProvider.java
@@ -67,8 +67,6 @@ public class KubernetesMembershipProvider extends 
CloudMembershipProvider {
             return;
         }
 
-        super.start(level);
-
         // Set up Kubernetes API parameters
         String namespace = getNamespace();
 
@@ -111,8 +109,9 @@ public class KubernetesMembershipProvider extends 
CloudMembershipProvider {
         } else {
             String clientKeyFile = getEnv("KUBERNETES_CLIENT_KEY_FILE");
             if (clientKeyFile == null) {
-                log.error(sm.getString("kubernetesMembershipProvider.noKey"));
-                return;
+                // Without the key, the Kubernetes API cannot be accessed and 
a provider without a stream provider
+                // never recovers. Fail the start, as is done when the service 
account token cannot be read.
+                throw new 
IllegalStateException(sm.getString("kubernetesMembershipProvider.noKey"));
             }
             String clientKeyPassword = 
getEnv("KUBERNETES_CLIENT_KEY_PASSWORD");
             String clientKeyAlgo = getEnv("KUBERNETES_CLIENT_KEY_ALGO");
@@ -143,6 +142,10 @@ public class KubernetesMembershipProvider extends 
CloudMembershipProvider {
             url = url + "?labelSelector=" + labels;
         }
 
+        // Everything that can reject the configuration is done. Only now 
create the membership and register as a
+        // channel listener so that a failed start does not leave the listener 
registered.
+        super.start(level);
+
         // Fetch initial members
         heartbeat();
     }
diff --git 
a/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
 
b/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
index 335d3d1244..48337a7764 100644
--- 
a/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
+++ 
b/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
@@ -47,7 +47,7 @@ public class TestKubernetesMembershipProvider {
         Assume.assumeFalse(Files.exists(
                 
FileSystems.getDefault().getPath("/var/run/secrets/kubernetes.io/serviceaccount/token")));
 
-        GroupChannel channel = new GroupChannel();
+        ListenerCountingChannel channel = new ListenerCountingChannel();
         channel.setName("TestKubernetesMembershipProvider-" + 
System.nanoTime());
 
         CloudMembershipService service = new CloudMembershipService();
@@ -60,6 +60,8 @@ public class TestKubernetesMembershipProvider {
             // The start fails closed rather than running without access to 
the API
             Assert.assertTrue(expected.getCause() instanceof IOException);
         }
+        // A failed start must not leave the provider registered as a channel 
listener
+        Assert.assertEquals(0, channel.getListenerCount());
     }
 
 
@@ -107,4 +109,10 @@ public class TestKubernetesMembershipProvider {
         }
         Assert.assertNull(service.getMembershipProvider());
     }
+
+    private static class ListenerCountingChannel extends GroupChannel {
+        int getListenerCount() {
+            return channelListeners.size();
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to