Merge "Pass FORMULA_PKG_REVISION to heat env"
diff --git a/build-debian-packages-pipeline.groovy b/build-debian-packages-pipeline.groovy
index 9e40944..0d9839f 100644
--- a/build-debian-packages-pipeline.groovy
+++ b/build-debian-packages-pipeline.groovy
@@ -28,6 +28,13 @@
   uploadPpa = null
 }
 
+def lintianCheck
+try {
+  lintianCheck = LINTIAN_CHECK.toBoolean()
+} catch (MissingPropertyException e) {
+  lintianCheck = true
+}
+
 def uploadAptly
 try {
   uploadAptly = UPLOAD_APTLY.toBoolean()
@@ -73,13 +80,16 @@
       )
       archiveArtifacts artifacts: "build-area/*.deb"
     }
-    stage("lintian") {
-      changes = sh script: "ls build-area/*_"+ARCH+".changes", returnStdout: true
-      try {
-        debian.runLintian(changes.trim(), OS, OS+":"+DIST)
-      } catch (Exception e) {
-        println "[WARN] Lintian returned non-zero exit status"
-        currentBuild.result = 'UNSTABLE'
+
+    if (lintianCheck) {
+      stage("lintian") {
+        changes = sh script: "ls build-area/*_"+ARCH+".changes", returnStdout: true
+        try {
+          debian.runLintian(changes.trim(), OS, OS+":"+DIST)
+        } catch (Exception e) {
+          println "[WARN] Lintian returned non-zero exit status"
+          currentBuild.result = 'UNSTABLE'
+        }
       }
     }
 
diff --git a/change-config.groovy b/change-config.groovy
index 44832ed..16cd629 100644
--- a/change-config.groovy
+++ b/change-config.groovy
@@ -9,6 +9,7 @@
  *   TARGET_SUBSET_TEST         Number of nodes to test config changes, empty string means all targetted nodes.
  *   TARGET_SUBSET_LIVE         Number of selected noded to live apply selected config changes.
  *   TARGET_BATCH_LIVE          Batch size for the complete live config changes on all nodes, empty string means apply to all targetted nodes.
+ *   PULL_MODEL                 Pull the latest cluster model using reclass.storage.data state
  *
 **/
 
@@ -37,6 +38,14 @@
             saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
         }
 
+        if (common.validInputParam("PULL_MODEL") && PULL_MODEL.toBoolean() == true) {
+            stage('Update the reclass cluster model') {
+                def saltMasterTarget = ['expression': 'I@salt:master', 'type': 'compound']
+                result = salt.runSaltCommand(saltMaster, 'local', saltMasterTarget, 'state.apply', null, "reclass.storage.data")
+                salt.checkResult(result)
+            }
+        }
+
         stage('List target servers') {
             minions = salt.getMinions(saltMaster, TARGET_SERVERS)
             if (minions.isEmpty()) {
diff --git a/cicd-lab-pipeline.groovy b/cicd-lab-pipeline.groovy
index 8902e1f..782a051 100644
--- a/cicd-lab-pipeline.groovy
+++ b/cicd-lab-pipeline.groovy
@@ -225,7 +225,7 @@
             // Postgres client - initialize OSS services databases
             timeout(300){
                 println "Waiting for postgresql database to come up.."
-                salt.cmdRun(saltMaster, 'I@postgresql:client', 'while true; do if docker service logs postgresql_db | grep "ready to accept"; then break; else sleep 5; fi; done')
+                salt.cmdRun(saltMaster, 'I@postgresql:client', 'while true; do if docker service logs postgresql_postgresql-db | grep "ready to accept"; then break; else sleep 5; fi; done')
             }
             // XXX: first run usually fails on some inserts, but we need to create databases at first 
             salt.enforceState(saltMaster, 'I@postgresql:client', 'postgresql.client', true, false)
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index de14930..4195d13 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -112,6 +112,7 @@
 
                 // no underscore in STACK_NAME
                 STACK_NAME = STACK_NAME.replaceAll('_', '-')
+                outputs.put('stack_name', STACK_NAME)
 
                 // set description
                 currentBuild.description = "${STACK_NAME}"
@@ -133,7 +134,7 @@
                 //
                 wrap([$class: 'BuildUser']) {
                     if (env.BUILD_USER_ID && !env.BUILD_USER_ID.equals("jenkins") && !STACK_REUSE.toBoolean()) {
-                        def existingStacks = openstack.getStacksForNameContains(openstackCloud, "${env.BUILD_USER_ID}-${JOB_NAME}", venv)
+                        def existingStacks = openstack.getStacksForNameContains(openstackCloud, "${env.BUILD_USER_ID}-${JOB_NAME}".replaceAll('_', '-'), venv)
                         if (existingStacks.size() >= _MAX_PERMITTED_STACKS) {
                             STACK_DELETE = "false"
                             throw new Exception("You cannot create new stack, you already have ${_MAX_PERMITTED_STACKS} stacks of this type (${JOB_NAME}). \nStack names: ${existingStacks}")
@@ -200,6 +201,7 @@
 
                 // set description
                 currentBuild.description = STACK_NAME
+                outputs.put('stack_name', STACK_NAME)
 
                 if (STACK_REUSE.toBoolean() == false) {
                     // get templates
diff --git a/tcp-qa-pipeline.groovy b/tcp-qa-pipeline.groovy
index 1b178b4..17a7c3e 100644
--- a/tcp-qa-pipeline.groovy
+++ b/tcp-qa-pipeline.groovy
@@ -81,7 +81,7 @@
             . ${VENV_PATH}/bin/activate
 
             cd tcp_tests
-            if ! py.test -vvv -s -p no:django -p no:ipdb --junit-xml=nosetests.xml -k ${TEST_GROUP}; then
+            if ! py.test -vvv -s -p no:django -p no:ipdb --junit-xml=../nosetests.xml -k ${TEST_GROUP}; then
               echo "Tests failed!"
               exit 1
             fi
@@ -98,14 +98,14 @@
 
 def uploadResults(){
     stage('Upload tests results'){
-        def thisBuildUrl = "${env.JENKINS_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/"
-        def testPlanName = "${env.TESTRAIL_MILESTONE} Integration-${new Date().format('yyyy-MM-dd')}"
+        def thisBuildUrl = "${JENKINS_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/"
+        def testPlanName = "${TESTRAIL_MILESTONE} Integration-${new Date().format('yyyy-MM-dd')}"
 
         qaCommon.uploadResultsTestRail([
-            junitXml: "${env.WORKSPACE}/nosetests.xml",
+            junitXml: "${WORKSPACE}/nosetests.xml",
             testPlanName: testPlanName,
-            testSuiteName: "${env.TESTRAIL_TEST_SUITE}",
-            testrailMilestone: "${env.TESTRAIL_MILESTONE}",
+            testSuiteName: "${TESTRAIL_TEST_SUITE}",
+            testrailMilestone: "${TESTRAIL_MILESTONE}",
             jobURL: thisBuildUrl,
         ])
     }
diff --git a/test-salt-model-node.groovy b/test-salt-model-node.groovy
index eaf0104..e22bcbe 100644
--- a/test-salt-model-node.groovy
+++ b/test-salt-model-node.groovy
@@ -56,6 +56,7 @@
       stage("test node") {
         if (checkouted) {
           def workspace = common.getWorkspace()
+          common.infoMsg("Running salt model test for node ${NODE_TARGET} in cluster ${CLUSTER_NAME}")
           saltModelTesting.setupAndTestNode(NODE_TARGET, CLUSTER_NAME, EXTRA_FORMULAS, workspace, FORMULAS_SOURCE, FORMULAS_REVISION, MAX_CPU_PER_JOB.toInteger())
         }
       }
diff --git a/test-salt-models-pipeline.groovy b/test-salt-models-pipeline.groovy
index 2ff76d2..4236fdd 100644
--- a/test-salt-models-pipeline.groovy
+++ b/test-salt-models-pipeline.groovy
@@ -83,6 +83,15 @@
         def infraYMLs = sh(script: "find ./classes/ -regex '.*cluster/[-_a-zA-Z0-9]*/[infra/]*init\\.yml' -exec grep -il 'cluster_name' {} \\;", returnStdout: true).tokenize()
         def branches = [:]
         def acc = 0
+
+        def modifiedClusters = null
+        if (gerritRef) {
+          checkChange = sh(script: "git diff-tree --no-commit-id --name-only -r HEAD | grep -v classes/cluster", returnStatus: true)
+          if (checkChange == 1) {
+            modifiedClusters = sh(script: "git diff-tree --no-commit-id --name-only -r HEAD | grep classes/cluster/ | awk -F/ '{print \$3}' | uniq", returnStdout: true).tokenize()
+          }
+        }
+
         for (int i = 0; i < infraYMLs.size(); i++) {
           def infraYMLConfig = readYaml(file: infraYMLs[i])
           if(!infraYMLConfig["parameters"].containsKey("_param")){
@@ -104,6 +113,10 @@
             acc = 0
           }
 
+          if (gerritRef && modifiedClusters && !modifiedClusters.contains(clusterName)) {
+            continue
+          }
+
           branches[testTarget] = {
             build job: "test-salt-model-node", parameters: [
               [$class: 'StringParameterValue', name: 'DEFAULT_GIT_URL', value: defaultGitUrl],
@@ -133,4 +146,3 @@
      common.sendNotification(currentBuild.result,"",["slack"])
   }
 }
-