Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 1 | /** |
| 2 | * |
| 3 | * Update Salt environment pipeline |
| 4 | * |
| 5 | * Expected parameters: |
| 6 | * SALT_MASTER_URL Salt API server location |
| 7 | * SALT_MASTER_CREDENTIALS Credentials to the Salt API |
| 8 | * MCP_VERSION Version of MCP to upgrade to |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 9 | * UPGRADE_SALTSTACK Upgrade SaltStack packages to new version. |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 10 | * UPDATE_CLUSTER_MODEL Update MCP version parameter in cluster model |
| 11 | * UPDATE_PIPELINES Update pipeline repositories on Gerrit |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 12 | * UPDATE_LOCAL_REPOS Update local repositories |
| 13 | */ |
| 14 | |
| 15 | // Load shared libs |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 16 | salt = new com.mirantis.mk.Salt() |
| 17 | common = new com.mirantis.mk.Common() |
| 18 | python = new com.mirantis.mk.Python() |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 19 | jenkinsUtils = new com.mirantis.mk.JenkinsUtils() |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 20 | venvPepper = "venvPepper" |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 21 | workspace = "" |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 22 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 23 | def triggerMirrorJob(jobName){ |
| 24 | params = jenkinsUtils.getJobParameters(jobName) |
| 25 | build job: jobName, parameters: [ |
| 26 | [$class: 'StringParameterValue', name: 'BRANCHES', value: params.get("BRANCHES")], |
| 27 | [$class: 'StringParameterValue', name: 'CREDENTIALS_ID', value: params.get("CREDENTIALS_ID")], |
| 28 | [$class: 'StringParameterValue', name: 'SOURCE_URL', value: params.get("SOURCE_URL")], |
| 29 | [$class: 'StringParameterValue', name: 'TARGET_URL', value: params.get("TARGET_URL")] |
| 30 | ] |
| 31 | } |
| 32 | |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 33 | def updateSaltStack(target, pkgs){ |
| 34 | try{ |
| 35 | salt.runSaltProcessStep(venvPepper, target, 'pkg.install', ["force_yes=True", "pkgs='$pkgs'"], null, true, 5) |
| 36 | }catch(Exception ex){} |
| 37 | |
| 38 | common.retry(10, 30){ |
| 39 | salt.minionsReachable(venvPepper, 'I@salt:master', '*') |
| 40 | def running = salt.runSaltProcessStep(venvPepper, target, 'saltutil.running', [], null, true, 5) |
| 41 | for(value in running.get("return")[0].values()){ |
| 42 | if(value != []){ |
| 43 | throw new Exception("Not all salt-minions are ready for execution") |
| 44 | } |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | def saltVersion = salt.getPillar(venvPepper, 'I@salt:master', "_param:salt_version").get("return")[0].values()[0] |
Richard Felkl | f23257e | 2018-08-06 09:24:23 +0200 | [diff] [blame] | 49 | def saltMinionVersions = salt.cmdRun(venvPepper, target, "apt-cache policy salt-common | awk '/Installed/ && /$saltVersion/'").get("return") |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 50 | def saltMinionVersion = "" |
| 51 | |
| 52 | for(minion in saltMinionVersions[0].keySet()){ |
| 53 | saltMinionVersion = saltMinionVersions[0].get(minion).replace("Salt command execution success","").trim() |
| 54 | if(saltMinionVersion == ""){ |
| 55 | error("Installed version of Salt on $minion doesn't match specified version in the model.") |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | def archiveReclassInventory(filename){ |
| 61 | def ret = salt.cmdRun(venvPepper, 'I@salt:master', "reclass -i", true, null, false) |
| 62 | def reclassInv = ret.values()[0] |
| 63 | writeFile file: filename, text: reclassInv.toString() |
| 64 | archiveArtifacts artifacts: "$filename" |
| 65 | } |
| 66 | |
Martin Polreich | 965c903 | 2018-08-09 16:33:57 +0200 | [diff] [blame] | 67 | def pipelineTimeout = 12 |
| 68 | if (common.validInputParam('PIPELINE_TIMEOUT') && PIPELINE_TIMEOUT.isInteger()) { |
| 69 | pipelineTimeout = "${PIPELINE_TIMEOUT}".toInteger() |
| 70 | } |
| 71 | |
| 72 | timeout(time: pipelineTimeout, unit: 'HOURS') { |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 73 | node("python") { |
| 74 | try { |
Richard Felkl | 65e3837 | 2018-07-30 11:46:43 +0200 | [diff] [blame] | 75 | def gitMcpVersion = MCP_VERSION |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 76 | workspace = common.getWorkspace() |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 77 | python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS) |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 78 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 79 | if(MCP_VERSION == ""){ |
| 80 | error("You must specify MCP version") |
| 81 | } |
Richard Felkl | 65e3837 | 2018-07-30 11:46:43 +0200 | [diff] [blame] | 82 | if(MCP_VERSION == "testing"){ |
| 83 | gitMcpVersion = "master" |
| 84 | } |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 85 | |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 86 | stage("Update Reclass"){ |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 87 | def cluster_name = salt.getPillar(venvPepper, 'I@salt:master', "_param:cluster_name").get("return")[0].values()[0] |
| 88 | if(UPDATE_CLUSTER_MODEL.toBoolean()){ |
| 89 | try{ |
| 90 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/ && git diff-index --quiet HEAD --") |
| 91 | } |
| 92 | catch(Exception ex){ |
| 93 | error("You have uncommited changes in your Reclass cluster model repository. Please commit or reset them and rerun the pipeline.") |
| 94 | } |
Martin Polreich | 4d606f5 | 2018-08-06 10:40:11 +0200 | [diff] [blame] | 95 | def dateTime = common.getDatetime() |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 96 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name && grep -r --exclude-dir=aptly -l 'apt_mk_version: .*' * | xargs sed -i 's/apt_mk_version: .*/apt_mk_version: \"$MCP_VERSION\"/g'") |
Martin Polreich | 4d606f5 | 2018-08-06 10:40:11 +0200 | [diff] [blame] | 97 | common.infoMsg("The following changes were made to the cluster model and will be commited. Please consider if you want to push them to the remote repository or not. You have to do this manually when the run is finished.") |
| 98 | salt.cmdRun(venvPepper, 'I@salt.master', "cd /srv/salt/reclass/classes/cluster/$cluster_name && git diff") |
| 99 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name && git status && git add -u && git commit -m 'Cluster model update to the release $MCP_VERSION on $dateTime'") |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | try{ |
| 103 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git diff-index --quiet HEAD --") |
| 104 | } |
| 105 | catch(Exception ex){ |
| 106 | error("You have unstaged changes in your Reclass system model repository. Please reset them and rerun the pipeline.") |
| 107 | } |
Richard Felkl | 65e3837 | 2018-07-30 11:46:43 +0200 | [diff] [blame] | 108 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git checkout $gitMcpVersion") |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 109 | } |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 110 | |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 111 | if(UPDATE_LOCAL_REPOS.toBoolean()){ |
| 112 | stage("Update local repos"){ |
| 113 | common.infoMsg("Updating local repositories") |
Sam Stoelinga | aab7970 | 2018-04-09 18:49:39 -0700 | [diff] [blame] | 114 | |
| 115 | def engine = salt.getPillar(venvPepper, 'I@aptly:server', "aptly:server:source:engine") |
| 116 | runningOnDocker = engine.get("return")[0].containsValue("docker") |
| 117 | |
| 118 | if (runningOnDocker) { |
| 119 | common.infoMsg("Aptly is running as Docker container") |
| 120 | } |
| 121 | else { |
| 122 | common.infoMsg("Aptly isn't running as Docker container. Going to use aptly user for executing aptly commands") |
| 123 | } |
| 124 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 125 | salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name/cicd/aptly && git checkout $MCP_VERSION") |
| 126 | |
Sam Stoelinga | aab7970 | 2018-04-09 18:49:39 -0700 | [diff] [blame] | 127 | if(runningOnDocker){ |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 128 | salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true) |
| 129 | } |
| 130 | else{ |
| 131 | salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true, ['runas=aptly']) |
| 132 | } |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 133 | |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 134 | salt.enforceState(venvPepper, 'I@aptly:server', 'aptly', true) |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 135 | |
Sam Stoelinga | aab7970 | 2018-04-09 18:49:39 -0700 | [diff] [blame] | 136 | if(runningOnDocker){ |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 137 | salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv"], null, true) |
| 138 | salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-frv -u http://10.99.0.1:8080"], null, true) |
| 139 | } |
| 140 | else{ |
| 141 | salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true) |
| 142 | salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-afrv", 'runas=aptly'], null, true) |
| 143 | } |
Richard Felkl | 79d7df1 | 2018-01-05 16:40:11 +0100 | [diff] [blame] | 144 | |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 145 | salt.enforceState(venvPepper, 'I@aptly:server', 'docker.client.registry', true) |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 146 | |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 147 | salt.enforceState(venvPepper, 'I@aptly:server', 'debmirror', true) |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 148 | |
Richard Felkl | 5f7fdaf | 2018-02-15 15:38:31 +0100 | [diff] [blame] | 149 | salt.enforceState(venvPepper, 'I@aptly:server', 'git.server', true) |
| 150 | |
| 151 | salt.enforceState(venvPepper, 'I@aptly:server', 'linux.system.file', true) |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 152 | } |
| 153 | } |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 154 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 155 | stage("Update Drivetrain"){ |
| 156 | salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_salt.list") |
| 157 | salt.cmdRun(venvPepper, 'I@salt:master', "apt-get -o Dir::Etc::sourcelist='/etc/apt/sources.list.d/mcp_salt.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0' update") |
| 158 | salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades salt-formula-*") |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 159 | |
| 160 | def inventoryBeforeFilename = "reclass-inventory-before.out" |
| 161 | def inventoryAfterFilename = "reclass-inventory-after.out" |
| 162 | |
| 163 | archiveReclassInventory(inventoryBeforeFilename) |
| 164 | |
| 165 | salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_extra.list") |
| 166 | salt.cmdRun(venvPepper, 'I@salt:master', "apt-get -o Dir::Etc::sourcelist='/etc/apt/sources.list.d/mcp_extra.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0' update") |
| 167 | salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades reclass") |
| 168 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 169 | salt.fullRefresh(venvPepper, 'I@salt:master') |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 170 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 171 | try{ |
| 172 | salt.enforceState(venvPepper, "I@salt:master", 'reclass', true) |
| 173 | } |
| 174 | catch(Exception ex){ |
| 175 | error("Reclass fails rendering. Pay attention to your cluster model.") |
| 176 | } |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 177 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 178 | salt.fullRefresh(venvPepper, '*') |
| 179 | |
| 180 | try{ |
| 181 | salt.cmdRun(venvPepper, 'I@salt:master', "reclass-salt --top") |
| 182 | } |
| 183 | catch(Exception ex){ |
| 184 | error("Reclass fails rendering. Pay attention to your cluster model.") |
| 185 | } |
| 186 | |
Richard Felkl | 0e80d89 | 2018-06-20 13:44:54 +0200 | [diff] [blame] | 187 | archiveReclassInventory(inventoryAfterFilename) |
| 188 | |
| 189 | sh "diff -u $inventoryBeforeFilename $inventoryAfterFilename > reclass-inventory-diff.out || true" |
| 190 | archiveArtifacts artifacts: "reclass-inventory-diff.out" |
| 191 | |
| 192 | if(UPGRADE_SALTSTACK.toBoolean()){ |
| 193 | salt.enforceState(venvPepper, "I@linux:system", 'linux.system.repo', true) |
| 194 | |
| 195 | updateSaltStack("I@salt:master", '["salt-master", "salt-common", "salt-api", "salt-minion"]') |
| 196 | |
| 197 | updateSaltStack("I@salt:minion and not I@salt:master", '["salt-minion"]') |
| 198 | } |
| 199 | |
Richard Felkl | 970e008 | 2018-06-12 18:00:51 +0200 | [diff] [blame] | 200 | if(UPDATE_PIPELINES.toBoolean()){ |
| 201 | triggerMirrorJob("git-mirror-downstream-mk-pipelines") |
| 202 | triggerMirrorJob("git-mirror-downstream-pipeline-library") |
| 203 | } |
| 204 | |
| 205 | salt.enforceState(venvPepper, "I@jenkins:client", 'jenkins.client', true) |
| 206 | |
| 207 | salt.cmdRun(venvPepper, "I@salt:master", "salt -C 'I@jenkins:client and I@docker:client' state.sls docker.client --async") |
| 208 | |
| 209 | sleep(180) |
| 210 | |
| 211 | common.infoMsg("Checking if Docker containers are up") |
| 212 | |
| 213 | try{ |
| 214 | common.retry(10, 30){ |
| 215 | salt.cmdRun(venvPepper, 'I@jenkins:client and I@docker:client', "! docker service ls | tail -n +2 | grep -v -E '\\s([0-9])/\\1\\s'") |
| 216 | } |
| 217 | } |
| 218 | catch(Exception ex){ |
| 219 | error("Docker containers for CI/CD services are having troubles with starting.") |
| 220 | } |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 221 | } |
| 222 | } |
Jakub Josef | a63f986 | 2018-01-11 17:58:38 +0100 | [diff] [blame] | 223 | catch (Throwable e) { |
| 224 | // If there was an error or exception thrown, the build failed |
| 225 | currentBuild.result = "FAILURE" |
| 226 | throw e |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 227 | } |
Richard Felkl | 26cae4d | 2017-12-19 00:19:16 +0100 | [diff] [blame] | 228 | } |
Jakub Josef | 2c21c6c | 2018-02-08 18:51:42 +0100 | [diff] [blame] | 229 | } |