| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 1 | /* | 
 | 2 | Able to be triggered from Gerrit if : | 
 | 3 | Variators: | 
 | 4 | Modes: | 
 | 5 | 1) manual run via job-build , possible to pass refspec | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 6 |    TODO: currently impossible to use custom COOKIECUTTER_TEMPLATE_URL| RECLASS_SYSTEM_URL Gerrit-one always used. | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 7 |    - for CC | 
 | 8 |    - Reclass | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 9 |  | 
 | 10 | 2) gerrit trigger | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 11 |    Automatically switches if GERRIT_PROJECT variable detected | 
 | 12 |    Always test GERRIT_REFSPEC VS GERRIT_BRANCH-master version of opposite project | 
 | 13 |  */ | 
 | 14 |  | 
| Alexander Evseev | 02fe5eb | 2018-11-15 13:58:36 +0100 | [diff] [blame] | 15 | import groovy.json.JsonOutput | 
 | 16 |  | 
| chnyda | e80bb92 | 2017-05-29 17:48:40 +0200 | [diff] [blame] | 17 | common = new com.mirantis.mk.Common() | 
| azvyagintsev | 1385db9 | 2019-03-22 16:05:10 +0200 | [diff] [blame] | 18 | mcpCommon = new com.mirantis.mcp.Common() | 
| chnyda | bc63c9a | 2017-05-30 15:37:54 +0200 | [diff] [blame] | 19 | gerrit = new com.mirantis.mk.Gerrit() | 
| chnyda | e80bb92 | 2017-05-29 17:48:40 +0200 | [diff] [blame] | 20 | python = new com.mirantis.mk.Python() | 
| chnyda | e80bb92 | 2017-05-29 17:48:40 +0200 | [diff] [blame] | 21 |  | 
| Denis Egorenko | d67a6d2 | 2018-10-18 16:00:46 +0400 | [diff] [blame] | 22 | extraVarsYAML = env.EXTRA_VARIABLES_YAML.trim() ?: '' | 
| Denis Egorenko | 535d5b6 | 2018-09-28 11:28:10 +0400 | [diff] [blame] | 23 | if (extraVarsYAML) { | 
 | 24 |     common.mergeEnv(env, extraVarsYAML) | 
| Alexander Evseev | 02fe5eb | 2018-11-15 13:58:36 +0100 | [diff] [blame] | 25 |     extraVars = readYaml text: extraVarsYAML | 
 | 26 | } else { | 
 | 27 |     extraVars = [:] | 
| Denis Egorenko | 535d5b6 | 2018-09-28 11:28:10 +0400 | [diff] [blame] | 28 | } | 
 | 29 |  | 
| Aleksey Zvyagintsev | 4a80421 | 2019-02-07 13:02:31 +0000 | [diff] [blame] | 30 | slaveNode = env.SLAVE_NODE ?: 'virtual' | 
| azvyagintsev | e7b8e79 | 2018-09-21 17:27:01 +0300 | [diff] [blame] | 31 | checkIncludeOrder = env.CHECK_INCLUDE_ORDER ?: false | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 32 |  | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 33 | // Global var's | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 34 | gerritConData = [credentialsId       : env.CREDENTIALS_ID, | 
 | 35 |                  gerritName          : env.GERRIT_NAME ?: 'mcp-jenkins', | 
| Roman Vyalov | f0c596e | 2018-10-01 17:56:09 +0300 | [diff] [blame] | 36 |                  gerritHost          : env.GERRIT_HOST ?: 'gerrit.mcp.mirantis.com', | 
| azvyagintsev | b266ad2 | 2018-09-11 12:11:11 +0300 | [diff] [blame] | 37 |                  gerritScheme        : env.GERRIT_SCHEME ?: 'ssh', | 
 | 38 |                  gerritPort          : env.GERRIT_PORT ?: '29418', | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 39 |                  gerritRefSpec       : null, | 
 | 40 |                  gerritProject       : null, | 
 | 41 |                  withWipeOut         : true, | 
 | 42 |                  GERRIT_CHANGE_NUMBER: null] | 
 | 43 | // | 
| Roman Vyalov | f0c596e | 2018-10-01 17:56:09 +0300 | [diff] [blame] | 44 | //ccTemplatesRepo = env.COOKIECUTTER_TEMPLATE_URL ?: 'ssh://mcp-jenkins@gerrit.mcp.mirantis.com:29418/mk/cookiecutter-templates' | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 45 | gerritDataCCHEAD = [:] | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 46 | gerritDataCC = [:] | 
 | 47 | gerritDataCC << gerritConData | 
 | 48 | gerritDataCC['gerritBranch'] = env.COOKIECUTTER_TEMPLATE_BRANCH ?: 'master' | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 49 | gerritDataCC['gerritRefSpec'] = env.COOKIECUTTER_TEMPLATE_REF ?: null | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 50 | gerritDataCC['gerritProject'] = 'mk/cookiecutter-templates' | 
 | 51 | // | 
| Roman Vyalov | f0c596e | 2018-10-01 17:56:09 +0300 | [diff] [blame] | 52 | //reclassSystemRepo = env.RECLASS_SYSTEM_URL ?: 'ssh://mcp-jenkins@gerrit.mcp.mirantis.com:29418/salt-models/reclass-system' | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 53 | gerritDataRSHEAD = [:] | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 54 | gerritDataRS = [:] | 
 | 55 | gerritDataRS << gerritConData | 
| Denis Egorenko | e7040ac | 2018-10-24 20:11:04 +0400 | [diff] [blame] | 56 | gerritDataRS['gerritBranch'] = env.RECLASS_SYSTEM_BRANCH ?: 'master' | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 57 | gerritDataRS['gerritRefSpec'] = env.RECLASS_SYSTEM_GIT_REF ?: null | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 58 | gerritDataRS['gerritProject'] = 'salt-models/reclass-system' | 
 | 59 |  | 
| azvyagintsev | ec055b4 | 2018-10-11 12:59:05 +0300 | [diff] [blame] | 60 | // version of debRepos, aka formulas|reclass|ubuntu | 
| azvyagintsev | 10e2401 | 2018-09-10 21:36:32 +0300 | [diff] [blame] | 61 | testDistribRevision = env.DISTRIB_REVISION ?: 'nightly' | 
| Denis Egorenko | 086aff1 | 2018-10-18 17:54:59 +0400 | [diff] [blame] | 62 |  | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 63 | // Name of sub-test chunk job | 
 | 64 | chunkJobName = "test-mk-cookiecutter-templates-chunk" | 
 | 65 | testModelBuildsData = [:] | 
| Vasyl Saienko | 772e123 | 2018-07-23 14:42:24 +0300 | [diff] [blame] | 66 |  | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 67 | def getAndUnpackNodesInfoArtifact(jobName, copyTo, build) { | 
 | 68 |     return { | 
 | 69 |         dir(copyTo) { | 
 | 70 |             copyArtifacts(projectName: jobName, selector: specific(build), filter: "nodesinfo.tar.gz") | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 71 |             sh "tar -xf nodesinfo.tar.gz" | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 72 |             sh "rm -v nodesinfo.tar.gz" | 
 | 73 |         } | 
 | 74 |     } | 
 | 75 | } | 
| azvyagintsev | 8798553 | 2018-07-10 20:49:38 +0300 | [diff] [blame] | 76 |  | 
| Denis Egorenko | 086aff1 | 2018-10-18 17:54:59 +0400 | [diff] [blame] | 77 | def testModel(modelFile, reclassArtifactName, artifactCopyPath, useExtraRepos = false) { | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 78 |     // modelFile - `modelfiname` from model/modelfiname/modelfiname.yaml | 
 | 79 |     //* Grub all models and send it to check in paralell - by one in thread. | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 80 |     def _uuid = "${env.JOB_NAME.toLowerCase()}_${env.BUILD_TAG.toLowerCase()}_${modelFile.toLowerCase()}_" + UUID.randomUUID().toString().take(8) | 
| Alexander Evseev | 02fe5eb | 2018-11-15 13:58:36 +0100 | [diff] [blame] | 81 |     def _values = [ | 
| azvyagintsev | 4220bff | 2019-01-09 21:32:11 +0200 | [diff] [blame] | 82 |         MODELS_TARGZ    : "${env.BUILD_URL}/artifact/${reclassArtifactName}", | 
 | 83 |         DockerCName     : _uuid, | 
 | 84 |         testReclassEnv  : "model/${modelFile}/", | 
 | 85 |         modelFile       : "contexts/${modelFile}.yml", | 
| Alexander Evseev | 02fe5eb | 2018-11-15 13:58:36 +0100 | [diff] [blame] | 86 |         DISTRIB_REVISION: testDistribRevision, | 
| azvyagintsev | 4220bff | 2019-01-09 21:32:11 +0200 | [diff] [blame] | 87 |         useExtraRepos   : useExtraRepos, | 
| Alexander Evseev | 02fe5eb | 2018-11-15 13:58:36 +0100 | [diff] [blame] | 88 |     ] | 
 | 89 |     def _values_string = JsonOutput.toJson(_values << extraVars) | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 90 |     def chunkJob = build job: chunkJobName, parameters: [ | 
| azvyagintsev | 08b34e3 | 2018-09-12 12:29:42 +0300 | [diff] [blame] | 91 |         [$class: 'TextParameterValue', name: 'EXTRA_VARIABLES_YAML', | 
| azvyagintsev | 30bc82e | 2018-08-22 12:26:06 +0300 | [diff] [blame] | 92 |          value : _values_string.stripIndent()], | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 93 |     ] | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 94 |     // Put sub-job info into global map. | 
 | 95 |     testModelBuildsData.put(_uuid, ['jobname'  : chunkJob.fullProjectName, | 
 | 96 |                                     'copyToDir': "${artifactCopyPath}/${modelFile}", | 
 | 97 |                                     'buildId'  : "${chunkJob.number}"]) | 
| chnyda | bc63c9a | 2017-05-30 15:37:54 +0200 | [diff] [blame] | 98 | } | 
 | 99 |  | 
| Denis Egorenko | 086aff1 | 2018-10-18 17:54:59 +0400 | [diff] [blame] | 100 | def StepTestModel(basename, reclassArtifactName, artifactCopyPath, useExtraRepos = false) { | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 101 |     // We need to wrap what we return in a Groovy closure, or else it's invoked | 
 | 102 |     // when this method is called, not when we pass it to parallel. | 
 | 103 |     // To do this, you need to wrap the code below in { }, and either return | 
 | 104 |     // that explicitly, or use { -> } syntax. | 
 | 105 |     // return node object | 
 | 106 |     return { | 
 | 107 |         node(slaveNode) { | 
| Denis Egorenko | 086aff1 | 2018-10-18 17:54:59 +0400 | [diff] [blame] | 108 |             testModel(basename, reclassArtifactName, artifactCopyPath, useExtraRepos) | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 109 |         } | 
| chnyda | e80bb92 | 2017-05-29 17:48:40 +0200 | [diff] [blame] | 110 |     } | 
| azvyagintsev | 8798553 | 2018-07-10 20:49:38 +0300 | [diff] [blame] | 111 | } | 
 | 112 |  | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 113 | def StepPrepareGit(templateEnvFolder, gerrit_data) { | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 114 |     // return git clone  object | 
 | 115 |     return { | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 116 |         common.infoMsg("StepPrepareGit: ${gerrit_data}") | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 117 |         // fetch needed sources | 
 | 118 |         dir(templateEnvFolder) { | 
| azvyagintsev | 4f34f7a | 2019-02-26 18:47:37 +0200 | [diff] [blame] | 119 |             if (!gerrit_data['gerritRefSpec']) { | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 120 |                 // Get clean HEAD | 
 | 121 |                 gerrit_data['useGerritTriggerBuildChooser'] = false | 
| Denis Egorenko | 80d45b2 | 2019-01-31 22:28:38 +0400 | [diff] [blame] | 122 |             } | 
 | 123 |             def checkouted = gerrit.gerritPatchsetCheckout(gerrit_data) | 
 | 124 |             if (!checkouted) { | 
 | 125 |                 error("Failed to get repo:${gerrit_data}") | 
| azvyagintsev | 8798553 | 2018-07-10 20:49:38 +0300 | [diff] [blame] | 126 |             } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 127 |         } | 
| azvyagintsev | 8798553 | 2018-07-10 20:49:38 +0300 | [diff] [blame] | 128 |     } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 129 | } | 
 | 130 |  | 
 | 131 | def StepGenerateModels(_contextFileList, _virtualenv, _templateEnvDir) { | 
 | 132 |     return { | 
 | 133 |         for (contextFile in _contextFileList) { | 
| Denis Egorenko | f346909 | 2018-10-17 17:05:50 +0400 | [diff] [blame] | 134 |             def basename = common.GetBaseName(contextFile, '.yml') | 
| azvyagintsev | 1385db9 | 2019-03-22 16:05:10 +0200 | [diff] [blame] | 135 |             def contextYaml = readYaml text: readFile(file: "${_templateEnvDir}/contexts/${contextFile}") | 
 | 136 |             // secrets_encryption overcomplicated for expected 'fast syntax tests' | 
 | 137 |             // So, lets disable it. It would be tested only in generate-cookiecutter-products.groovy pipeline | 
 | 138 |             if (contextYaml['default_context'].get('secrets_encryption_enabled')) { | 
 | 139 |                 common.warningMsg('Disabling secrets_encryption_enabled for tests!') | 
 | 140 |                 contextYaml['default_context']['secrets_encryption_enabled'] = 'False' | 
 | 141 |             } | 
 | 142 |             context = mcpCommon.dumpYAML(contextYaml) | 
| azvyagintsev | 4f34f7a | 2019-02-26 18:47:37 +0200 | [diff] [blame] | 143 |             if (!fileExists(new File(_templateEnvDir, 'tox.ini').toString())) { | 
 | 144 |                 common.warningMsg('Forming NEW reclass-root structure...') | 
 | 145 |                 python.generateModel(context, basename, 'cfg01', _virtualenv, "${_templateEnvDir}/model", _templateEnvDir) | 
 | 146 |             } else { | 
 | 147 |                 // tox-based CC generated structure of reclass,from the root. Otherwise for bw compat, modelEnv | 
 | 148 |                 // still expect only lower lvl of project, aka model/classes/cluster/XXX/. So,lets dump result into | 
 | 149 |                 // temp dir, and then copy it over initial structure. | 
 | 150 |                 def reclassTempRootDir = sh(script: "mktemp -d -p ${env.WORKSPACE}", returnStdout: true).trim() | 
 | 151 |                 python.generateModel(context, basename, 'cfg01', _virtualenv, reclassTempRootDir, _templateEnvDir) | 
 | 152 |                 dir("${_templateEnvDir}/model/${basename}/") { | 
 | 153 |                     if (fileExists(new File(reclassTempRootDir, 'reclass').toString())) { | 
 | 154 |                         common.warningMsg('Forming NEW reclass-root structure...') | 
 | 155 |                         sh("cp -ra ${reclassTempRootDir}/reclass/* .") | 
 | 156 |                     } else { | 
 | 157 |                         // those hack needed only for period release/2019.2.0 => current patch. | 
 | 158 |                         common.warningMsg('Forming OLD reclass-root structure...') | 
 | 159 |                         sh("mkdir -p classes/cluster/ ; cd classes/cluster/; cp -ra ${reclassTempRootDir}/* .") | 
 | 160 |                     } | 
 | 161 |                 } | 
 | 162 |             } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 163 |         } | 
 | 164 |     } | 
 | 165 | } | 
 | 166 |  | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 167 | def globalVariatorsUpdate() { | 
 | 168 |     // Simple function, to check and define branch-around variables | 
 | 169 |     // In general, simply make transition updates for non-master branch | 
 | 170 |     // based on magic logic | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 171 |     def newline = '<br/>' | 
 | 172 |     def messages = [] | 
| azvyagintsev | b266ad2 | 2018-09-11 12:11:11 +0300 | [diff] [blame] | 173 |     if (env.GERRIT_PROJECT) { | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 174 |         messages.add("<font color='red'>GerritTrigger detected! We are in auto-mode:</font>") | 
 | 175 |         messages.add("Test env variables has been changed:") | 
| azvyagintsev | e0eb6cd | 2018-09-12 13:00:40 +0300 | [diff] [blame] | 176 |         // TODO are we going to have such branches? | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 177 |         if (!['nightly', 'testing', 'stable', 'proposed', 'master'].contains(env.GERRIT_BRANCH)) { | 
 | 178 |             gerritDataCC['gerritBranch'] = env.GERRIT_BRANCH | 
 | 179 |             gerritDataRS['gerritBranch'] = env.GERRIT_BRANCH | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 180 |             testDistribRevision = env.GERRIT_BRANCH | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 181 |         } | 
| Denis Egorenko | 60e45c1 | 2018-11-12 12:00:11 +0400 | [diff] [blame] | 182 |         messages.add("COOKIECUTTER_TEMPLATE_BRANCH => ${gerritDataCC['gerritBranch']}") | 
 | 183 |         messages.add("RECLASS_SYSTEM_BRANCH => ${gerritDataRS['gerritBranch']}") | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 184 |         // Identify, who triggered. To whom we should pass refspec | 
 | 185 |         if (env.GERRIT_PROJECT == 'salt-models/reclass-system') { | 
 | 186 |             gerritDataRS['gerritRefSpec'] = env.GERRIT_REFSPEC | 
 | 187 |             gerritDataRS['GERRIT_CHANGE_NUMBER'] = env.GERRIT_CHANGE_NUMBER | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 188 |             messages.add("RECLASS_SYSTEM_GIT_REF => ${gerritDataRS['gerritRefSpec']}") | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 189 |         } else if (env.GERRIT_PROJECT == 'mk/cookiecutter-templates') { | 
 | 190 |             gerritDataCC['gerritRefSpec'] = env.GERRIT_REFSPEC | 
 | 191 |             gerritDataCC['GERRIT_CHANGE_NUMBER'] = env.GERRIT_CHANGE_NUMBER | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 192 |             messages.add("COOKIECUTTER_TEMPLATE_REF => ${gerritDataCC['gerritRefSpec']}") | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 193 |         } else { | 
 | 194 |             error("Unsuported gerrit-project triggered:${env.GERRIT_PROJECT}") | 
 | 195 |         } | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 196 |     } else { | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 197 |         messages.add("<font color='red'>Non-gerrit trigger run detected!</font>") | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 198 |     } | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 199 |     gerritDataCCHEAD << gerritDataCC | 
 | 200 |     gerritDataCCHEAD['gerritRefSpec'] = null | 
 | 201 |     gerritDataCCHEAD['GERRIT_CHANGE_NUMBER'] = null | 
 | 202 |     gerritDataRSHEAD << gerritDataRS | 
 | 203 |     gerritDataRSHEAD['gerritRefSpec'] = null | 
 | 204 |     gerritDataRSHEAD['GERRIT_CHANGE_NUMBER'] = null | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 205 |     // 'binary' branch logic w\o 'release/' prefix | 
 | 206 |     if (testDistribRevision.contains('/')) { | 
 | 207 |         testDistribRevision = testDistribRevision.split('/')[-1] | 
 | 208 |     } | 
 | 209 |     // Check if we are going to test bleeding-edge release, which doesn't have binary release yet | 
| azvyagintsev | 5c200e7 | 2018-12-28 15:58:09 +0200 | [diff] [blame] | 210 |     // After 2018q4 releases, need to also check 'static' repo, for example ubuntu. | 
| azvyagintsev | 4220bff | 2019-01-09 21:32:11 +0200 | [diff] [blame] | 211 |     binTest = common.checkRemoteBinary(['mcp_version': testDistribRevision]) | 
| azvyagintsev | 5c200e7 | 2018-12-28 15:58:09 +0200 | [diff] [blame] | 212 |     if (!binTest.linux_system_repo_url || !binTest.linux_system_repo_ubuntu_url) { | 
 | 213 |         common.errorMsg("Binary release: ${testDistribRevision} not exist or not full. Fallback to 'proposed'! ") | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 214 |         testDistribRevision = 'proposed' | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 215 |         messages.add("DISTRIB_REVISION => ${testDistribRevision}") | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 216 |     } | 
| Denis Egorenko | fe9a336 | 2018-10-17 15:33:25 +0400 | [diff] [blame] | 217 |     def message = messages.join(newline) + newline | 
| azvyagintsev | 458278c | 2018-09-25 18:38:30 +0300 | [diff] [blame] | 218 |     currentBuild.description = currentBuild.description ? message + currentBuild.description : message | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 219 | } | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 220 |  | 
| Denis Egorenko | a6117fc | 2018-09-11 13:40:00 +0400 | [diff] [blame] | 221 | def replaceGeneratedValues(path) { | 
 | 222 |     def files = sh(script: "find ${path} -name 'secrets.yml'", returnStdout: true) | 
 | 223 |     def stepsForParallel = [:] | 
 | 224 |     stepsForParallel.failFast = true | 
 | 225 |     files.tokenize().each { | 
 | 226 |         stepsForParallel.put("Removing generated passwords/secrets from ${it}", | 
 | 227 |             { | 
 | 228 |                 def secrets = readYaml file: it | 
| azvyagintsev | 08b34e3 | 2018-09-12 12:29:42 +0300 | [diff] [blame] | 229 |                 for (String key in secrets['parameters']['_param'].keySet()) { | 
| Denis Egorenko | a6117fc | 2018-09-11 13:40:00 +0400 | [diff] [blame] | 230 |                     secrets['parameters']['_param'][key] = 'generated' | 
 | 231 |                 } | 
 | 232 |                 // writeYaml can't write to already existing file | 
 | 233 |                 writeYaml file: "${it}.tmp", data: secrets | 
 | 234 |                 sh "mv ${it}.tmp ${it}" | 
 | 235 |             }) | 
 | 236 |     } | 
 | 237 |     parallel stepsForParallel | 
 | 238 | } | 
 | 239 |  | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 240 | def linkReclassModels(contextList, envPath, archiveName) { | 
 | 241 |     // to be able share reclass for all subenvs | 
 | 242 |     // Also, makes artifact test more solid - use one reclass for all of sub-models. | 
 | 243 |     // Archive Structure will be: | 
 | 244 |     // tar.gz | 
 | 245 |     // ├── contexts | 
 | 246 |     // │   └── ceph.yml | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 247 |     // ├── classes-system <<< reclass system | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 248 |     // ├── model | 
 | 249 |     // │   └── ceph       <<< from `context basename` | 
 | 250 |     // │       ├── classes | 
 | 251 |     // │       │   ├── cluster | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 252 |     // │       │   └── system -> ../../../classes-system | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 253 |     // │       └── nodes | 
 | 254 |     // │           └── cfg01.ceph-cluster-domain.local.yml | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 255 |     def archiveBaseName = common.GetBaseName(archiveName, '.tar.gz') | 
 | 256 |     def classesSystemDir = 'classes-system' | 
 | 257 |     // copy reclass system under envPath with -R and trailing / to support symlinks direct copy | 
 | 258 |     sh("cp -R ${archiveBaseName}/ ${envPath}/${classesSystemDir}") | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 259 |     dir(envPath) { | 
 | 260 |         for (String context : contextList) { | 
 | 261 |             def basename = common.GetBaseName(context, '.yml') | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 262 |             dir("${envPath}/model/${basename}/classes") { | 
 | 263 |                 sh(script: "ln -sfv ../../../${classesSystemDir} system ") | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 264 |             } | 
 | 265 |         } | 
| Denis Egorenko | a6117fc | 2018-09-11 13:40:00 +0400 | [diff] [blame] | 266 |         // replace all generated passwords/secrets/keys with hardcode value for infra/secrets.yaml | 
 | 267 |         replaceGeneratedValues("${envPath}/model") | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 268 |         // Save all models and all contexts. Warning! `h` flag must be used! | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 269 |         sh(script: "set -ex; tar -czhf ${env.WORKSPACE}/${archiveName} --exclude='*@tmp' contexts model ${classesSystemDir}", returnStatus: true) | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 270 |     } | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 271 |     archiveArtifacts artifacts: archiveName | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 272 | } | 
 | 273 |  | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 274 | timeout(time: 1, unit: 'HOURS') { | 
 | 275 |     node(slaveNode) { | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 276 |         globalVariatorsUpdate() | 
| azvyagintsev | 30bc82e | 2018-08-22 12:26:06 +0300 | [diff] [blame] | 277 |         def templateEnvHead = "${env.WORKSPACE}/EnvHead/" | 
 | 278 |         def templateEnvPatched = "${env.WORKSPACE}/EnvPatched/" | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 279 |         def contextFileListHead = [] | 
 | 280 |         def contextFileListPatched = [] | 
 | 281 |         def vEnv = "${env.WORKSPACE}/venv" | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 282 |         def headReclassArtifactName = "head_reclass.tar.gz" | 
 | 283 |         def patchedReclassArtifactName = "patched_reclass.tar.gz" | 
 | 284 |         def reclassNodeInfoDir = "${env.WORKSPACE}/reclassNodeInfo_compare/" | 
 | 285 |         def reclassInfoHeadPath = "${reclassNodeInfoDir}/old" | 
 | 286 |         def reclassInfoPatchedPath = "${reclassNodeInfoDir}/new" | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 287 |         try { | 
 | 288 |             sh(script: 'find . -mindepth 1 -delete > /dev/null || true') | 
 | 289 |             stage('Download and prepare CC env') { | 
 | 290 |                 // Prepare 2 env - for patchset, and for HEAD | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 291 |                 def paralellEnvs = [:] | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 292 |                 paralellEnvs.failFast = true | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 293 |                 paralellEnvs['downloadEnvHead'] = StepPrepareGit(templateEnvHead, gerritDataCCHEAD) | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 294 |                 if (gerritDataCC.get('gerritRefSpec', null)) { | 
 | 295 |                     paralellEnvs['downloadEnvPatched'] = StepPrepareGit(templateEnvPatched, gerritDataCC) | 
 | 296 |                     parallel paralellEnvs | 
 | 297 |                 } else { | 
 | 298 |                     paralellEnvs['downloadEnvPatched'] = { common.warningMsg('No need to process: downloadEnvPatched') } | 
 | 299 |                     parallel paralellEnvs | 
 | 300 |                     sh("rsync -a --exclude '*@tmp' ${templateEnvHead} ${templateEnvPatched}") | 
 | 301 |                 } | 
| Denis Egorenko | 3de070c | 2018-11-20 13:57:35 +0400 | [diff] [blame] | 302 |                 if (env.CUSTOM_COOKIECUTTER_CONTEXT) { | 
 | 303 |                     // readYaml to check custom context structure | 
 | 304 |                     def customContext = readYaml text: env.CUSTOM_COOKIECUTTER_CONTEXT | 
 | 305 |                     writeYaml file: "${templateEnvHead}/contexts/custom_context.yml", data: customContext | 
 | 306 |                     writeYaml file: "${templateEnvPatched}/contexts/custom_context.yml", data: customContext | 
 | 307 |                     common.infoMsg("Using custom context provided from job parameter 'CUSTOM_COOKIECUTTER_CONTEXT'") | 
 | 308 |                 } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 309 |             } | 
| azvyagintsev | 8ab34fd | 2019-01-10 15:32:26 +0200 | [diff] [blame] | 310 |             stage('Check workflow_definition') { | 
 | 311 |                 // Prepare venv for old env's, aka non-tox based | 
 | 312 |                 if (!fileExists(new File(templateEnvPatched, 'tox.ini').toString()) || !fileExists(new File(templateEnvHead, 'tox.ini').toString())) { | 
 | 313 |                     python.setupVirtualenv(vEnv, 'python2', [], "${templateEnvPatched}/requirements.txt") | 
 | 314 |                 } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 315 |                 // Check only for patchset | 
| azvyagintsev | 1037fb4 | 2019-01-10 13:52:38 +0200 | [diff] [blame] | 316 |                 if (fileExists(new File(templateEnvPatched, 'tox.ini').toString())) { | 
 | 317 |                     dir(templateEnvPatched) { | 
 | 318 |                         output = sh(returnStdout: true, script: "tox -ve test") | 
 | 319 |                         common.infoMsg("[Cookiecutter test] Result: ${output}") | 
| azvyagintsev | 4220bff | 2019-01-09 21:32:11 +0200 | [diff] [blame] | 320 |                     } | 
| azvyagintsev | 1037fb4 | 2019-01-10 13:52:38 +0200 | [diff] [blame] | 321 |  | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 322 |                 } else { | 
| azvyagintsev | 1037fb4 | 2019-01-10 13:52:38 +0200 | [diff] [blame] | 323 |                     common.warningMsg('Old Cookiecutter env detected!') | 
| azvyagintsev | 1037fb4 | 2019-01-10 13:52:38 +0200 | [diff] [blame] | 324 |                     common.infoMsg(python.runVirtualenvCommand(vEnv, "python ${templateEnvPatched}/workflow_definition_test.py")) | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 325 |                 } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 326 |             } | 
 | 327 |  | 
| azvyagintsev | 8ab34fd | 2019-01-10 15:32:26 +0200 | [diff] [blame] | 328 |             stage('generate models') { | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 329 |                 dir("${templateEnvHead}/contexts") { | 
 | 330 |                     for (String x : findFiles(glob: "*.yml")) { | 
 | 331 |                         contextFileListHead.add(x) | 
 | 332 |                     } | 
 | 333 |                 } | 
 | 334 |                 dir("${templateEnvPatched}/contexts") { | 
 | 335 |                     for (String x : findFiles(glob: "*.yml")) { | 
 | 336 |                         contextFileListPatched.add(x) | 
 | 337 |                     } | 
 | 338 |                 } | 
 | 339 |                 // Generate over 2env's - for patchset, and for HEAD | 
| azvyagintsev | 9df82e5 | 2018-09-06 19:17:18 +0300 | [diff] [blame] | 340 |                 def paralellEnvs = [:] | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 341 |                 paralellEnvs.failFast = true | 
| azvyagintsev | 30bc82e | 2018-08-22 12:26:06 +0300 | [diff] [blame] | 342 |                 paralellEnvs['GenerateEnvHead'] = StepGenerateModels(contextFileListHead, vEnv, templateEnvHead) | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 343 |                 if (gerritDataCC.get('gerritRefSpec', null)) { | 
 | 344 |                     paralellEnvs['GenerateEnvPatched'] = StepGenerateModels(contextFileListPatched, vEnv, templateEnvPatched) | 
 | 345 |                     parallel paralellEnvs | 
 | 346 |                 } else { | 
 | 347 |                     paralellEnvs['GenerateEnvPatched'] = { common.warningMsg('No need to process: GenerateEnvPatched') } | 
 | 348 |                     parallel paralellEnvs | 
 | 349 |                     sh("rsync -a --exclude '*@tmp' ${templateEnvHead} ${templateEnvPatched}") | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 350 |                 } | 
 | 351 |  | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 352 |                 // We need 2 git's, one for HEAD, one for PATCHed. | 
 | 353 |                 // if no patch, use head for both | 
 | 354 |                 RSHeadDir = common.GetBaseName(headReclassArtifactName, '.tar.gz') | 
 | 355 |                 RSPatchedDir = common.GetBaseName(patchedReclassArtifactName, '.tar.gz') | 
 | 356 |                 common.infoMsg("gerritDataRS= ${gerritDataRS}") | 
 | 357 |                 common.infoMsg("gerritDataRSHEAD= ${gerritDataRSHEAD}") | 
 | 358 |                 if (gerritDataRS.get('gerritRefSpec', null)) { | 
 | 359 |                     StepPrepareGit("${env.WORKSPACE}/${RSPatchedDir}/", gerritDataRS).call() | 
 | 360 |                     StepPrepareGit("${env.WORKSPACE}/${RSHeadDir}/", gerritDataRSHEAD).call() | 
 | 361 |                 } else { | 
 | 362 |                     StepPrepareGit("${env.WORKSPACE}/${RSHeadDir}/", gerritDataRS).call() | 
 | 363 |                     sh("cd ${env.WORKSPACE} ; ln -svf ${RSHeadDir} ${RSPatchedDir}") | 
 | 364 |                 } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 365 |                 // link all models, to use one global reclass | 
 | 366 |                 // For HEAD | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 367 |                 linkReclassModels(contextFileListHead, templateEnvHead, headReclassArtifactName) | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 368 |                 // For patched | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 369 |                 linkReclassModels(contextFileListPatched, templateEnvPatched, patchedReclassArtifactName) | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 370 |             } | 
 | 371 |  | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 372 |             stage("Compare cluster lvl Head/Patched") { | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 373 |                 // Compare patched and HEAD reclass pillars | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 374 |                 compareRoot = "${env.WORKSPACE}/cluster_compare/" | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 375 |                 // extract archive and drop all copied classes/system before comparing | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 376 |                 sh(script: """ | 
 | 377 |                    mkdir -pv ${compareRoot}/new ${compareRoot}/old | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 378 |                    tar -xzf ${patchedReclassArtifactName}  --directory ${compareRoot}/new | 
 | 379 |                    tar -xzf ${headReclassArtifactName}  --directory ${compareRoot}/old | 
| Denis Egorenko | 7aa5ac5 | 2018-10-17 15:14:56 +0400 | [diff] [blame] | 380 |                    find ${compareRoot} -name classes -type d -exec rm -rf '{}/system' \\; | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 381 |                    """) | 
 | 382 |                 common.warningMsg('infra/secrets.yml has been skipped from compare!') | 
| azvyagintsev | 3a80e34 | 2018-09-19 19:22:48 +0300 | [diff] [blame] | 383 |                 result = '\n' + common.comparePillars(compareRoot, env.BUILD_URL, "-Ev \'infra/secrets.yml|\\.git\'") | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 384 |                 currentBuild.description = currentBuild.description ? currentBuild.description + result : result | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 385 |             } | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 386 |             stage("TestContexts Head/Patched") { | 
 | 387 |                 def stepsForParallel = [:] | 
 | 388 |                 stepsForParallel.failFast = true | 
 | 389 |                 common.infoMsg("Found: ${contextFileListHead.size()} HEAD contexts to test.") | 
 | 390 |                 for (String context : contextFileListHead) { | 
 | 391 |                     def basename = common.GetBaseName(context, '.yml') | 
 | 392 |                     stepsForParallel.put("ContextHeadTest:${basename}", StepTestModel(basename, headReclassArtifactName, reclassInfoHeadPath)) | 
 | 393 |                 } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 394 |                 common.infoMsg("Found: ${contextFileListPatched.size()} patched contexts to test.") | 
 | 395 |                 for (String context : contextFileListPatched) { | 
 | 396 |                     def basename = common.GetBaseName(context, '.yml') | 
| Denis Egorenko | 086aff1 | 2018-10-18 17:54:59 +0400 | [diff] [blame] | 397 |                     stepsForParallel.put("ContextPatchedTest:${basename}", StepTestModel(basename, patchedReclassArtifactName, reclassInfoPatchedPath, true)) | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 398 |                 } | 
 | 399 |                 parallel stepsForParallel | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 400 |                 common.infoMsg('All TestContexts tests done') | 
 | 401 |             } | 
 | 402 |             stage("Compare NodesInfo Head/Patched") { | 
 | 403 |                 // Download all artifacts | 
 | 404 |                 def stepsForParallel = [:] | 
 | 405 |                 stepsForParallel.failFast = true | 
 | 406 |                 common.infoMsg("Found: ${testModelBuildsData.size()} nodeinfo artifacts to download.") | 
 | 407 |                 testModelBuildsData.each { bname, bdata -> | 
 | 408 |                     stepsForParallel.put("FetchData:${bname}", | 
 | 409 |                         getAndUnpackNodesInfoArtifact(bdata.jobname, bdata.copyToDir, bdata.buildId)) | 
 | 410 |                 } | 
 | 411 |                 parallel stepsForParallel | 
| Denis Egorenko | a6117fc | 2018-09-11 13:40:00 +0400 | [diff] [blame] | 412 |                 // remove timestamp field from rendered files | 
 | 413 |                 sh("find ${reclassNodeInfoDir} -type f -exec sed -i '/  timestamp: .*/d' {} \\;") | 
| Denis Egorenko | d874894 | 2018-09-07 12:26:20 +0400 | [diff] [blame] | 414 |                 // Compare patched and HEAD reclass pillars | 
 | 415 |                 result = '\n' + common.comparePillars(reclassNodeInfoDir, env.BUILD_URL, '') | 
 | 416 |                 currentBuild.description = currentBuild.description ? currentBuild.description + result : result | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 417 |             } | 
| Denis Egorenko | 04ca9f2 | 2018-09-19 16:06:49 +0400 | [diff] [blame] | 418 |             stage('Check include order') { | 
| azvyagintsev | e7b8e79 | 2018-09-21 17:27:01 +0300 | [diff] [blame] | 419 |                 if (!checkIncludeOrder) { | 
 | 420 |                     common.infoMsg('Check include order require to much time, and currently disabled!') | 
 | 421 |  | 
 | 422 |                 } else { | 
 | 423 |                     def correctIncludeOrder = ["service", "system", "cluster"] | 
 | 424 |                     dir(reclassInfoPatchedPath) { | 
 | 425 |                         def nodeInfoFiles = findFiles(glob: "**/*.reclass.nodeinfo") | 
 | 426 |                         def messages = ["<b>Wrong include ordering found</b><ul>"] | 
 | 427 |                         def stepsForParallel = [:] | 
 | 428 |                         nodeInfoFiles.each { nodeInfo -> | 
 | 429 |                             stepsForParallel.put("Checking ${nodeInfo.path}:", { | 
 | 430 |                                 def node = readYaml file: nodeInfo.path | 
 | 431 |                                 def classes = node['classes'] | 
 | 432 |                                 def curClassID = 0 | 
 | 433 |                                 def prevClassID = 0 | 
 | 434 |                                 def wrongOrder = false | 
 | 435 |                                 for (String className in classes) { | 
 | 436 |                                     def currentClass = className.tokenize('.')[0] | 
 | 437 |                                     curClassID = correctIncludeOrder.indexOf(currentClass) | 
 | 438 |                                     if (currentClass != correctIncludeOrder[prevClassID]) { | 
 | 439 |                                         if (prevClassID > curClassID) { | 
 | 440 |                                             wrongOrder = true | 
 | 441 |                                             common.warningMsg("File ${nodeInfo.path} contains wrong order of classes including: Includes for ${className} should be declared before ${correctIncludeOrder[prevClassID]} includes") | 
 | 442 |                                         } else { | 
 | 443 |                                             prevClassID = curClassID | 
 | 444 |                                         } | 
| Denis Egorenko | 04ca9f2 | 2018-09-19 16:06:49 +0400 | [diff] [blame] | 445 |                                     } | 
 | 446 |                                 } | 
| azvyagintsev | e7b8e79 | 2018-09-21 17:27:01 +0300 | [diff] [blame] | 447 |                                 if (wrongOrder) { | 
 | 448 |                                     messages.add("<li>${nodeInfo.path} contains wrong order of classes including</li>") | 
 | 449 |                                 } | 
 | 450 |                             }) | 
 | 451 |                         } | 
 | 452 |                         parallel stepsForParallel | 
 | 453 |                         def includerOrder = '<b>No wrong include order</b>' | 
 | 454 |                         if (messages.size() != 1) { | 
 | 455 |                             includerOrder = messages.join('') | 
 | 456 |                         } | 
 | 457 |                         currentBuild.description = currentBuild.description ? currentBuild.description + includerOrder : includerOrder | 
| Denis Egorenko | 04ca9f2 | 2018-09-19 16:06:49 +0400 | [diff] [blame] | 458 |                     } | 
| Denis Egorenko | 04ca9f2 | 2018-09-19 16:06:49 +0400 | [diff] [blame] | 459 |                 } | 
 | 460 |             } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 461 |             sh(script: 'find . -mindepth 1 -delete > /dev/null || true') | 
 | 462 |  | 
 | 463 |         } catch (Throwable e) { | 
 | 464 |             currentBuild.result = "FAILURE" | 
 | 465 |             currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message | 
 | 466 |             throw e | 
 | 467 |         } finally { | 
| Denis Egorenko | 34c4a3b | 2019-03-12 12:48:15 +0400 | [diff] [blame] | 468 |             stage('Save artifacts to Artifactory') { | 
 | 469 |                 def artifactory = new com.mirantis.mcp.MCPArtifactory() | 
 | 470 |                 def artifactoryLink = artifactory.uploadJobArtifactsToArtifactory(['artifactory': 'mcp-ci', 'artifactoryRepo': "drivetrain-local/${JOB_NAME}/${BUILD_NUMBER}"]) | 
 | 471 |                 currentBuild.description += "<br/>${artifactoryLink}" | 
 | 472 |             } | 
| azvyagintsev | 5c0313d | 2018-08-13 17:13:35 +0300 | [diff] [blame] | 473 |         } | 
 | 474 |     } | 
| chnyda | e80bb92 | 2017-05-29 17:48:40 +0200 | [diff] [blame] | 475 | } |