Merge changes I605355bd,I981e72a5

* changes:
  Refactor salt-models testing
  Add pipeline to build jmx-exporter
diff --git a/build-debian-packages-jmx-exporter.groovy b/build-debian-packages-jmx-exporter.groovy
new file mode 100644
index 0000000..f996635
--- /dev/null
+++ b/build-debian-packages-jmx-exporter.groovy
@@ -0,0 +1,79 @@
+def common = new com.mirantis.mk.Common()
+def git = new com.mirantis.mk.Git()
+def aptly = new com.mirantis.mk.Aptly()
+
+def timestamp = common.getDatetime()
+
+node('docker') {
+    try{
+
+        stage("cleanup") {
+            sh("rm -rf * || true")
+        }
+
+        stage("checkout") {
+            git.checkoutGitRepository(
+                "jmx-exporter-${timestamp}",
+                "${SOURCE_URL}",
+                SOURCE_BRANCH,
+                SOURCE_CREDENTIALS,
+                true,
+                30,
+                1
+            )
+        }
+
+        try {
+            def img = docker.img("tcpcloud/debian-build-ubuntu-xenial")
+
+            img.inside {
+                stage("Build") {
+                    sh("sed -i \"s/TIMESTAMP/${timestamp}/g\" \$(find -name pom.xml)")
+                    sh("sudo apt-get update && sudo apt-get install -y openjdk-8-jdk maven")
+                    sh("cd jmx-exporter-${timestamp} && mvn package")
+                }
+            }
+
+            if (UPLOAD_APTLY.toBoolean()) {
+                stage("upload package") {
+                    def buildSteps = [:]
+                    def debFiles = sh script: "find -name *.deb", returnStdout: true
+                    def debFilesArray = debFiles.trim().tokenize()
+                    def workspace = common.getWorkspace()
+                    for (int i = 0; i < debFilesArray.size(); i++) {
+                        def debFile = debFilesArray[i];
+                        buildSteps[debFiles[i]] = aptly.uploadPackageStep(
+                            "${workspace}/"+debFile,
+                            APTLY_URL,
+                            APTLY_REPO,
+                            true
+                        )
+                    }
+                    parallel buildSteps
+                }
+
+                stage("publish") {
+                    aptly.snapshotRepo(APTLY_URL, APTLY_REPO, timestamp)
+                    aptly.publish(APTLY_URL)
+                }
+            }
+
+        } catch (Exception e) {
+            currentBuild.result = 'FAILURE'
+            println "Cleaning up docker images"
+            sh("docker images | grep -E '[-:\\ ]+${timestamp}[\\.\\ /\$]+' | awk '{print \$3}' | xargs docker rmi -f || true")
+            throw e
+        }
+
+    } catch (Throwable e) {
+       // If there was an exception thrown, the build failed
+       currentBuild.result = "FAILURE"
+       throw e
+    } finally {
+       common.sendNotification(currentBuild.result,"",["slack"])
+
+       if (currentBuild.result != 'FAILURE') {
+          sh("rm -rf *")
+       }
+    }
+}
diff --git a/test-salt-model-node.groovy b/test-salt-model-node.groovy
new file mode 100644
index 0000000..8ec3936
--- /dev/null
+++ b/test-salt-model-node.groovy
@@ -0,0 +1,62 @@
+
+/**
+ *  Test salt models pipeline
+ *  DEFAULT_GIT_REF
+ *  DEFAULT_GIT_URL
+ *  CREDENTIALS_ID
+ *  EXTRA_FORMULAS
+ *  NODE_TARGET
+ *  SYSTEM_GIT_URL
+ *  SYSTEM_GIT_REF
+ */
+
+def common = new com.mirantis.mk.Common()
+def gerrit = new com.mirantis.mk.Gerrit()
+def saltModelTesting = new com.mirantis.mk.SaltModelTesting()
+
+def defaultGitRef = DEFAULT_GIT_REF
+def defaultGitUrl = DEFAULT_GIT_URL
+
+def checkouted = false
+node("python") {
+  try{
+    stage("checkout") {
+      if(defaultGitRef != "" && defaultGitUrl != "") {
+          checkouted = gerrit.gerritPatchsetCheckout(defaultGitUrl, defaultGitRef, "HEAD", CREDENTIALS_ID)
+      } else {
+        throw new Exception("Cannot checkout gerrit patchset, DEFAULT_GIT_URL or DEFAULT_GIT_REF is null")
+      }
+      if(checkouted) {
+        if (fileExists('classes/system')) {
+          if (SYSTEM_GIT_URL == "") {
+            ssh.prepareSshAgentKey(CREDENTIALS_ID)
+            dir('classes/system') {
+              remoteUrl = git.getGitRemote()
+              ssh.ensureKnownHosts(remoteUrl)
+            }
+            ssh.agentSh("git submodule init; git submodule sync; git submodule update --recursive")
+          } else {
+            dir('classes/system') {
+              if (!gerrit.gerritPatchsetCheckout(SYSTEM_GIT_URL, SYSTEM_GIT_REF, "HEAD", CREDENTIALS_ID)) {
+                common.errorMsg("Failed to obtain system reclass with url: ${SYSTEM_GIT_URL} and ${SYSTEM_GIT_REF}")
+              }
+            }
+          }
+        }
+      }
+    }
+
+    stage("test node") {
+      if (checkouted) {
+        def workspace = common.getWorkspace()
+        saltModelTesting.setupAndTestNode(NODE_TARGET, EXTRA_FORMULAS, workspace)
+      }
+    }
+  } catch (Throwable e) {
+     // If there was an error or exception thrown, the build failed
+     currentBuild.result = "FAILURE"
+     throw e
+  } finally {
+     common.sendNotification(currentBuild.result,"",["slack"])
+  }
+}
diff --git a/test-salt-models-pipeline.groovy b/test-salt-models-pipeline.groovy
index de6a612..317cadd 100644
--- a/test-salt-models-pipeline.groovy
+++ b/test-salt-models-pipeline.groovy
@@ -5,13 +5,14 @@
  *  DEFAULT_GIT_URL
  *  CREDENTIALS_ID
  *  EXTRA_FORMULAS
+ *  SYSTEM_GIT_URL
+ *  SYSTEM_GIT_REF
  */
 
 def common = new com.mirantis.mk.Common()
 def gerrit = new com.mirantis.mk.Gerrit()
 def ssh = new com.mirantis.mk.Ssh()
 def git = new com.mirantis.mk.Git()
-def saltModelTesting = new com.mirantis.mk.SaltModelTesting()
 
 def gerritRef
 try {
@@ -61,43 +62,38 @@
             common.successMsg("Change ${GERRIT_CHANGE_NUMBER} is already merged, no need to test them")
           }
         }
+        // defaultGitUrl is passed to the triggered job
+        defaultGitUrl = "${GERRIT_SCHEME}://${GERRIT_NAME}@${GERRIT_HOST}:${GERRIT_PORT}/${GERRIT_PROJECT}"
+        defaultGitRef = GERRIT_REFSPEC
       } else if(defaultGitRef && defaultGitUrl) {
           checkouted = gerrit.gerritPatchsetCheckout(defaultGitUrl, defaultGitRef, "HEAD", CREDENTIALS_ID)
       } else {
         throw new Exception("Cannot checkout gerrit patchset, GERRIT_REFSPEC and DEFAULT_GIT_REF is null")
       }
-      if(checkouted) {
-        if (fileExists('classes/system')) {
-          ssh.prepareSshAgentKey(CREDENTIALS_ID)
-          dir('classes/system') {
-            remoteUrl = git.getGitRemote()
-            ssh.ensureKnownHosts(remoteUrl)
-          }
-          ssh.agentSh("git submodule init; git submodule sync; git submodule update --recursive")
-        }
-      }
     }
 
     stage("test-nodes") {
       if(checkouted) {
-        def workspace = common.getWorkspace()
         def nodes = sh(script: "find ./nodes -type f -name 'cfg*.yml'", returnStdout: true).tokenize()
-        def buildSteps = [:]
-        def partitionSize = (nodes.size() <= PARALLEL_NODE_GROUP_SIZE.toInteger()) ? nodes.size() : PARALLEL_NODE_GROUP_SIZE.toInteger()
-        def partitions = common.partitionList(nodes, partitionSize)
-        for (int i =0; i < partitions.size();i++) {
-          def partition = partitions[i]
-          buildSteps.put("partition-${i}", new HashMap<String,org.jenkinsci.plugins.workflow.cps.CpsClosure2>())
-          for(int k=0; k < partition.size;k++){
-              def basename = sh(script: "basename ${partition[k]} .yml", returnStdout: true).trim()
-              buildSteps.get("partition-${i}").put(basename, { saltModelTesting.setupAndTestNode(basename, EXTRA_FORMULAS, workspace) })
-          }
+        def branches = [:]
+        for (int i = 0; i < nodes.size(); i++) {
+
+          def testTarget = sh(scipt: "basename ${nodes[i]}.yml", returnStdout: true).trim()
+          branches[${testTarget}] = {
+            build job: "test-salt-model-node", parameters: [
+              [$class: 'StringParameterValue', name: 'DEFAULT_GIT_URL', value: defaultGitUrl],
+              [$class: 'StringParameterValue', name: 'DEFAULT_GIT_REF', value: defaultGitRef],
+              [$class: 'StringParameterValue', name: 'NODE_TARGET', value: testTarget],
+              [$class: 'StringParameterValue', name: 'EXTRA_FORMULAS', value: EXTRA_FORMULAS],
+              [$class: 'StringParameterValue', name: 'CREDENTIALS_ID', value: CREDENTIALS_ID],
+              [$class: 'StringParameterValue', name: 'SYSTEM_GIT_URL', value: SYSTEM_GIT_URL],
+              [$class: 'StringParameterValue', name: 'SYSTEM_GIT_REF', value: SYSTEM_GIT_REF]
+            ]}
+          parallel branches
         }
-        common.serial(buildSteps)
       }
     }
   } catch (Throwable e) {
-     // If there was an error or exception thrown, the build failed
      currentBuild.result = "FAILURE"
      throw e
   } finally {
diff --git a/test-system-reclass-pipeline.groovy b/test-system-reclass-pipeline.groovy
index 27106fe..a334020 100644
--- a/test-system-reclass-pipeline.groovy
+++ b/test-system-reclass-pipeline.groovy
@@ -25,6 +25,7 @@
 }
 def checkouted = false
 def merged = false
+def systemRefspec = "HEAD"
 try {
   stage("Checkout") {
     node() {
@@ -37,6 +38,7 @@
           checkouted = gerrit.gerritPatchsetCheckout ([
             credentialsId : gerritCredentials
           ])
+          systemRefspec = GERRIT_REFSPEC
         }
         // change defaultGit variables if job triggered from Gerrit
         defaultGitUrl = "${GERRIT_SCHEME}://${GERRIT_NAME}@${GERRIT_HOST}:${GERRIT_PORT}/${GERRIT_PROJECT}"
@@ -60,6 +62,8 @@
               build job: "test-salt-model-${cluster}", parameters: [
                 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_URL', value: clusterGitUrl],
                 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_REF', value: "HEAD"]
+                [$class: 'StringParameterValue', name: 'SYSTEM_GIT_URL', value: defaultGitUrl],
+                [$class: 'StringParameterValue', name: 'SYSTEM_GIT_REF', value: systemRefspec]
               ]
             }
           }