blob: 08796c967252d4a578c04ce7afc12f23a5f83947 [file] [log] [blame]
Richard Felkl26cae4d2017-12-19 00:19:16 +01001/**
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 Felkl0e80d892018-06-20 13:44:54 +02009 * UPGRADE_SALTSTACK Upgrade SaltStack packages to new version.
Richard Felkl970e0082018-06-12 18:00:51 +020010 * UPDATE_CLUSTER_MODEL Update MCP version parameter in cluster model
11 * UPDATE_PIPELINES Update pipeline repositories on Gerrit
Richard Felkl26cae4d2017-12-19 00:19:16 +010012 * UPDATE_LOCAL_REPOS Update local repositories
13 */
14
15// Load shared libs
Richard Felkl5f7fdaf2018-02-15 15:38:31 +010016salt = new com.mirantis.mk.Salt()
17common = new com.mirantis.mk.Common()
18python = new com.mirantis.mk.Python()
Richard Felkl970e0082018-06-12 18:00:51 +020019jenkinsUtils = new com.mirantis.mk.JenkinsUtils()
Richard Felkl5f7fdaf2018-02-15 15:38:31 +010020venvPepper = "venvPepper"
Richard Felkl0e80d892018-06-20 13:44:54 +020021workspace = ""
Richard Felkl5f7fdaf2018-02-15 15:38:31 +010022
Richard Felkl970e0082018-06-12 18:00:51 +020023def 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 Felkl0e80d892018-06-20 13:44:54 +020033def 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]
49 def saltMinionVersions = salt.cmdRun(venvPepper, "*", "apt-cache policy salt-common | awk '/Installed/ && /$saltVersion/'").get("return")
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
60def 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
Jakub Josefa63f9862018-01-11 17:58:38 +010067timeout(time: 12, unit: 'HOURS') {
68 node("python") {
69 try {
Richard Felkl0e80d892018-06-20 13:44:54 +020070 workspace = common.getWorkspace()
Jakub Josefa63f9862018-01-11 17:58:38 +010071 python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Richard Felkl26cae4d2017-12-19 00:19:16 +010072
Richard Felkl970e0082018-06-12 18:00:51 +020073 if(MCP_VERSION == ""){
74 error("You must specify MCP version")
75 }
76
Jakub Josefa63f9862018-01-11 17:58:38 +010077 stage("Update Reclass"){
Richard Felkl970e0082018-06-12 18:00:51 +020078 def cluster_name = salt.getPillar(venvPepper, 'I@salt:master', "_param:cluster_name").get("return")[0].values()[0]
79 if(UPDATE_CLUSTER_MODEL.toBoolean()){
80 try{
81 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/ && git diff-index --quiet HEAD --")
82 }
83 catch(Exception ex){
84 error("You have uncommited changes in your Reclass cluster model repository. Please commit or reset them and rerun the pipeline.")
85 }
86 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'")
87 }
88
89 try{
90 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git diff-index --quiet HEAD --")
91 }
92 catch(Exception ex){
93 error("You have unstaged changes in your Reclass system model repository. Please reset them and rerun the pipeline.")
94 }
95 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git checkout $MCP_VERSION")
Jakub Josefa63f9862018-01-11 17:58:38 +010096 }
Richard Felkl26cae4d2017-12-19 00:19:16 +010097
Jakub Josefa63f9862018-01-11 17:58:38 +010098 if(UPDATE_LOCAL_REPOS.toBoolean()){
99 stage("Update local repos"){
100 common.infoMsg("Updating local repositories")
Sam Stoelingaaab79702018-04-09 18:49:39 -0700101
102 def engine = salt.getPillar(venvPepper, 'I@aptly:server', "aptly:server:source:engine")
103 runningOnDocker = engine.get("return")[0].containsValue("docker")
104
105 if (runningOnDocker) {
106 common.infoMsg("Aptly is running as Docker container")
107 }
108 else {
109 common.infoMsg("Aptly isn't running as Docker container. Going to use aptly user for executing aptly commands")
110 }
111
Richard Felkl970e0082018-06-12 18:00:51 +0200112 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name/cicd/aptly && git checkout $MCP_VERSION")
113
Sam Stoelingaaab79702018-04-09 18:49:39 -0700114 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100115 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true)
116 }
117 else{
118 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true, ['runas=aptly'])
119 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100120
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100121 salt.enforceState(venvPepper, 'I@aptly:server', 'aptly', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100122
Sam Stoelingaaab79702018-04-09 18:49:39 -0700123 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100124 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv"], null, true)
125 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)
126 }
127 else{
128 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true)
129 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-afrv", 'runas=aptly'], null, true)
130 }
Richard Felkl79d7df12018-01-05 16:40:11 +0100131
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100132 salt.enforceState(venvPepper, 'I@aptly:server', 'docker.client.registry', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100133
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100134 salt.enforceState(venvPepper, 'I@aptly:server', 'debmirror', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100135
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100136 salt.enforceState(venvPepper, 'I@aptly:server', 'git.server', true)
137
138 salt.enforceState(venvPepper, 'I@aptly:server', 'linux.system.file', true)
Jakub Josefa63f9862018-01-11 17:58:38 +0100139 }
140 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100141
Richard Felkl970e0082018-06-12 18:00:51 +0200142 stage("Update Drivetrain"){
143 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_salt.list")
144 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")
145 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades salt-formula-*")
Richard Felkl0e80d892018-06-20 13:44:54 +0200146
147 def inventoryBeforeFilename = "reclass-inventory-before.out"
148 def inventoryAfterFilename = "reclass-inventory-after.out"
149
150 archiveReclassInventory(inventoryBeforeFilename)
151
152 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_extra.list")
153 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")
154 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades reclass")
155
Richard Felkl970e0082018-06-12 18:00:51 +0200156 salt.fullRefresh(venvPepper, 'I@salt:master')
Jakub Josefa63f9862018-01-11 17:58:38 +0100157
Richard Felkl970e0082018-06-12 18:00:51 +0200158 try{
159 salt.enforceState(venvPepper, "I@salt:master", 'reclass', true)
160 }
161 catch(Exception ex){
162 error("Reclass fails rendering. Pay attention to your cluster model.")
163 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100164
Richard Felkl970e0082018-06-12 18:00:51 +0200165 salt.fullRefresh(venvPepper, '*')
166
167 try{
168 salt.cmdRun(venvPepper, 'I@salt:master', "reclass-salt --top")
169 }
170 catch(Exception ex){
171 error("Reclass fails rendering. Pay attention to your cluster model.")
172 }
173
Richard Felkl0e80d892018-06-20 13:44:54 +0200174 archiveReclassInventory(inventoryAfterFilename)
175
176 sh "diff -u $inventoryBeforeFilename $inventoryAfterFilename > reclass-inventory-diff.out || true"
177 archiveArtifacts artifacts: "reclass-inventory-diff.out"
178
179 if(UPGRADE_SALTSTACK.toBoolean()){
180 salt.enforceState(venvPepper, "I@linux:system", 'linux.system.repo', true)
181
182 updateSaltStack("I@salt:master", '["salt-master", "salt-common", "salt-api", "salt-minion"]')
183
184 updateSaltStack("I@salt:minion and not I@salt:master", '["salt-minion"]')
185 }
186
Richard Felkl970e0082018-06-12 18:00:51 +0200187 if(UPDATE_PIPELINES.toBoolean()){
188 triggerMirrorJob("git-mirror-downstream-mk-pipelines")
189 triggerMirrorJob("git-mirror-downstream-pipeline-library")
190 }
191
192 salt.enforceState(venvPepper, "I@jenkins:client", 'jenkins.client', true)
193
194 salt.cmdRun(venvPepper, "I@salt:master", "salt -C 'I@jenkins:client and I@docker:client' state.sls docker.client --async")
195
196 sleep(180)
197
198 common.infoMsg("Checking if Docker containers are up")
199
200 try{
201 common.retry(10, 30){
202 salt.cmdRun(venvPepper, 'I@jenkins:client and I@docker:client', "! docker service ls | tail -n +2 | grep -v -E '\\s([0-9])/\\1\\s'")
203 }
204 }
205 catch(Exception ex){
206 error("Docker containers for CI/CD services are having troubles with starting.")
207 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100208 }
209 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100210 catch (Throwable e) {
211 // If there was an error or exception thrown, the build failed
212 currentBuild.result = "FAILURE"
213 throw e
Richard Felkl26cae4d2017-12-19 00:19:16 +0100214 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100215 }
Jakub Josef2c21c6c2018-02-08 18:51:42 +0100216}