blob: 62e56225b5970b2f08ab52783e017702498756a9 [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 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 }
90 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'")
91 }
92
93 try{
94 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git diff-index --quiet HEAD --")
95 }
96 catch(Exception ex){
97 error("You have unstaged changes in your Reclass system model repository. Please reset them and rerun the pipeline.")
98 }
Richard Felkl65e38372018-07-30 11:46:43 +020099 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/system && git checkout $gitMcpVersion")
Jakub Josefa63f9862018-01-11 17:58:38 +0100100 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100101
Jakub Josefa63f9862018-01-11 17:58:38 +0100102 if(UPDATE_LOCAL_REPOS.toBoolean()){
103 stage("Update local repos"){
104 common.infoMsg("Updating local repositories")
Sam Stoelingaaab79702018-04-09 18:49:39 -0700105
106 def engine = salt.getPillar(venvPepper, 'I@aptly:server', "aptly:server:source:engine")
107 runningOnDocker = engine.get("return")[0].containsValue("docker")
108
109 if (runningOnDocker) {
110 common.infoMsg("Aptly is running as Docker container")
111 }
112 else {
113 common.infoMsg("Aptly isn't running as Docker container. Going to use aptly user for executing aptly commands")
114 }
115
Richard Felkl970e0082018-06-12 18:00:51 +0200116 salt.cmdRun(venvPepper, 'I@salt:master', "cd /srv/salt/reclass/classes/cluster/$cluster_name/cicd/aptly && git checkout $MCP_VERSION")
117
Sam Stoelingaaab79702018-04-09 18:49:39 -0700118 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100119 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true)
120 }
121 else{
122 salt.cmdRun(venvPepper, 'I@aptly:server', "aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop -force", true, null, true, ['runas=aptly'])
123 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100124
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100125 salt.enforceState(venvPepper, 'I@aptly:server', 'aptly', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100126
Sam Stoelingaaab79702018-04-09 18:49:39 -0700127 if(runningOnDocker){
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100128 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv"], null, true)
129 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)
130 }
131 else{
132 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true)
133 salt.runSaltProcessStep(venvPepper, 'I@aptly:server', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-afrv", 'runas=aptly'], null, true)
134 }
Richard Felkl79d7df12018-01-05 16:40:11 +0100135
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100136 salt.enforceState(venvPepper, 'I@aptly:server', 'docker.client.registry', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100137
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100138 salt.enforceState(venvPepper, 'I@aptly:server', 'debmirror', true)
Richard Felkl26cae4d2017-12-19 00:19:16 +0100139
Richard Felkl5f7fdaf2018-02-15 15:38:31 +0100140 salt.enforceState(venvPepper, 'I@aptly:server', 'git.server', true)
141
142 salt.enforceState(venvPepper, 'I@aptly:server', 'linux.system.file', true)
Jakub Josefa63f9862018-01-11 17:58:38 +0100143 }
144 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100145
Richard Felkl970e0082018-06-12 18:00:51 +0200146 stage("Update Drivetrain"){
147 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_salt.list")
148 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")
149 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades salt-formula-*")
Richard Felkl0e80d892018-06-20 13:44:54 +0200150
151 def inventoryBeforeFilename = "reclass-inventory-before.out"
152 def inventoryAfterFilename = "reclass-inventory-after.out"
153
154 archiveReclassInventory(inventoryBeforeFilename)
155
156 salt.cmdRun(venvPepper, 'I@salt:master', "sed -i -e 's/[^ ]*[^ ]/$MCP_VERSION/4' /etc/apt/sources.list.d/mcp_extra.list")
157 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")
158 salt.cmdRun(venvPepper, 'I@salt:master', "apt-get install -y --allow-downgrades reclass")
159
Richard Felkl970e0082018-06-12 18:00:51 +0200160 salt.fullRefresh(venvPepper, 'I@salt:master')
Jakub Josefa63f9862018-01-11 17:58:38 +0100161
Richard Felkl970e0082018-06-12 18:00:51 +0200162 try{
163 salt.enforceState(venvPepper, "I@salt:master", 'reclass', true)
164 }
165 catch(Exception ex){
166 error("Reclass fails rendering. Pay attention to your cluster model.")
167 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100168
Richard Felkl970e0082018-06-12 18:00:51 +0200169 salt.fullRefresh(venvPepper, '*')
170
171 try{
172 salt.cmdRun(venvPepper, 'I@salt:master', "reclass-salt --top")
173 }
174 catch(Exception ex){
175 error("Reclass fails rendering. Pay attention to your cluster model.")
176 }
177
Richard Felkl0e80d892018-06-20 13:44:54 +0200178 archiveReclassInventory(inventoryAfterFilename)
179
180 sh "diff -u $inventoryBeforeFilename $inventoryAfterFilename > reclass-inventory-diff.out || true"
181 archiveArtifacts artifacts: "reclass-inventory-diff.out"
182
183 if(UPGRADE_SALTSTACK.toBoolean()){
184 salt.enforceState(venvPepper, "I@linux:system", 'linux.system.repo', true)
185
186 updateSaltStack("I@salt:master", '["salt-master", "salt-common", "salt-api", "salt-minion"]')
187
188 updateSaltStack("I@salt:minion and not I@salt:master", '["salt-minion"]')
189 }
190
Richard Felkl970e0082018-06-12 18:00:51 +0200191 if(UPDATE_PIPELINES.toBoolean()){
192 triggerMirrorJob("git-mirror-downstream-mk-pipelines")
193 triggerMirrorJob("git-mirror-downstream-pipeline-library")
194 }
195
196 salt.enforceState(venvPepper, "I@jenkins:client", 'jenkins.client', true)
197
198 salt.cmdRun(venvPepper, "I@salt:master", "salt -C 'I@jenkins:client and I@docker:client' state.sls docker.client --async")
199
200 sleep(180)
201
202 common.infoMsg("Checking if Docker containers are up")
203
204 try{
205 common.retry(10, 30){
206 salt.cmdRun(venvPepper, 'I@jenkins:client and I@docker:client', "! docker service ls | tail -n +2 | grep -v -E '\\s([0-9])/\\1\\s'")
207 }
208 }
209 catch(Exception ex){
210 error("Docker containers for CI/CD services are having troubles with starting.")
211 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100212 }
213 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100214 catch (Throwable e) {
215 // If there was an error or exception thrown, the build failed
216 currentBuild.result = "FAILURE"
217 throw e
Richard Felkl26cae4d2017-12-19 00:19:16 +0100218 }
Richard Felkl26cae4d2017-12-19 00:19:16 +0100219 }
Jakub Josef2c21c6c2018-02-08 18:51:42 +0100220}