blob: fb291ab7fc978a1db32b85be3e3928a778fbc289 [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]
Richard Felklf23257e2018-08-06 09:24:23 +020049 def saltMinionVersions = salt.cmdRun(venvPepper, target, "apt-cache policy salt-common | awk '/Installed/ && /$saltVersion/'").get("return")
Richard Felkl0e80d892018-06-20 13:44:54 +020050 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 Felkl65e38372018-07-30 11:46:43 +020070 def gitMcpVersion = MCP_VERSION
Richard Felkl0e80d892018-06-20 13:44:54 +020071 workspace = common.getWorkspace()
Jakub Josefa63f9862018-01-11 17:58:38 +010072 python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Richard Felkl26cae4d2017-12-19 00:19:16 +010073
Richard Felkl970e0082018-06-12 18:00:51 +020074 if(MCP_VERSION == ""){
75 error("You must specify MCP version")
76 }
Richard Felkl65e38372018-07-30 11:46:43 +020077 if(MCP_VERSION == "testing"){
78 gitMcpVersion = "master"
79 }
Richard Felkl970e0082018-06-12 18:00:51 +020080
Jakub Josefa63f9862018-01-11 17:58:38 +010081 stage("Update Reclass"){
Richard Felkl970e0082018-06-12 18:00:51 +020082 def cluster_name = salt.getPillar(venvPepper, 'I@salt:master', "_param:cluster_name").get("return")[0].values()[0]
83 if(UPDATE_CLUSTER_MODEL.toBoolean()){
84 try{
85 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/ && git diff-index --quiet HEAD --")
86 }
87 catch(Exception ex){
88 error("You have uncommited changes in your Reclass cluster model repository. Please commit or reset them and rerun the pipeline.")
89 }
Martin Polreich4d606f52018-08-06 10:40:11 +020090 def dateTime = common.getDatetime()
Richard Felkl970e0082018-06-12 18:00:51 +020091 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 Polreich4d606f52018-08-06 10:40:11 +020092 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.")
93 salt.cmdRun(venvPepper, 'I@salt.master', "cd /srv/salt/reclass/classes/cluster/$cluster_name && git diff")
94 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 Felkl970e0082018-06-12 18:00:51 +020095 }
96
97 try{
98 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git diff-index --quiet HEAD --")
99 }
100 catch(Exception ex){
101 error("You have unstaged changes in your Reclass system model repository. Please reset them and rerun the pipeline.")
102 }
Richard Felkl65e38372018-07-30 11:46:43 +0200103 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git checkout $gitMcpVersion")
Jakub Josefa63f9862018-01-11 17:58:38 +0100104 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100105
Jakub Josefa63f9862018-01-11 17:58:38 +0100106 if(UPDATE_LOCAL_REPOS.toBoolean()){
107 stage("Update local repos"){
108 common.infoMsg("Updating local repositories")
Sam Stoelingaaab79702018-04-09 18:49:39 -0700109
110 def engine = salt.getPillar(venvPepper, 'I@aptly:server', "aptly:server:source:engine")
111 runningOnDocker = engine.get("return")[0].containsValue("docker")
112
113 if (runningOnDocker) {
114 common.infoMsg("Aptly is running as Docker container")
115 }
116 else {
117 common.infoMsg("Aptly isn't running as Docker container. Going to use aptly user for executing aptly commands")
118 }
119
Richard Felkl970e0082018-06-12 18:00:51 +0200120 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name/cicd/aptly && git checkout $MCP_VERSION")
121
Sam Stoelingaaab79702018-04-09 18:49:39 -0700122 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100123 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true)
124 }
125 else{
126 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true, ['runas=aptly'])
127 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100128
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100129 salt.enforceState(venvPepper, 'I@aptly:server', 'aptly', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100130
Sam Stoelingaaab79702018-04-09 18:49:39 -0700131 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100132 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv"], null, true)
133 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)
134 }
135 else{
136 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true)
137 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-afrv", 'runas=aptly'], null, true)
138 }
Richard Felkl79d7df12018-01-05 16:40:11 +0100139
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100140 salt.enforceState(venvPepper, 'I@aptly:server', 'docker.client.registry', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100141
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100142 salt.enforceState(venvPepper, 'I@aptly:server', 'debmirror', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100143
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100144 salt.enforceState(venvPepper, 'I@aptly:server', 'git.server', true)
145
146 salt.enforceState(venvPepper, 'I@aptly:server', 'linux.system.file', true)
Jakub Josefa63f9862018-01-11 17:58:38 +0100147 }
148 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100149
Richard Felkl970e0082018-06-12 18:00:51 +0200150 stage("Update Drivetrain"){
151 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_salt.list")
152 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")
153 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades salt-formula-*")
Richard Felkl0e80d892018-06-20 13:44:54 +0200154
155 def inventoryBeforeFilename = "reclass-inventory-before.out"
156 def inventoryAfterFilename = "reclass-inventory-after.out"
157
158 archiveReclassInventory(inventoryBeforeFilename)
159
160 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_extra.list")
161 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")
162 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades reclass")
163
Richard Felkl970e0082018-06-12 18:00:51 +0200164 salt.fullRefresh(venvPepper, 'I@salt:master')
Jakub Josefa63f9862018-01-11 17:58:38 +0100165
Richard Felkl970e0082018-06-12 18:00:51 +0200166 try{
167 salt.enforceState(venvPepper, "I@salt:master", 'reclass', true)
168 }
169 catch(Exception ex){
170 error("Reclass fails rendering. Pay attention to your cluster model.")
171 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100172
Richard Felkl970e0082018-06-12 18:00:51 +0200173 salt.fullRefresh(venvPepper, '*')
174
175 try{
176 salt.cmdRun(venvPepper, 'I@salt:master', "reclass-salt --top")
177 }
178 catch(Exception ex){
179 error("Reclass fails rendering. Pay attention to your cluster model.")
180 }
181
Richard Felkl0e80d892018-06-20 13:44:54 +0200182 archiveReclassInventory(inventoryAfterFilename)
183
184 sh "diff -u $inventoryBeforeFilename $inventoryAfterFilename > reclass-inventory-diff.out || true"
185 archiveArtifacts artifacts: "reclass-inventory-diff.out"
186
187 if(UPGRADE_SALTSTACK.toBoolean()){
188 salt.enforceState(venvPepper, "I@linux:system", 'linux.system.repo', true)
189
190 updateSaltStack("I@salt:master", '["salt-master", "salt-common", "salt-api", "salt-minion"]')
191
192 updateSaltStack("I@salt:minion and not I@salt:master", '["salt-minion"]')
193 }
194
Richard Felkl970e0082018-06-12 18:00:51 +0200195 if(UPDATE_PIPELINES.toBoolean()){
196 triggerMirrorJob("git-mirror-downstream-mk-pipelines")
197 triggerMirrorJob("git-mirror-downstream-pipeline-library")
198 }
199
200 salt.enforceState(venvPepper, "I@jenkins:client", 'jenkins.client', true)
201
202 salt.cmdRun(venvPepper, "I@salt:master", "salt -C 'I@jenkins:client and I@docker:client' state.sls docker.client --async")
203
204 sleep(180)
205
206 common.infoMsg("Checking if Docker containers are up")
207
208 try{
209 common.retry(10, 30){
210 salt.cmdRun(venvPepper, 'I@jenkins:client and I@docker:client', "! docker service ls | tail -n +2 | grep -v -E '\\s([0-9])/\\1\\s'")
211 }
212 }
213 catch(Exception ex){
214 error("Docker containers for CI/CD services are having troubles with starting.")
215 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100216 }
217 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100218 catch (Throwable e) {
219 // If there was an error or exception thrown, the build failed
220 currentBuild.result = "FAILURE"
221 throw e
Richard Felkl26cae4d2017-12-19 00:19:16 +0100222 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100223 }
Jakub Josef2c21c6c2018-02-08 18:51:42 +0100224}