Added script installKind to fix the chicken-n-egg problem around cluster detection.  Wrap call in a try/catch block until build system behavior is known

Change-Id: I874e841e6076e9f59c16213f575b14f7023388ab
diff --git a/jjb/pipeline/voltha/master/bbsim-tests.groovy b/jjb/pipeline/voltha/master/bbsim-tests.groovy
index 6a2330f..a41060f 100644
--- a/jjb/pipeline/voltha/master/bbsim-tests.groovy
+++ b/jjb/pipeline/voltha/master/bbsim-tests.groovy
@@ -282,18 +282,39 @@
         buildVolthaComponent("${gerritProject}")
       }
     }
-    stage('Create K8s Cluster') {
-      steps {
-        script {
-          def clusterExists = sh returnStdout: true, script: """
+
+    stage('Create K8s Cluster')
+    {
+        steps
+	{
+	    script
+	    {
+		// non-fatal prototyping
+                try
+		{
+		    installKind(self) { debug:true }
+		}
+		catch (Exception err)
+		{
+		    println("** ${iam}: EXCEPTION ${err}")
+		    throw err
+		}
+		finally
+		{
+		    println("** ${iam}: LEAVE")
+		}
+
+		def clusterExists = sh returnStdout: true, script: """
           kind get clusters | grep ${clusterName} | wc -l
           """
-          if (clusterExists.trim() == "0") {
-            createKubernetesCluster([nodes: 3, name: clusterName])
-          }
+		if (clusterExists.trim() == "0")
+                {
+		    createKubernetesCluster([nodes: 3, name: clusterName])
+		}
+            }
         }
-      }
     }
+	
     stage('Replace voltctl') {
       // if the project is voltctl override the downloaded one with the built one
       when {
@@ -357,3 +378,5 @@
     }
   }
 }
+
+// EOF
diff --git a/vars/installKind.groovy b/vars/installKind.groovy
new file mode 100644
index 0000000..28d4f58
--- /dev/null
+++ b/vars/installKind.groovy
@@ -0,0 +1,97 @@
+#!/usr/bin/env groovy
+// -----------------------------------------------------------------------
+// Copyright 2023 Open Networking Foundation (ONF) and the ONF Contributors
+//
+// 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.
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+def getIam(String func)
+{
+    // Cannot rely on a stack trace due to jenkins manipulation
+    String src = 'vars/installKind.groovy'
+    String iam = [src, func].join('::')
+    return iam
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+def process(Map args) {
+
+    String iam = getIam('process')
+    println("** ${iam}: ENTER")
+
+    // go install sigs.k8s.io/kind@v0.18.0
+    sh(
+        returnStdout: true,
+        script: """#!/bin/bash
+
+set -eu -o pipefail
+umask 0
+
+function error()
+{
+    echo "** ${FUNCNAME[1]} ERROR: $*"
+    exit 1
+}
+
+dir="$WORKSPACE/bin"
+if [ ! -f "$dir/kind" ]; then
+    mkdir -p "$dir"
+    pushd "$dir" || error "pushd $dir failed"
+    curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.0/kind-linux-amd64
+    chmod +x ./kind
+    popd         || error "popd $dir failed"
+fi
+
+return
+""")
+
+    println("** ${iam}: LEAVE")
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+Boolean call\
+    (
+    def self,  // jenkins env object for access to primitives like echo()
+    Closure body, // jenkins closure attached to the call iam() {closure}
+    )
+{
+    Map config           = [:]    // propogate block parameters
+    body.resolveStrategy = Closure.DELEGATE_FIRST
+    body.delegate        = config // make parameters visible down below
+    body()
+
+    String iam = getIam('main')
+    println("** ${iam}: ENTER")
+    println("** ${iam}: Debug= is " + config.contains(debug))
+
+    try
+    {
+        process(config)
+    }
+    catch (Exception err)
+    {
+        println("** ${iam}: EXCEPTION ${err}")
+        throw err
+    }
+    finally
+    {
+        println("** ${iam}: LEAVE")
+    }
+    return
+}
+
+// [EOF]