Merge "Added mirror snapshot pipeline"
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index 989d130..41c08ab 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -50,6 +50,13 @@
  *   TEST_TEMPEST_IMAGE           Tempest image link
  *   TEST_TEMPEST_PATTERN         If not false, run tests matched to pattern only
  *   TEST_TEMPEST_TARGET          Salt target for tempest node
+ *   TESTRAIL_REPORT              Whether upload results to testrail or not
+ *   TESTRAIL_REPORTER_IMAGE      Docker image for testrail reporter
+ *   TESTRAIL_QA_CREDENTIALS      Credentials for upload to testrail
+ *   TESTRAIL_MILESTONE           Product version for tests
+ *   TESTRAIL_PLAN                Testrail test plan
+ *   TESTRAIL_GROUP               Testrail test group
+ *   TESTRAIL_SUITE               Testrail test suite
  *
  * optional parameters for overwriting soft params
  *   SALT_OVERRIDES              YAML with overrides for Salt deployment
@@ -470,18 +477,23 @@
                 stage('Run k8s conformance e2e tests') {
                     def image = TEST_K8S_CONFORMANCE_IMAGE
                     def output_file = image.replaceAll('/', '-') + '.output'
+                    def target = 'ctl01*'
+                    def conformance_output_file = 'conformance_test.tar'
 
                     // run image
-                    test.runConformanceTests(venvPepper, 'ctl01*', TEST_K8S_API_SERVER, image)
+                    test.runConformanceTests(venvPepper, target, TEST_K8S_API_SERVER, image)
 
                     // collect output
                     sh "mkdir -p ${artifacts_dir}"
-                    file_content = salt.getFileContent(venvPepper, 'ctl01*', '/tmp/' + output_file)
+                    file_content = salt.getFileContent(venvPepper, target, '/tmp/' + output_file)
                     writeFile file: "${artifacts_dir}${output_file}", text: file_content
                     sh "cat ${artifacts_dir}${output_file}"
 
                     // collect artifacts
                     archiveArtifacts artifacts: "${artifacts_dir}${output_file}"
+
+                    // Copy test results
+                    test.CopyConformanceResults(venvPepper, target, artifacts_dir, conformance_output_file)
                 }
             }
 
@@ -500,6 +512,19 @@
                 stage('Archive rally artifacts') {
                     test.archiveRallyArtifacts(venvPepper, TEST_TEMPEST_TARGET)
                 }
+
+                if (common.validInputParam('TESTRAIL_REPORT') && TESTRAIL_REPORT.toBoolean()) {
+                    stage('Upload test results to TestRail') {
+                        def date = sh(script: 'date +%Y-%m-%d', returnStdout: true).trim()
+                        def plan = TESTRAIL_PLAN ?: "[${TESTRAIL_MILESTONE}]System-Devcloud-${date}"
+                        def group = TESTRAIL_GROUP ?: STACK_TEMPLATE
+
+                        salt.cmdRun(venvPepper, TEST_TEMPEST_TARGET, "cd /root/rally_reports && cp \$(ls -t *xml | head -n1) report.xml")
+                        test.uploadResultsTestrail("/root/rally_reports/report.xml",
+                                TESTRAIL_REPORTER_IMAGE, group, TESTRAIL_QA_CREDENTIALS,
+                                plan, TESTRAIL_MILESTONE, TESTRAIL_SUITE)
+                    }
+                }
             }
 
 
diff --git a/create-debmirror-package.groovy b/create-debmirror-package.groovy
new file mode 100644
index 0000000..7911d37
--- /dev/null
+++ b/create-debmirror-package.groovy
@@ -0,0 +1,52 @@
+/**
+ *
+ * Create debmirror package pipeline
+ *
+ * Expected parameters:
+ * MIRROR_NAME - Name of the mirror
+ * MIRROR_URL - URL of mirror
+ * ROOT - Root directory of the upstream location
+ * METHOD - rsync or http
+ * DEBMIRROR_ARGS - args for debmirror comand
+ * UPLOAD_URL - URL to upload TAR to
+ */
+
+// Load shared libs
+def common = new com.mirantis.mk.Common()
+
+timeout(time: 12, unit: 'HOURS') {
+    node("python&&disk-xl") {
+        try {
+            def workspace = common.getWorkspace()
+            if(METHOD == "rsync"){
+                ROOT = ":mirror/${ROOT}"
+            }
+            stage("Create mirror"){
+                def mirrordir="${workspace}/mirror"
+                def debmlog="${workspace}/mirror_${MIRROR_NAME}_log"
+
+                sh "debmirror --verbose --method=${METHOD} --progress --host=${MIRROR_URL} --root=${ROOT} ${DEBMIRROR_ARGS} ${mirrordir}/${MIRROR_NAME} 2>&1 | tee -a ${debmlog}"
+
+                sh "tar -czvf ${workspace}/${MIRROR_NAME}.tar.gz -C ${mirrordir}/${MIRROR_NAME} ."
+            }
+
+            stage("Upload mirror"){
+                common.retry(3, 5, {
+                    uploadImageStatus = sh(script: "curl -f -T ${workspace}/${MIRROR_NAME}.tar.gz ${UPLOAD_URL}", returnStatus: true)
+                    if(uploadImageStatus!=0){
+                        throw new Exception("Image upload failed")
+                    }
+                })
+            }
+
+        } catch (Throwable e) {
+            // If there was an error or exception thrown, the build failed
+            currentBuild.result = "FAILURE"
+            throw e
+        }finally {
+            stage("Cleanup"){
+                sh "rm -rf ${workspace}/*"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/test-salt-formulas-pipeline.groovy b/test-salt-formulas-pipeline.groovy
index af22dc8..56e9bb9 100644
--- a/test-salt-formulas-pipeline.groovy
+++ b/test-salt-formulas-pipeline.groovy
@@ -43,8 +43,13 @@
         try {
           triggerTestFormulaJob(currentFormula, defaultGitRef, defaultGitUrl)
         } catch (Exception e) {
-          failedFormulas << currentFormula
-          common.warningMsg("Test of ${currentFormula} failed :  ${e}")
+          if (e.getMessage().contains("completed with status ABORTED")) {
+            common.warningMsg("Test of ${currentFormula} was aborted and will be retriggered")
+            futureFormulas << currentFormula
+          } else {
+            failedFormulas << currentFormula
+            common.warningMsg("Test of ${currentFormula} failed :  ${e}")
+          }
         }
       }
     }