Merge "VOL-4836 - use newer version of voltctl."
diff --git a/.gitignore b/.gitignore
index f07503c..0506491 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,9 @@
 venv-jjb
 job-configs
 
+# npm-groovy-lint
+node_modules/
+package-lock.json
+package.json
+
+# [EOF]
diff --git a/jjb/bbr.yaml b/jjb/bbr.yaml
index 14b4caa..5d756bc 100644
--- a/jjb/bbr.yaml
+++ b/jjb/bbr.yaml
@@ -22,7 +22,7 @@
                   Interval scale tests for BBSim using BBR <br />
                   Created from job-template bbsim_scale_test from ci-management/jjb/bbr.yaml <br />
                   Created by Matteo Scandolo, teo@opennetworking.org <br />
-                  Copyright (c) 2017 Open Networking Foundation (ONF)
+                  Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     project-type: pipeline
     sandbox: true
diff --git a/jjb/cord-test/nightly-build-pipeline.yaml b/jjb/cord-test/nightly-build-pipeline.yaml
index 7ff3007..4f20609 100644
--- a/jjb/cord-test/nightly-build-pipeline.yaml
+++ b/jjb/cord-test/nightly-build-pipeline.yaml
@@ -21,7 +21,7 @@
                   Manual Build on POD {config-pod} using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by QA (Suchitra Vemuri - suchitra@opennetworking.org ) <br />
-                  Copyright (c) 2018 Open Networking Foundation (ONF)
+                  Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     openoltAdapterChart: onf/voltha-adapter-openolt
 
@@ -172,8 +172,7 @@
     description: |
                   Nightly Kubernetes tests on {config-pod} using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml<br />
-                  Created by Suchitra Vemuri, suchitra@opennetworking.org <br />
-                  Copyright (c) 2017 Open Networking Foundation (ONF)
+                  Created by Suchitra Vemuri, suchitra@opennetworking.org <br />                  Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
     disabled: '{disable-job}'
 
     <<: *test-pipe-job-boiler-plate
@@ -302,8 +301,7 @@
     description: |
                   Post Tests on {config-pod} triggered by build_{config-pod}_{branch}, using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
-                  Created by Kailash Khalasi - kailash@opennetworking.org <br />
-                  Copyright (c) 2017 Open Networking Foundation (ONF)
+                  Created by Kailash Khalasi - kailash@opennetworking.org <br />                  Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
@@ -374,7 +372,7 @@
                   Manual Build on POD {config-pod}, using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by QA (Suchitra Vemuri - suchitra@opennetworking.org ) <br />
-                  Copyright (c) 2018 Open Networking Foundation (ONF)
+                  Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
@@ -465,7 +463,7 @@
                   Manual Build on POD {config-pod}, using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by QA (Suchitra Vemuri - suchitra@opennetworking.org ) <br />
-                  Copyright (c) 2018 Open Networking Foundation (ONF)
+                  Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
@@ -566,7 +564,7 @@
                   Post Tests on {config-pod} triggered by build_{config-pod}_{branch}, using {Jenkinsfile} <br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by Kailash Khalasi - kailash@opennetworking.org <br />
-                  Copyright (c) 2017 Open Networking Foundation (ONF)
+                  Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
@@ -638,7 +636,7 @@
                   Post Tests on {config-pod} triggered by build_{config-pod}_{branch}, using {Jenkinsfile}<br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by Kailash Khalasi - kailash@opennetworking.org <br />
-                  Copyright (c) 2017 Open Networking Foundation (ONF)
+                  Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
@@ -710,7 +708,7 @@
                   Manual Build on POD {config-pod}, using {Jenkinsfile} <br /><br />
                   Created from job-template {id} from ci-management/jjb/cord-test/nightly-build-pipeline.yaml <br />
                   Created by QA (Kailash Khalasi - kailash@opennetworking.org ) <br />
-                  Copyright (c) 2019 Open Networking Foundation (ONF)
+                  Copyright 2019-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     <<: *test-pipe-job-boiler-plate
 
diff --git a/jjb/fossa.yaml b/jjb/fossa.yaml
index acfa347..5deeba0 100644
--- a/jjb/fossa.yaml
+++ b/jjb/fossa.yaml
@@ -20,7 +20,7 @@
     description: |
                   Post-merge check of code with fossa toolset
                   Created by {id} job-template from ci-management/jjb/fossa.yaml<br/>
-                  Copyright (c) 2018-present Open Networking Foundation (ONF)
+                  Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
 
     properties:
       - cord-infra-properties:
diff --git a/jjb/pipeline/docker-publish.groovy b/jjb/pipeline/docker-publish.groovy
index 316d429..9e3f9f9 100644
--- a/jjb/pipeline/docker-publish.groovy
+++ b/jjb/pipeline/docker-publish.groovy
@@ -1,4 +1,4 @@
-// Copyright 2017-present Open Networking Foundation
+// Copyright 2017-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.
diff --git a/jjb/pipeline/omec-postmerge.groovy b/jjb/pipeline/omec-postmerge.groovy
index 06e2be2..2abcf49 100644
--- a/jjb/pipeline/omec-postmerge.groovy
+++ b/jjb/pipeline/omec-postmerge.groovy
@@ -1,4 +1,4 @@
-// Copyright 2020-present Open Networking Foundation
+// Copyright 2020-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.
diff --git a/jjb/pipeline/onos-app-release.groovy b/jjb/pipeline/onos-app-release.groovy
index dc022e1..4cd3011 100644
--- a/jjb/pipeline/onos-app-release.groovy
+++ b/jjb/pipeline/onos-app-release.groovy
@@ -1,4 +1,4 @@
-// Copyright 2019-present Open Networking Foundation
+// Copyright 2019-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.
diff --git a/jjb/pipeline/xos-core.groovy b/jjb/pipeline/xos-core.groovy
index e3f398b..8962545 100644
--- a/jjb/pipeline/xos-core.groovy
+++ b/jjb/pipeline/xos-core.groovy
@@ -1,4 +1,4 @@
-// Copyright 2017-present Open Networking Foundation
+// Copyright 2017-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.
diff --git a/jjb/shell/github-release.sh b/jjb/shell/github-release.sh
index 80b346f..47e6ce8 100644
--- a/jjb/shell/github-release.sh
+++ b/jjb/shell/github-release.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-# Copyright 2018-present Open Networking Foundation
+# Copyright 2018-2022 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.
@@ -19,6 +19,41 @@
 # given a tag also create checksums files and release notes from the commit
 # message
 
+## -----------------------------------------------------------------------
+## Intent:
+##   Display available commands and paths for golang.
+##   A github release job is failing due to a command being mia.
+##
+## Note: This function is being used for side effects, when commands
+## are unavailable to query for version info, fail the job.
+## -----------------------------------------------------------------------
+## 05:02:50 bash: go: command not found
+## 05:03:00 Unable to find image 'voltha/voltha-ci-tools:2.4.0-golang' locally
+## -----------------------------------------------------------------------
+function displayCommands()
+{
+    echo
+    echo "Installed /usr/lib/go"
+    echo "-----------------------------------------------------------------------"
+    find /usr/lib -mindepth 1 -maxdepth 1 -name 'go-*' -print || /bin/true
+
+    echo
+    echo "Go commands in \$PATH"
+    echo "-----------------------------------------------------------------------"
+    which -a go || /bin/true
+
+    echo
+    echo "VERSIONS:"
+    echo "-----------------------------------------------------------------------"
+    git --version
+    go version
+
+    return
+}
+
+##----------------##
+##---]  MAIN  [---##
+##----------------##
 set -eu -o pipefail
 
 # when not running under Jenkins, use current dir as workspace and a blank
@@ -60,6 +95,8 @@
 export GOPATH=${GOPATH:-$WORKSPACE/go}
 export PATH=$PATH:/usr/lib/go-1.12/bin:/usr/local/go/bin:$GOPATH/bin
 
+displayCommands
+
 # To support golang projects that require GOPATH to be set and code checked out there
 # If $DEST_GOPATH is not an empty string:
 # - create GOPATH within WORKSPACE, and destination directory within
@@ -80,18 +117,20 @@
   echo "Makefile not found at $release_path!"
   exit 1
 else
+
   pushd "$release_path"
+  set -x
 
   # Release description is sanitized version of the log message
-  RELEASE_DESCRIPTION=$(git log -1 --pretty=%B | tr -dc "[:alnum:]\n\r\.\[\]\:\-\\\/\`\' ")
+  RELEASE_DESCRIPTION="$(git log -1 --pretty=%B | tr -dc "[:alnum:]\n\r\.\[\]\:\-\\\/\`\' ")"
 
   # build the release, can be multiple space separated targets
   # shellcheck disable=SC2086
-  make $RELEASE_TARGETS
+  make "$RELEASE_TARGETS"
 
   # Copy artifacts into the release temp dir
   # shellcheck disable=SC2086
-  cp $ARTIFACT_GLOB "$RELEASE_TEMP"
+  cp "$ARTIFACT_GLOB" "$RELEASE_TEMP"
 
   # create release
   echo "Creating Release: $GERRIT_PROJECT - $GIT_VERSION"
@@ -123,6 +162,7 @@
         --name "$rel_file" \
         --file "$rel_file"
     done
+    set +x
   popd
 
   popd
diff --git a/jjb/shell/make-unit.sh b/jjb/shell/make-unit.sh
index a6920e3..c28a59e 100755
--- a/jjb/shell/make-unit.sh
+++ b/jjb/shell/make-unit.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-# Copyright 2019-present Open Networking Foundation
+# Copyright 2019-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.
diff --git a/jjb/shell/shcheck.sh b/jjb/shell/shcheck.sh
index 2abe89c..48ffc7d 100755
--- a/jjb/shell/shcheck.sh
+++ b/jjb/shell/shcheck.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-# Copyright 2017-present Open Networking Foundation
+# Copyright 2017-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.
diff --git a/jjb/voltha-e2e.yaml b/jjb/voltha-e2e.yaml
index 8d343aa..f16969a 100755
--- a/jjb/voltha-e2e.yaml
+++ b/jjb/voltha-e2e.yaml
@@ -329,7 +329,17 @@
               flags: "--set kafka.externalAccess.enabled=true,kafka.externalAccess.service.type=NodePort,kafka.externalAccess.service.nodePorts[0]=30201,kafka.externalAccess.service.domain=127.0.0.1,voltha-adapter-openonu.global.mib_audit.interval=60s"
               teardown: true
               logging: true
-          timeout: 210
+            - target: onu-robustness-test-single-kind-dt
+              workflow: dt
+              flags: "--set kafka.externalAccess.enabled=true,kafka.externalAccess.service.type=NodePort,kafka.externalAccess.service.nodePorts[0]=30201,kafka.externalAccess.service.domain=127.0.0.1"
+              teardown: true
+              logging: true
+            - target: onu-robustness-test-multi-uni-kind-tt
+              workflow: tt
+              flags: "--set voltha-adapter-openonu.adapter_open_onu.uni_port_mask=0x00FF,kafka.externalAccess.enabled=true,kafka.externalAccess.service.type=NodePort,kafka.externalAccess.service.nodePorts[0]=30201,kafka.externalAccess.service.domain=127.0.0.1"
+              teardown: true
+              logging: true
+          timeout: 240
 
       - 'voltha-periodic-test':
           name: 'periodic-voltha-openonu-go-test-bbsim-2.8'
@@ -1979,7 +1989,7 @@
                   Automated build on POD {config-pod} using {pipeline-script} <br /><br />
                   Created from job-template {id} from ci-management/jjb/voltha-e2e.yaml <br />
                   Created by Andy Bavier, andy@opennetworking.org <br />
-                  Copyright (c) 2019 Open Networking Foundation (ONF)
+                  Copyright 2019-2023 Open Networking Foundation (ONF) and the ONF Contributors
     sandbox: true
     pipeline-script: 'voltha/master/tucson-build-and-test.groovy'
     default-test-args: '-i sanityORDeleteOLT -i PowerSwitch -X'
@@ -2032,7 +2042,7 @@
                   Automated build on POD {config-pod} using {pipeline-script} <br /><br />
                   Created from job-template {id} from ci-management/jjb/voltha-e2e.yaml <br />
                   Created by Andy Bavier, andy@opennetworking.org <br />
-                  Copyright (c) 2019 Open Networking Foundation (ONF)
+                  Copyright 2019-2023 Open Networking Foundation (ONF) and the ONF Contributors
     sandbox: true
     build-node: 'tucson-pod'
     config-pod: 'tucson-pod'
diff --git a/vars/getVolthaCode.groovy b/vars/getVolthaCode.groovy
index d763429..5277350 100644
--- a/vars/getVolthaCode.groovy
+++ b/vars/getVolthaCode.groovy
@@ -1,109 +1,178 @@
+#!/usr/bin/env groovy
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+def getIam(String func)
+{
+    String src = 'vars/getVolthaCode.groovy'
+    String iam = [src, func].join('::')
+    return iam
+}
+
 // TODO the 3 stages are very similar, most of the code can be shared
 
-def call(Map config) {
+def wrapped(Map config)
+{
+    def defaultConfig = [
+	branch: "master",
+	gerritProject: "",
+	gerritRefspec: "",
+	volthaSystemTestsChange: "",
+	volthaHelmChartsChange: "",
+    ]
+    
+    def cfg = defaultConfig + config
 
-  def defaultConfig = [
-    branch: "master",
-    gerritProject: "",
-    gerritRefspec: "",
-    volthaSystemTestsChange: "",
-    volthaHelmChartsChange: "",
-  ]
+    println "Downloading VOLTHA code with the following parameters: ${cfg}."
 
-  if (!config) {
-      config = [:]
-  }
+    stage('Download Patch')
+    {
+	frequent_repos = [
+	    '',
+	    'voltha-system-tests',
+	    'voltha-helm-charts',
+	]
 
-  def cfg = defaultConfig + config
+	// We are always downloading those repos, if the patch under test is in one of those
+	// just checkout the patch, no need to clone it again
+	if (cfg.gerritProject == '')
+	{
+	    // Revisit:
+	    // gerritProject should be defined.  Ignore when empty was likely
+	    // added to support manually re-running a job when repo values
+	    // may not be defined.
+	    // Unfortunately the conditional can also inadvertently bypass
+	    // checkout during an error condition.
+	    // Case: when cfg= is invalid due to a jenkins hiccup.
+	}
+	else if (!(cfg.gerritProject in frequent_repos))
+	{
+	    repo_project = "https://gerrit.opencord.org/${cfg.gerritProject}"
+		
+	    checkout([
+		$class: 'GitSCM',
+		userRemoteConfigs: [[ url:repo_project ]],
+		branches: [[ name: "${cfg.branch}", ]],
+		extensions: [
+		    [$class: 'WipeWorkspace'],
+		    [$class: 'RelativeTargetDirectory', relativeTargetDir: "${cfg.gerritProject}"],
+		    [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
+		],
+	    ])
 
-  println "Downloading VOLTHA code with the following parameters: ${cfg}."
-
-  stage('Download Patch') {
-    // We are always downloading those repos, if the patch under test is in one of those
-    // just checkout the patch, no need to clone it again
-    if (cfg.gerritProject != 'voltha-system-tests' &&
-      cfg.gerritProject != 'voltha-helm-charts' &&
-      cfg.gerritProject != '') {
-      checkout([
-        $class: 'GitSCM',
-        userRemoteConfigs: [[
-          url: "https://gerrit.opencord.org/${cfg.gerritProject}",
-        ]],
-        branches: [[ name: "${cfg.branch}", ]],
-        extensions: [
-          [$class: 'WipeWorkspace'],
-          [$class: 'RelativeTargetDirectory', relativeTargetDir: "${cfg.gerritProject}"],
-          [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
-        ],
-      ])
-      sh """
+	    sh """
         pushd $WORKSPACE/${cfg.gerritProject}
+        git fetch "$repo_project" ${cfg.gerritRefspec} && git checkout FETCH_HEAD
+
+        echo "Currently on commit: \n"
+        git log -1 --oneline
+        popd
+      """
+	}
+    }
+
+    stage('Clone voltha-system-tests')
+    {	
+	repo_vst = 'https://gerrit.opencord.org/voltha-system-tests'
+
+	checkout([
+	    $class: 'GitSCM',
+	    userRemoteConfigs: [[ url:repo_vst ]],
+	    branches: [[ name: "${cfg.branch}", ]],
+	    extensions: [
+		[$class: 'WipeWorkspace'],
+		[$class: 'RelativeTargetDirectory', relativeTargetDir: "voltha-system-tests"],
+		[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
+	    ],
+	])
+
+	if (cfg.volthaSystemTestsChange != '' && cfg.gerritProject != 'voltha-system-tests')
+	{
+	    sh """
+        cd "$WORKSPACE/voltha-system-tests"
+        git fetch "${repo_vst}" ${cfg.volthaSystemTestsChange} && git checkout FETCH_HEAD
+      """
+	}
+	else if (cfg.gerritProject == 'voltha-system-tests') {
+	    sh """
+        pushd "$WORKSPACE/${cfg.gerritProject}"
         git fetch https://gerrit.opencord.org/${cfg.gerritProject} ${cfg.gerritRefspec} && git checkout FETCH_HEAD
 
         echo "Currently on commit: \n"
         git log -1 --oneline
         popd
       """
+	}
     }
-  }
-  stage('Clone voltha-system-tests') {
-    checkout([
-      $class: 'GitSCM',
-      userRemoteConfigs: [[
-        url: "https://gerrit.opencord.org/voltha-system-tests",
-      ]],
-      branches: [[ name: "${cfg.branch}", ]],
-      extensions: [
-        [$class: 'WipeWorkspace'],
-        [$class: 'RelativeTargetDirectory', relativeTargetDir: "voltha-system-tests"],
-        [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
-      ],
-    ])
-    if (cfg.volthaSystemTestsChange != '' && cfg.gerritProject != 'voltha-system-tests') {
-      sh """
-        cd $WORKSPACE/voltha-system-tests
-        git fetch https://gerrit.opencord.org/voltha-system-tests ${cfg.volthaSystemTestsChange} && git checkout FETCH_HEAD
+
+    stage('Clone voltha-helm-charts')
+    {
+	repo_vhc = 'https://gerrit.opencord.org/voltha-helm-charts'
+
+	checkout([
+	    $class: 'GitSCM',
+	    userRemoteConfigs: [[ url:repo_vhc ]],
+	    branches: [[ name: "${cfg.branch}", ]],
+	    extensions: [
+		[$class: 'WipeWorkspace'],
+		[$class: 'RelativeTargetDirectory', relativeTargetDir: "voltha-helm-charts"],
+		[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
+	    ],
+	])
+
+	if (cfg.volthaHelmChartsChange != '' && cfg.gerritProject != 'voltha-helm-charts') {
+	    sh """
+        cd "$WORKSPACE/voltha-helm-charts"
+        git fetch "$repo_vhc" ${cfg.volthaHelmChartsChange} && git checkout FETCH_HEAD
       """
-    }
-    else if (cfg.gerritProject == 'voltha-system-tests') {
-      sh """
-        pushd $WORKSPACE/${cfg.gerritProject}
-        git fetch https://gerrit.opencord.org/${cfg.gerritProject} ${cfg.gerritRefspec} && git checkout FETCH_HEAD
+	}
+	else if (cfg.gerritProject == 'voltha-helm-charts') {
+	    sh """
+        pushd "$WORKSPACE/${cfg.gerritProject}"
+        git fetch "https://gerrit.opencord.org/${cfg.gerritProject}" ${cfg.gerritRefspec} && git checkout FETCH_HEAD
 
         echo "Currently on commit: \n"
         git log -1 --oneline
         popd
       """
+	}
     }
-  }
-  stage('Clone voltha-helm-charts') {
-    checkout([
-      $class: 'GitSCM',
-      userRemoteConfigs: [[
-        url: "https://gerrit.opencord.org/voltha-helm-charts",
-      ]],
-      branches: [[ name: "${cfg.branch}", ]],
-      extensions: [
-        [$class: 'WipeWorkspace'],
-        [$class: 'RelativeTargetDirectory', relativeTargetDir: "voltha-helm-charts"],
-        [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
-      ],
-    ])
-    if (cfg.volthaHelmChartsChange != '' && cfg.gerritProject != 'voltha-helm-charts') {
-      sh """
-        cd $WORKSPACE/voltha-helm-charts
-        git fetch https://gerrit.opencord.org/voltha-helm-charts ${cfg.volthaHelmChartsChange} && git checkout FETCH_HEAD
-      """
-    }
-    else if (cfg.gerritProject == 'voltha-helm-charts') {
-      sh """
-        pushd $WORKSPACE/${cfg.gerritProject}
-        git fetch https://gerrit.opencord.org/${cfg.gerritProject} ${cfg.gerritRefspec} && git checkout FETCH_HEAD
+}
 
-        echo "Currently on commit: \n"
-        git log -1 --oneline
-        popd
-      """
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+def call(Map config)
+{
+    String iam = getIam('main')
+    Boolean debug = false
+
+    if (debug)
+    {
+	println("** ${iam}: ENTER")
     }
-  }
+
+    if (!config) {
+        config = [:]
+    }
+
+    try
+    {
+	wrapped(config)
+    }
+    catch (Exception err)
+    {
+	println("** ${iam}: EXCEPTION ${err}")
+	throw err
+    }
+    finally
+    {
+	if (debug)
+	{
+	    println("** ${iam}: LEAVE")
+	}
+    }
+
+    return
 }