Merge "Completed first version of pipeline for generating salt-model sphing documentation"
diff --git a/build-mirror-image.groovy b/build-mirror-image.groovy
index 822d398..0aff603 100644
--- a/build-mirror-image.groovy
+++ b/build-mirror-image.groovy
@@ -44,28 +44,12 @@
def uploadImageStatus = ""
def uploadMd5Status = ""
-def retry(int times = 5, int delay = 0, Closure body) {
- int retries = 0
- def exceptions = []
- while(retries++ < times) {
- try {
- return body.call()
- } catch(e) {
- sleep(delay)
- }
- }
- currentBuild.result = "FAILURE"
- throw new Exception("Failed after $times retries")
-}
-
timeout(time: 12, unit: 'HOURS') {
node("python&&disk-xl") {
try {
def workspace = common.getWorkspace()
openstackEnv = String.format("%s/venv", workspace)
venvPepper = String.format("%s/venvPepper", workspace)
- rcFile = openstack.createOpenstackEnv(openstackEnv, OS_URL, OS_CREDENTIALS_ID, OS_PROJECT, "default", "", "default", "2", "")
- def openstackVersion = OS_VERSION
VM_IP_DELAY = VM_IP_DELAY as Integer
VM_IP_RETRIES = VM_IP_RETRIES as Integer
@@ -79,10 +63,11 @@
}
sh "wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/salt-bootstrap.sh"
- openstack.setupOpenstackVirtualenv(openstackEnv, openstackVersion)
+ openstack.setupOpenstackVirtualenv(openstackEnv, OS_VERSION)
}
stage("Spawn Instance"){
+ rcFile = openstack.createOpenstackEnv(OS_URL, OS_CREDENTIALS_ID, OS_PROJECT, "default", "", "default", "2", "")
privateKey = openstack.runOpenstackCommand("openstack keypair create mcp-offline-keypair-${dateTime}", rcFile, openstackEnv)
common.infoMsg(privateKey)
@@ -94,21 +79,26 @@
sh "envsubst < salt-bootstrap.sh > salt-bootstrap.sh.temp;mv salt-bootstrap.sh.temp salt-bootstrap.sh; cat salt-bootstrap.sh"
}
- openstackServer = openstack.runOpenstackCommand("openstack server create --key-name mcp-offline-keypair-${dateTime} --availability-zone ${VM_AVAILABILITY_ZONE} --image ${VM_IMAGE} --flavor ${VM_FLAVOR} --nic net-id=${VM_NETWORK_ID},v4-fixed-ip=${VM_IP} --user-data salt-bootstrap.sh mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
+ if(VM_IP != ""){
+ openstackServer = openstack.runOpenstackCommand("openstack server create --key-name mcp-offline-keypair-${dateTime} --availability-zone ${VM_AVAILABILITY_ZONE} --image ${VM_IMAGE} --flavor ${VM_FLAVOR} --nic net-id=${VM_NETWORK_ID},v4-fixed-ip=${VM_IP} --user-data salt-bootstrap.sh mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
+ }else{
+ openstackServer = openstack.runOpenstackCommand("openstack server create --key-name mcp-offline-keypair-${dateTime} --availability-zone ${VM_AVAILABILITY_ZONE} --image ${VM_IMAGE} --flavor ${VM_FLAVOR} --nic net-id=${VM_NETWORK_ID} --user-data salt-bootstrap.sh mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
+ }
sleep(60)
- retry(VM_IP_RETRIES, VM_IP_DELAY){
+ common.retry(VM_IP_RETRIES, VM_IP_DELAY){
openstack.runOpenstackCommand("openstack ip floating add ${floatingIP} mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
}
sleep(500)
- retry(VM_CONNECT_RETRIES, VM_CONNECT_DELAY){
+ common.retry(VM_CONNECT_RETRIES, VM_CONNECT_DELAY){
sh "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i id_rsa root@${floatingIP}:/srv/initComplete ./"
}
python.setupPepperVirtualenv(venvPepper, "http://${floatingIP}:6969", SALT_MASTER_CREDENTIALS)
}
+
stage("Prepare instance"){
salt.runSaltProcessStep(venvPepper, '*apt*', 'saltutil.refresh_pillar', [], null, true)
salt.runSaltProcessStep(venvPepper, '*apt*', 'saltutil.sync_all', [], null, true)
@@ -130,14 +120,8 @@
stage("Create Aptly"){
common.infoMsg("Creating Aptly")
salt.enforceState(venvPepper, '*apt*', ['aptly'], true, false, null, false, -1, 2)
- //TODO: Do it new way
- salt.cmdRun(venvPepper, '*apt*', "aptly_mirror_update.sh -s -v", true, null, true, ["runas=aptly"])
- salt.cmdRun(venvPepper, '*apt*', "nohup aptly api serve --no-lock > /dev/null 2>&1 </dev/null &", true, null, true, ["runas=aptly"])
- salt.cmdRun(venvPepper, '*apt*', "aptly-publisher --timeout=1200 publish -v -c /etc/aptly-publisher.yaml --architectures amd64 --url http://127.0.0.1:8080 --recreate --force-overwrite", true, null, true, ["runas=aptly"])
- salt.cmdRun(venvPepper, '*apt*', "aptly db cleanup", true, null, true, ["runas=aptly"])
- //NEW way
- //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", "runas=aptly"], null, true)
- //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acrfv", "runas=aptly"], null, true)
+ salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", "runas=aptly"], null, true)
+ salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acrfv", "runas=aptly"], null, true)
salt.cmdRun(venvPepper, '*apt*', "wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/aptly/aptly-update.sh -O /srv/scripts/aptly-update.sh")
salt.cmdRun(venvPepper, '*apt*', "chmod +x /srv/scripts/aptly-update.sh")
}
@@ -173,36 +157,37 @@
salt.cmdRun(venvPepper, '*apt*', "rm -rf /var/lib/cloud/sem/* /var/lib/cloud/instance /var/lib/cloud/instances/*")
salt.cmdRun(venvPepper, '*apt*', "cloud-init init")
- retry(3, 5){
+ common.retry(3, 5){
openstack.runOpenstackCommand("openstack server stop mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
}
- retry(6, 30){
+ common.retry(6, 30){
serverStatus = openstack.runOpenstackCommand("openstack server show --format value -c status mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
if(serverStatus != "SHUTOFF"){
throw new ResourceException("Instance is not ready for image create.")
}
}
- retry(3, 5){
+ common.retry(3, 5){
openstack.runOpenstackCommand("openstack server image create --name ${IMAGE_NAME}-${dateTime} --wait mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
}
}
stage("Publish image"){
common.infoMsg("Saving image ${IMAGE_NAME}-${dateTime}")
- retry(3, 5){
+ common.retry(3, 5){
openstack.runOpenstackCommand("openstack image save --file ${IMAGE_NAME}-${dateTime}.qcow2 ${IMAGE_NAME}-${dateTime}", rcFile, openstackEnv)
}
sh "md5sum ${IMAGE_NAME}-${dateTime}.qcow2 > ${IMAGE_NAME}-${dateTime}.qcow2.md5"
common.infoMsg("Uploading image ${IMAGE_NAME}-${dateTime}")
- retry(3, 5){
+ common.retry(3, 5){
uploadImageStatus = sh(script: "curl -f -T ${IMAGE_NAME}-${dateTime}.qcow2 ${UPLOAD_URL}", returnStatus: true)
if(uploadImageStatus!=0){
throw new Exception("Image upload failed")
}
}
- retry(3, 5){
+
+ common.retry(3, 5){
uploadMd5Status = sh(script: "curl -f -T ${IMAGE_NAME}-${dateTime}.qcow2.md5 ${UPLOAD_URL}", returnStatus: true)
if(uploadMd5Status != 0){
throw new Exception("MD5 sum upload failed")
diff --git a/ceph-remove-osd.groovy b/ceph-remove-osd.groovy
index 71946b7..169bbd0 100644
--- a/ceph-remove-osd.groovy
+++ b/ceph-remove-osd.groovy
@@ -22,21 +22,45 @@
def flags = CLUSTER_FLAGS.tokenize(',')
def osds = OSD.tokenize(',')
-def removePartition(master, target, partition_uuid) {
- def partition = ""
- try {
- // partition = /dev/sdi2
- partition = runCephCommand(master, target, "blkid | grep ${partition_uuid} ")['return'][0].values()[0].split("(?<=[0-9])")[0]
- } catch (Exception e) {
- common.warningMsg(e)
- }
+def removePartition(master, target, partition_uuid, type='', id=-1) {
+ def partition = ""
+ if (type == 'lockbox') {
+ try {
+ // umount - partition = /dev/sdi2
+ partition = runCephCommand(master, target, "lsblk -rp | grep -v mapper | grep ${partition_uuid} ")['return'][0].values()[0].split()[0]
+ runCephCommand(master, target, "umount ${partition}")
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
+ } else if (type == 'data') {
+ try {
+ // umount - partition = /dev/sdi2
+ partition = runCephCommand(master, target, "df | grep /var/lib/ceph/osd/ceph-${id}")['return'][0].values()[0].split()[0]
+ runCephCommand(master, target, "umount ${partition}")
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
+ try {
+ // partition = /dev/sdi2
+ partition = runCephCommand(master, target, "blkid | grep ${partition_uuid} ")['return'][0].values()[0].split(":")[0]
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
+ } else {
+ try {
+ // partition = /dev/sdi2
+ partition = runCephCommand(master, target, "blkid | grep ${partition_uuid} ")['return'][0].values()[0].split(":")[0]
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
+ }
if (partition?.trim()) {
// dev = /dev/sdi
def dev = partition.replaceAll('\\d+$', "")
// part_id = 2
- def part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]", "")
- runCephCommand(master, target, "parted ${dev} rm ${part_id}")
+ def part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]+", "")
+ runCephCommand(master, target, "Ignore | parted ${dev} rm ${part_id}")
}
return
}
@@ -75,10 +99,12 @@
// get list of osd disks of the host
salt.runSaltProcessStep(pepperEnv, HOST, 'saltutil.sync_grains', [], null, true, 5)
- def cephGrain = salt.getGrain(pepperEnv, HOST, 'ceph')['return']
+ def cephGrain = salt.getGrain(pepperEnv, HOST, 'ceph')
+
if(cephGrain['return'].isEmpty()){
throw new Exception("Ceph salt grain cannot be found!")
}
+ common.print(cephGrain)
def ceph_disks = cephGrain['return'][0].values()[0].values()[0]['ceph_disk']
common.prettyPrint(ceph_disks)
@@ -137,8 +163,9 @@
}
for (osd_id in osd_ids) {
-
id = osd_id.replaceAll('osd.', '')
+ /*
+
def dmcrypt = ""
try {
dmcrypt = runCephCommand(pepperEnv, HOST, "ls -la /var/lib/ceph/osd/ceph-${id}/ | grep dmcrypt")['return'][0].values()[0]
@@ -156,6 +183,8 @@
}
}
+ */
+
// remove journal, block_db, block_wal partition `parted /dev/sdj rm 3`
stage('Remove journal / block_db / block_wal partition') {
def partition_uuid = ""
@@ -163,39 +192,73 @@
def block_db_partition_uuid = ""
def block_wal_partition_uuid = ""
try {
- journal_partition_uuid = runCephCommand(pepperEnv, HOST, "ls -la /var/lib/ceph/osd/ceph-${id}/ | grep journal | grep partuuid")
- journal_partition_uuid = journal_partition_uuid.toString().trim().split("\n")[0].substring(journal_partition_uuid.toString().trim().lastIndexOf("/")+1)
+ journal_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/journal_uuid")['return'][0].values()[0].split("\n")[0]
} catch (Exception e) {
common.infoMsg(e)
}
try {
- block_db_partition_uuid = runCephCommand(pepperEnv, HOST, "ls -la /var/lib/ceph/osd/ceph-${id}/ | grep 'block.db' | grep partuuid")
- block_db_partition_uuid = block_db_partition_uuid.toString().trim().split("\n")[0].substring(block_db_partition_uuid.toString().trim().lastIndexOf("/")+1)
+ block_db_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block.db_uuid")['return'][0].values()[0].split("\n")[0]
} catch (Exception e) {
common.infoMsg(e)
}
try {
- block_wal_partition_uuid = runCephCommand(pepperEnv, HOST, "ls -la /var/lib/ceph/osd/ceph-${id}/ | grep 'block.wal' | grep partuuid")
- block_wal_partition_uuid = block_wal_partition_uuid.toString().trim().split("\n")[0].substring(block_wal_partition_uuid.toString().trim().lastIndexOf("/")+1)
+ block_wal_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block.wal_uuid")['return'][0].values()[0].split("\n")[0]
} catch (Exception e) {
common.infoMsg(e)
}
- // set partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
+ // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
if (journal_partition_uuid?.trim()) {
- partition_uuid = journal_partition_uuid
- } else if (block_db_partition_uuid?.trim()) {
- partition_uuid = block_db_partition_uuid
+ removePartition(pepperEnv, HOST, journal_partition_uuid)
}
-
- // if disk has journal, block_db or block_wal on different disk, then remove the partition
- if (partition_uuid?.trim()) {
- removePartition(pepperEnv, HOST, partition_uuid)
+ if (block_db_partition_uuid?.trim()) {
+ removePartition(pepperEnv, HOST, block_db_partition_uuid)
}
if (block_wal_partition_uuid?.trim()) {
removePartition(pepperEnv, HOST, block_wal_partition_uuid)
}
+
+ try {
+ runCephCommand(pepperEnv, HOST, "partprobe")
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
+ }
+
+ // remove data / block / lockbox partition `parted /dev/sdj rm 3`
+ stage('Remove data / block / lockbox partition') {
+ def data_partition_uuid = ""
+ def block_partition_uuid = ""
+ def lockbox_partition_uuid = ""
+ try {
+ data_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/fsid")['return'][0].values()[0].split("\n")[0]
+ common.print(data_partition_uuid)
+ } catch (Exception e) {
+ common.infoMsg(e)
+ }
+ try {
+ block_partition_uuid = runCephCommand(pepperEnv, HOST, "cat /var/lib/ceph/osd/ceph-${id}/block_uuid")['return'][0].values()[0].split("\n")[0]
+ } catch (Exception e) {
+ common.infoMsg(e)
+ }
+
+ try {
+ lockbox_partition_uuid = data_partition_uuid
+ } catch (Exception e) {
+ common.infoMsg(e)
+ }
+
+ // remove partition_uuid = 2c76f144-f412-481e-b150-4046212ca932
+ if (block_partition_uuid?.trim()) {
+ removePartition(pepperEnv, HOST, block_partition_uuid)
+ }
+ if (data_partition_uuid?.trim()) {
+ removePartition(pepperEnv, HOST, data_partition_uuid, 'data', id)
+ }
+ if (lockbox_partition_uuid?.trim()) {
+ removePartition(pepperEnv, HOST, lockbox_partition_uuid, 'lockbox')
+ }
}
}
// remove cluster flags
diff --git a/ceph-replace-failed-osd.groovy b/ceph-replace-failed-osd.groovy
index 93b6573..2361098 100644
--- a/ceph-replace-failed-osd.groovy
+++ b/ceph-replace-failed-osd.groovy
@@ -122,9 +122,14 @@
if (DMCRYPT.toBoolean() == true) {
// remove partition tables
- stage('dd part tables') {
+ stage('dd / zap device') {
for (dev in devices) {
- runCephCommand(pepperEnv, HOST, "dd if=/dev/zero of=${dev} bs=512 count=1 conv=notrunc")
+ runCephCommand(pepperEnv, HOST, "dd if=/dev/zero of=${dev} bs=4096k count=1 conv=notrunc")
+ try {
+ runCephCommand(pepperEnv, HOST, "sgdisk --zap-all --clear --mbrtogpt -g -- ${dev}")
+ } catch (Exception e) {
+ common.warningMsg(e)
+ }
}
}
@@ -135,7 +140,7 @@
// dev = /dev/sdi
def dev = partition.replaceAll("[0-9]", "")
// part_id = 2
- def part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]", "")
+ def part_id = partition.substring(partition.lastIndexOf("/")+1).replaceAll("[^0-9]+", "")
try {
runCephCommand(pepperEnv, HOST, "Ignore | parted ${dev} rm ${part_id}")
} catch (Exception e) {
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/cvp-func.groovy b/cvp-func.groovy
new file mode 100644
index 0000000..ef50945
--- /dev/null
+++ b/cvp-func.groovy
@@ -0,0 +1,63 @@
+/**
+ *
+ * Launch validation of the cloud
+ *
+ * Expected parameters:
+
+ * SALT_MASTER_URL URL of Salt master
+ * SALT_MASTER_CREDENTIALS Credentials that are used in this Jenkins for accessing Salt master (usually "salt")
+ * PROXY Proxy address (if any) for accessing the Internet. It will be used for cloning repos and installing pip dependencies
+ * TEST_IMAGE Docker image link to use for running container with testing tools.
+ * TOOLS_REPO URL of repo where testing tools, scenarios, configs are located
+ *
+ * DEBUG_MODE If you need to debug (keep container after test), please enabled this
+ * SKIP_LIST_PATH Path to tempest skip list file in TOOLS_REPO
+ * TARGET_NODE Node to run container with Tempest/Rally
+ * TEMPEST_REPO Tempest repo to clone and use
+ * TEMPEST_TEST_PATTERN Tests to run during HA scenarios
+ * TEMPEST_ENDPOINT_TYPE Type of OS endpoint to use during test run
+ *
+ */
+
+common = new com.mirantis.mk.Common()
+salt = new com.mirantis.mk.Salt()
+validate = new com.mirantis.mcp.Validate()
+
+def saltMaster
+def artifacts_dir = 'validation_artifacts/'
+def remote_artifacts_dir = '/root/qa_results/'
+
+node() {
+ try{
+ stage('Initialization') {
+ saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
+ validate.runBasicContainer(saltMaster, TARGET_NODE, TEST_IMAGE)
+ sh "rm -rf ${artifacts_dir}"
+ salt.cmdRun(saltMaster, TARGET_NODE, "mkdir -p ${remote_artifacts_dir}")
+ validate.configureContainer(saltMaster, TARGET_NODE, PROXY, TOOLS_REPO, TEMPEST_REPO, TEMPEST_ENDPOINT_TYPE)
+ }
+
+ stage('Run Tempest tests') {
+ sh "mkdir -p ${artifacts_dir}"
+ validate.runCVPtempest(saltMaster, TARGET_NODE, TEMPEST_TEST_PATTERN, SKIP_LIST_PATH, remote_artifacts_dir)
+ }
+
+ stage('Collect results') {
+ validate.addFiles(saltMaster, TARGET_NODE, remote_artifacts_dir, artifacts_dir)
+ archiveArtifacts artifacts: "${artifacts_dir}/*"
+ junit "${artifacts_dir}/*.xml"
+ }
+ } catch (Throwable e) {
+ // If there was an error or exception thrown, the build failed
+ currentBuild.result = "FAILURE"
+ throw e
+ } finally {
+ if (DEBUG_MODE == 'false') {
+ if (TOOLS_REPO != "") {
+ validate.openstack_cleanup(saltMaster, TARGET_NODE)
+ }
+ validate.runCleanup(saltMaster, TARGET_NODE)
+ salt.cmdRun(saltMaster, TARGET_NODE, "rm -rf ${remote_artifacts_dir}")
+ }
+ }
+}
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}")
+ }
}
}
}