Skip service upgrade test if the xos-core version requirements don't match

This is a first attempt at making the service upgrade job aware of the
xos-core version, and to allow merging service patches that require
xos-core 4.0.0.

The current implementation verifies that the `core_version` string found
in the released service's config.yaml is the same found in the patchset
to verify. If not, return SUCCESS immediately.

For example, given a released and patchset config.yaml's core_version
property:
- if RELEASED == ">=3.2.0" && PATCHSET == ">=3.2.0" -> RUN
- if RELEASED == ">=3.2.0" && PATCHSET == ">=4.0.0" -> SKIP (success)
- if RELEASED == ">=3.2.0" && PATCHSET == "=3.2.0"  -> SKIP (success)
- if RELEASED == ">=3.2.0" && PATCHSET == ">=3.2"   -> SKIP (success)
- if RELEASED == ">=3.2.0" && PATCHSET == "foobar"  -> SKIP (success)

A smarter implementation could parse the string and use semver logic to
decide (1) whether it exists a version of xos-core that satisfies both
the released and patchset requirement, (2) deploy that version of
xos-core, and (3) run the pipeline. However, such and implementation
smells of canned worms, so we keep things simple for now...

Change-Id: I2cc1be579398c84d4e8c44c333be20e012884e20
diff --git a/jjb/pipeline/xos-service-upgrade.groovy b/jjb/pipeline/xos-service-upgrade.groovy
index 35075b0..12fb69b 100644
--- a/jjb/pipeline/xos-service-upgrade.groovy
+++ b/jjb/pipeline/xos-service-upgrade.groovy
@@ -16,6 +16,7 @@
 // Checks functionality of the helm-chart, without overriding the version/tag used
 
 def serviceName = "${gerritProject}"
+def xosCoreVersionMismatch = false
 
 pipeline {
 
@@ -44,17 +45,6 @@
       }
     }
 
-    stage('patch') {
-      steps {
-        sh '''
-           pushd cord
-           PROJECT_PATH=\$(xmllint --xpath "string(//project[@name=\\\"${gerritProject}\\\"]/@path)" .repo/manifests/default.xml)
-           repo download "\$PROJECT_PATH" "${gerritChangeNumber}/${gerritPatchsetNumber}"
-           popd
-           '''
-      }
-    }
-
     stage('minikube') {
       steps {
         /* see https://github.com/kubernetes/minikube/#linux-continuous-integration-without-vm-support */
@@ -91,9 +81,86 @@
       }
     }
 
+    stage('Verify xos-core version requirements') {
+      steps {
+        script {
+          if (serviceName == "olt-service") {
+            serviceName = "volt"
+          }
+          else if (serviceName == "onos-service") {
+            serviceName = "onos"
+          }
+          else if (serviceName == "kubernetes-service") {
+            serviceName = "kubernetes"
+          }
+        }
+        result = sh returnStdout: true, script: """
+           #!/usr/bin/env bash
+           set -eu -o pipefail
+
+           # Obtain git tag of the service corresponding to the the docker image
+           # used in the latest released version of the helm chart (i.e., HEAD
+           # of cord/helm-charts master branch, which should be already checked
+           # out by repo).
+           pushd cord/helm-charts
+           export RELEASED_GIT_TAG=\$(echo -e "import yaml\\nwith open('xos-services/${serviceName}/Chart.yaml', 'r') as f: print yaml.safe_load(f)['appVersion']" | python)
+           popd
+
+           # Obtain the xos-core version requirement from the config.yaml of the
+           # released service.
+           pushd cord
+           PROJECT_PATH=\$(xmllint --xpath "string(//project[@name=\\\"${gerritProject}\\\"]/@path)" .repo/manifest.xml)
+           pushd \${PROJECT_PATH}
+           git fetch --all --tags
+           git checkout tags/\${RELEASED_GIT_TAG} -b foobar
+           export RELEASED_CORE_VER_REQ=\$(echo -e "import yaml\\nwith open('xos/synchronizer/config.yaml', 'r') as f: yaml.safe_load(f)['core_version']" | python)
+           popd
+           popd
+
+           # Do the same for the patchset we want to verify.
+           pushd cord
+           repo download "\$PROJECT_PATH" "${gerritChangeNumber}/${gerritPatchsetNumber}"
+           pushd \${PROJECT_PATH}
+           export PATCHSET_CORE_VER_REQ=\$(echo -e "import yaml\\nwith open('xos/synchronizer/config.yaml', 'r') as f: yaml.safe_load(f)['core_version']" | python)
+           popd
+           popd
+
+           echo "RELEASED_CORE_VER_REQ: \${RELEASED_CORE_VER_REQ}"
+           echo "PATCHSET_CORE_VER_REQ: \${PATCHSET_CORE_VER_REQ}"
+
+           if [ "\${PATCHSET_CORE_VER_REQ}" == "\${RELEASED_CORE_VER_REQ}" ]; then
+             echo 0
+           else
+             # xosCoreVersionMismatch is true
+             echo 1
+           fi
+           """
+        xosCoreVersionMismatch = result.toBoolean()
+      }
+    }
+
+    if( xosCoreVersionMismatch ) {
+      echo "Detected xos-core version requirements mismatch. Will skip the rest of the pipeline and return SUCCESS"
+      currentBuild.result = 'SUCCESS'
+      return
+    }
+
+    // The patchset should be already checked out, but for consistency with
+    // other pipeline jobs, we re-do the same here.
+    stage('patch') {
+      steps {
+        sh '''
+           pushd cord
+           PROJECT_PATH=\$(xmllint --xpath "string(//project[@name=\\\"${gerritProject}\\\"]/@path)" .repo/manifest.xml)
+           repo download "\$PROJECT_PATH" "${gerritChangeNumber}/${gerritPatchsetNumber}"
+           popd
+           '''
+      }
+    }
+
     stage('Install XOS w/Service') {
       steps {
-          script {
+        script {
           if (serviceName == "olt-service") {
             serviceName = "volt"
           }