blob: 9945d33f8433d847fbe88a0ea58d7f9fd1275e69 [file] [log] [blame]
Jiri Broulik60dcab32018-03-08 17:42:06 +01001/**
2 * Update packages on given nodes
3 *
4 * Expected parameters:
5 * SALT_MASTER_CREDENTIALS Credentials to the Salt API.
6 * SALT_MASTER_URL Full Salt API address [https://10.10.10.1:8000].
7 * SNAPSHOT_NAME Snapshot name
8 * CFG_NODE_PROVIDER Physical machine name hosting Salt-Master VM (ex. kvm01*)
9 * INTERACTIVE Ask interactive questions during pipeline run (bool)
10 * PER_NODE Target nodes will be managed one by one (bool)
11 * ROLLBACK_BY_REDEPLOY Omit taking live snapshots. Rollback is planned to be done by redeployment (bool)
12 * STOP_SERVICES Stop API services before update (bool)
Mykyta Karpin7820e752018-12-04 16:01:15 +020013 * TARGET_KERNEL_UPDATES Comma separated list of nodes to update kernel if newer version is available (Valid values are cfg,msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,cid,kvm,osd)
14 * TARGET_REBOOT Comma separated list of nodes to reboot after update or physical machine rollback (Valid values are cfg,msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,cid,kvm,osd)
15 * TARGET_HIGHSTATE Comma separated list of nodes to run Salt Highstate on after update or physical machine rollback (Valid values are cfg,msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,cid,kvm,osd)
16 * TARGET_UPDATES Comma separated list of nodes to update (Valid values are cfg,msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,cid,kvm,osd)
17 * TARGET_ROLLBACKS Comma separated list of nodes to rollback (Valid values are msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,kvm,osd)
18 * TARGET_SNAPSHOT_MERGES Comma separated list of nodes to merge live snapshot for (Valid values are cfg,msg,dbs,log,mon,mtr,ntw,nal,cmn,rgw,cid)
Jiri Broulik60dcab32018-03-08 17:42:06 +010019 * MSG_TARGET Salt targeted MSG nodes (ex. msg*)
20 * DBS_TARGET Salt targeted DBS nodes (ex. dbs*)
21 * LOG_TARGET Salt targeted LOG nodes (ex. log*)
22 * MON_TARGET Salt targeted MON nodes (ex. mon*)
23 * MTR_TARGET Salt targeted MTR nodes (ex. mtr*)
24 * NTW_TARGET Salt targeted NTW nodes (ex. ntw*)
25 * NAL_TARGET Salt targeted NAL nodes (ex. nal*)
26 * CMN_TARGET Salt targeted CMN nodes (ex. cmn*)
27 * RGW_TARGET Salt targeted RGW nodes (ex. rgw*)
28 * CID_TARGET Salt targeted CID nodes (ex. cid*)
Jiri Broulik60dcab32018-03-08 17:42:06 +010029 * KVM_TARGET Salt targeted physical KVM nodes (ex. kvm01*)
30 * CEPH_OSD_TARGET Salt targeted physical Ceph OSD nodes (ex. osd001*)
Jiri Broulik906e9972018-03-26 16:12:00 +020031 * ROLLBACK_PKG_VERSIONS Space separated list of pkgs=versions to rollback to on physical targeted machines (ex. pkg_name1=pkg_version1 pkg_name2=pkg_version2)
32 * PURGE_PKGS Space separated list of pkgs=versions to be purged on physical targeted machines (ex. pkg_name1=pkg_version1 pkg_name2=pkg_version2)
33 * REMOVE_PKGS Space separated list of pkgs=versions to be removed on physical targeted machines (ex. pkg_name1=pkg_version1 pkg_name2=pkg_version2)
Jiri Broulik60dcab32018-03-08 17:42:06 +010034 * RESTORE_GALERA Restore Galera DB (bool)
35 * RESTORE_CONTRAIL_DB Restore Cassandra and Zookeeper DBs for OpenContrail (bool)
Richard Felklaedc89b2018-06-26 23:50:49 +020036 * RUN_CVP_TESTS Run cloud validation pipelines before and after upgrade
Martin Polreich5ec90ee2018-08-21 16:27:40 +020037 * MINIONS_TEST_TIMEOUT Time in seconds for a Salt result to receive a response when calling a minionsReachable method.
Jiri Broulik60dcab32018-03-08 17:42:06 +010038 *
39**/
40def common = new com.mirantis.mk.Common()
Vasyl Saienkod63721d2018-11-13 18:04:41 +020041def orchestrate = new com.mirantis.mk.Orchestrate()
Jiri Broulik60dcab32018-03-08 17:42:06 +010042def salt = new com.mirantis.mk.Salt()
43def python = new com.mirantis.mk.Python()
44def virsh = new com.mirantis.mk.Virsh()
45
46def updates = TARGET_UPDATES.tokenize(",").collect{it -> it.trim()}
47def rollbacks = TARGET_ROLLBACKS.tokenize(",").collect{it -> it.trim()}
Jiri Broulik5dac8d82018-03-29 13:34:39 +020048def merges = TARGET_SNAPSHOT_MERGES.tokenize(",").collect{it -> it.trim()}
Jiri Broulik7ba05e42018-04-06 11:39:25 +020049def reboots = TARGET_REBOOT.tokenize(",").collect{it -> it.trim()}
Jiri Broulik60dcab32018-03-08 17:42:06 +010050
51def pepperEnv = "pepperEnv"
52def minions
53def result
54def packages
55def command
56def commandKwargs
57
mkraynov28199c22018-10-26 16:41:19 +040058wait = 10
Martin Polreich5ec90ee2018-08-21 16:27:40 +020059if (common.validInputParam('MINIONS_TEST_TIMEOUT') && MINIONS_TEST_TIMEOUT.isInteger()) {
60 wait = "${MINIONS_TEST_TIMEOUT}".toInteger()
61}
62
Denis Egorenko0d0c65f2019-02-26 16:05:03 +040063def updateSaltPackage(pepperEnv, target, pkgs, masterUpdate = false) {
64 def salt = new com.mirantis.mk.Salt()
65 salt.cmdRun(pepperEnv, "I@salt:master", "salt -C '${target}' --async pkg.install force_yes=True pkgs='$pkgs'")
66 def minions_reachable = target
67 if (masterUpdate) {
68 // in case of update Salt Master packages - check all minions are good
69 minions_reachable = '*'
70 }
71 salt.checkTargetMinionsReady(['saltId': venvPepper, 'target': target, 'target_reachable': minions_reachable])
72}
73
Jiri Broulik60dcab32018-03-08 17:42:06 +010074def updatePkgs(pepperEnv, target, targetType="", targetPackages="") {
75 def salt = new com.mirantis.mk.Salt()
76 def common = new com.mirantis.mk.Common()
Jiri Broulikba6d85d2018-04-05 13:29:07 +020077 def kernelUpdates = TARGET_KERNEL_UPDATES.tokenize(",").collect{it -> it.trim()}
78 def distUpgrade = false
Jiri Broulik60dcab32018-03-08 17:42:06 +010079 def commandKwargs
Jiri Broulik60dcab32018-03-08 17:42:06 +010080 def pkgs
81 def out
82
83 salt.enforceState(pepperEnv, target, 'linux.system.repo')
84
85 stage("List package upgrades") {
86 common.infoMsg("Listing all the packages that have a new update available on ${target}")
Jiri Broulikba6d85d2018-04-05 13:29:07 +020087 if (kernelUpdates.contains(targetType)) {
88 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', [], null, true))
89 } else {
90 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', ['dist_upgrade=False'], null, true))
91 }
Jiri Broulik60dcab32018-03-08 17:42:06 +010092 if(targetPackages != "" && targetPackages != "*"){
93 common.infoMsg("Note that only the ${targetPackages} would be installed from the above list of available updates on the ${target}")
94 }
95 }
96
97 if (INTERACTIVE.toBoolean()) {
98 stage("Confirm live package upgrades on ${target}") {
99 if (targetPackages=="") {
100 def userInput = input(
101 id: 'userInput', message: 'Insert package names for update', parameters: [
102 [$class: 'TextParameterDefinition', defaultValue: pkgs.keySet().join(",").toString(), description: 'Package names (or *)', name: 'packages']
103 ])
104 if (userInput!= "" && userInput!= "*") {
105 targetPackages = userInput
106 }
107 } else {
108 input message: "Approve live package upgrades on ${target} nodes?"
109 }
110 }
111 } else {
112 targetPackages = pkgs.keySet().join(",").toString()
113 }
114
115 if (targetPackages != "") {
116 // list installed versions of pkgs that will be upgraded
Mykyta Karpin7820e752018-12-04 16:01:15 +0200117 if (targetType == 'kvm' || targetType == 'osd') {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200118 def installedPkgs = []
119 def newPkgs = []
120 def targetPkgList = targetPackages.tokenize(',')
121 for (pkg in targetPkgList) {
122 def version
123 try {
124 def pkgsDetails = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.info_installed', [pkg], null, true))
125 version = pkgsDetails.get(pkg).get('version')
126 } catch (Exception er) {
127 common.infoMsg("${pkg} not installed yet")
128 }
129 if (version?.trim()) {
130 installedPkgs.add(pkg + '=' + version)
131 } else {
132 newPkgs.add(pkg)
133 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100134 }
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200135 common.warningMsg("the following list of pkgs will be upgraded")
136 common.warningMsg(installedPkgs.join(" "))
137 common.warningMsg("the following list of pkgs will be newly installed")
138 common.warningMsg(newPkgs.join(" "))
Jiri Broulik60dcab32018-03-08 17:42:06 +0100139 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100140 // set variables
141 command = "pkg.install"
142 packages = targetPackages
143 commandKwargs = ['only_upgrade': 'true','force_yes': 'true']
144
145 }else {
146 command = "pkg.upgrade"
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200147 if (kernelUpdates.contains(targetType)) {
148 commandKwargs = ['dist_upgrade': 'true']
149 distUpgrade = true
150 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100151 packages = null
152 }
153
Jiri Broulik60dcab32018-03-08 17:42:06 +0100154 stage("stop services on ${target}") {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200155 if ((STOP_SERVICES.toBoolean()) && (targetType != 'cid')) {
156 if (targetType == 'ntw' || targetType == 'nal') {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200157 contrailServices(pepperEnv, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100158 } else {
159 def probe = salt.getFirstMinion(pepperEnv, "${target}")
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200160 services(pepperEnv, probe, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100161 }
162 }
163 }
164
165 stage('Apply package upgrades') {
166 // salt master pkg
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200167 if (targetType == 'cfg') {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100168 common.warningMsg('salt-master pkg upgrade, rerun the pipeline if disconnected')
Denis Egorenko0d0c65f2019-02-26 16:05:03 +0400169 updateSaltPackage(pepperEnv, target, '["salt-master"]', true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100170 }
171 // salt minion pkg
Denis Egorenko0d0c65f2019-02-26 16:05:03 +0400172 updateSaltPackage(pepperEnv, target, '["salt-minion"]')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100173 common.infoMsg('Performing pkg upgrades ... ')
174 common.retry(3){
175 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], command, true, packages, commandKwargs)
176 salt.printSaltCommandResult(out)
177 }
178 def osRelease = salt.getGrain(pepperEnv, target, 'lsb_distrib_codename')
179 if (osRelease.toString().toLowerCase().contains('trusty')) {
azvyagintsev93e05cc2018-12-26 13:53:02 +0200180 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --force-yes -o Dpkg::Options::=\"--force-confold\" '
Jiri Broulik60dcab32018-03-08 17:42:06 +0100181 } else {
azvyagintsev93e05cc2018-12-26 13:53:02 +0200182 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q -f --allow-downgrades -o Dpkg::Options::=\"--force-confold\" '
Jiri Broulik60dcab32018-03-08 17:42:06 +0100183 }
184 if (out.toString().contains('errors:')) {
185 try {
186 if (packages?.trim()) {
187 packages = packages.replaceAll(',', ' ')
188 common.retry(3){
189 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install ' + packages])
190 }
191 } else {
192 if (distUpgrade) {
Denis Egorenkodaed4c52019-10-01 13:30:00 +0400193 common.infoMsg("Checking availability of Linux HWE Kernel...")
194 def switchHwe = false
195 def nodesOut = salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], 'linux_kernel_switch.check_hwe_kernel').get('return')[0]
196 def targetHWE = []
197 for (node in nodesOut) {
198 def nodeName = node.getKey()
199 def statusPkgs = node.getValue()
200 if (statusPkgs) {
201 statusPkgs.each { pkg, pkgStatus ->
202 if (pkgStatus instanceof String) {
203 common.warningMsg("Target ${nodeName} has no installed Linux HWE Kernel package: ${pkg}")
204 if (! targetHWE.contains(nodeName)) {
205 targetHWE.add(nodeName)
206 }
207 }
208 }
209 } else {
210 common.warningMsg("Target ${nodeName} has no info about Linux HWE Kernel, check formula or resync minion data.")
211 }
212 }
213 if (targetHWE) {
214 if (INTERACTIVE.toBoolean()) {
215 try {
216 input message: "Do you want to switch from generic to hwe kernel for ${targetHWE} nodes? Click to confirm", ok: 'Switch to HWE'
217 switchHwe = true
218 } catch (Exception ex) {
219 common.warningMsg("Kernel switch from generic to hwe for ${targetHWE} cancelled. Continue dist-upgrade with existing kernel.")
220 }
221 } else {
222 switchHwe = true
223 }
224 }
225 if (switchHwe) {
226 def onlyKernel='True'
227 def targetHWECompound = targetHWE.join(' or ')
228 if (INTERACTIVE.toBoolean()) {
229 try {
230 input message: "Install HWE headers and generic packages?", ok: 'Install'
231 onlyKernel='False'
232 common.infoMsg("HWE Kernel, headers and generic packages will be installed.")
233 } catch (Exception e) {
234 common.infoMsg("Only HWE Kernel packages will be installed.")
235 }
236 } else {
237 onlyKernel='False'
238 }
239 salt.runSaltCommand(pepperEnv, 'local', ['expression': targetHWECompound, 'type': 'compound'], 'linux_kernel_switch.switch_kernel', false, "only_kernel=${onlyKernel}")
240 common.infoMsg("HWE Kernel has been installed on ${targetHWE} nodes")
241 def rebootNow = true
242 if (INTERACTIVE.toBoolean()) {
243 try {
244 input message: "To finish switch on HWE kernel it is needed to reboot. Reboot nodes ${targetHWE} now?", ok: 'Reboot'
245 } catch (Exception e) {
246 common.warningMsg("HWE Kernel is not used. Please reboot nodes ${targetHWE} manually to finish kernel switch.")
247 rebootNow = false
248 }
249 }
250 if (rebootNow) {
251 common.infoMsg('Performing nodes reboot after kernel install...')
252 salt.runSaltCommand(pepperEnv, 'local', ['expression': targetHWECompound, 'type': 'compound'], 'system.reboot', null, 'at_time=1')
253 sleep(180)
254 salt.minionsReachable(pepperEnv, 'I@salt:master', targetHWECompound, null, 10, 20)
255 }
256 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100257 common.retry(3){
258 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' dist-upgrade'])
259 }
260 } else {
261 common.retry(3){
262 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' upgrade'])
263 }
264 } }
265 if (out.toString().contains('E: ')) {
266 common.errorMsg(out)
267 if (INTERACTIVE.toBoolean()) {
268 input message: "Pkgs update failed to be updated on ${target}. Please fix it manually."
269 } else {
270 salt.printSaltCommandResult(out)
271 throw new Exception("Pkgs update failed")
272 }
273 }
274 } catch (Exception e) {
275 common.errorMsg(out)
276 common.errorMsg(e)
277 if (INTERACTIVE.toBoolean()) {
278 input message: "Pkgs update failed to be updated on ${target}. Please fix it manually."
279 } else {
280 throw new Exception("Pkgs update failed")
281 }
282 }
283 }
284 }
285}
286
287def rollbackPkgs(pepperEnv, target, targetType = "", targetPackages="") {
288 def salt = new com.mirantis.mk.Salt()
289 def common = new com.mirantis.mk.Common()
290 def probe = salt.getFirstMinion(pepperEnv, "${target}")
291 def distUpgrade
292 def pkgs
293 def out
294
295 salt.enforceState(pepperEnv, target, 'linux.system.repo')
296
297 if (ROLLBACK_PKG_VERSIONS == "") {
298 stage("List package upgrades") {
299 common.infoMsg("Listing all the packages that have a new update available on ${target}")
300 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', [], null, true))
301 if(targetPackages != "" && targetPackages != "*"){
302 common.infoMsg("Note that only the ${targetPackages} would be installed from the above list of available updates on the ${target}")
303 }
304 }
305
306 if (INTERACTIVE.toBoolean()) {
307 stage("Confirm live package upgrades on ${target}") {
308 if(targetPackages==""){
309 timeout(time: 2, unit: 'HOURS') {
310 def userInput = input(
311 id: 'userInput', message: 'Insert package names for update', parameters: [
312 [$class: 'TextParameterDefinition', defaultValue: pkgs.keySet().join(",").toString(), description: 'Package names (or *)', name: 'packages']
313 ])
314 if(userInput!= "" && userInput!= "*"){
315 targetPackages = userInput
316 }
317 }
318 }else{
319 timeout(time: 2, unit: 'HOURS') {
320 input message: "Approve live package upgrades on ${target} nodes?"
321 }
322 }
323 }
324 } else {
325 targetPackages = pkgs.keySet().join(",").toString()
326 }
327 } else {
328 targetPackages = ROLLBACK_PKG_VERSIONS
329 }
330
331 if (targetPackages != "") {
332 // set variables
333 packages = targetPackages
334 } else {
335 distUpgrade = true
336 packages = null
337 }
338
339 stage("stop services on ${target}") {
340 try {
341 if (INTERACTIVE.toBoolean()) {
342 input message: "Click PROCEED to interactively stop services on ${target}. Otherwise click ABORT to skip stopping them and continue."
343 }
344 } catch (Exception er) {
345 common.infoMsg('skipping stopping services')
346 return
347 }
348 if (STOP_SERVICES.toBoolean()) {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200349 services(pepperEnv, probe, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100350 }
351 }
352
353 stage('Apply package downgrades') {
azvyagintsev93e05cc2018-12-26 13:53:02 +0200354 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confold\" '
Jiri Broulik60dcab32018-03-08 17:42:06 +0100355 common.infoMsg('Performing pkgs purge/remove ... ')
356 try {
357 if (PURGE_PKGS != "") {
358 def purgePackages = PURGE_PKGS.replaceAll(',', ' ')
359 common.retry(3){
360 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' purge ' + purgePackages])
361 }
362 }
363 if (REMOVE_PKGS != "") {
364 def removePackages = REMOVE_PKGS.replaceAll(',', ' ')
365 common.retry(3){
366 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' remove ' + removePackages])
367 }
368 }
369 if (out.toString().contains('E: ')) {
370 common.errorMsg(out)
371 if (INTERACTIVE.toBoolean()) {
372 input message: "Pkgs ${packages} purge failed on ${target}. Please fix it manually."
373 } else {
374 salt.printSaltCommandResult(out)
375 throw new Exception("Pkgs {packages} purge failed")
376 }
377 }
378 } catch (Exception e) {
379 common.errorMsg(out)
380 common.errorMsg(e)
381 if (INTERACTIVE.toBoolean()) {
382 input message: "Pkgs {packages} purge on ${target}. Please fix it manually."
383 } else {
384 throw new Exception("Pkgs {packages} purge failed")
385 }
386 }
387
388 common.infoMsg('Performing pkg downgrades ... ')
389 try {
390 packages = packages.replaceAll(',', ' ')
391 if (packages?.trim()) {
392 packages = packages.replaceAll(',', ' ')
393 common.retry(3){
394 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install salt-minion'], null, true, 5)
395 }
Martin Polreich5ec90ee2018-08-21 16:27:40 +0200396 salt.minionsReachable(pepperEnv, 'I@salt:master', target, null, wait)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100397 common.retry(3){
398 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install ' + packages])
399 }
400 } else {
401 if (distUpgrade) {
Denis Egorenkodaed4c52019-10-01 13:30:00 +0400402 salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], 'linux_kernel_switch.rollback_switch_kernel', false)
403 def rebootNow = true
404 if (INTERACTIVE.toBoolean()) {
405 try {
406 input message: "To finish kernel downgrade it is needed to reboot. Reboot nodes ${target} now?", ok: 'Reboot'
407 } catch (Exception e) {
408 common.warningMsg("Please reboot nodes ${target} manually to finish kernel downgrade.")
409 rebootNow = false
410 }
411 }
412 if (rebootNow) {
413 common.infoMsg('Performing nodes reboot after kernel downgrade...')
414 salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], 'system.reboot', null, 'at_time=1')
415 sleep(180)
416 salt.minionsReachable(pepperEnv, 'I@salt:master', target, null, 10, 20)
417 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100418 common.retry(3){
419 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' dist-upgrade'])
420 }
421 } else {
422 common.retry(3){
423 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' upgrade'])
424 }
425 }
426 }
427 if (out.toString().contains('E: ')) {
428 common.errorMsg(out)
429 if (INTERACTIVE.toBoolean()) {
430 input message: "Pkgs rollback failed on ${target}. Please fix it manually."
431 } else {
432 salt.printSaltCommandResult(out)
433 throw new Exception("Pkgs rollback failed")
434 }
435 }
436 } catch (Exception e) {
437 common.errorMsg(out)
438 common.errorMsg(e)
439 if (INTERACTIVE.toBoolean()) {
440 input message: "Pkgs rollback failed on ${target}. Please fix it manually."
441 } else {
442 throw new Exception("Pkgs rollback failed")
443 }
444 }
445 }
446}
447
Jiri Broulik827d0112018-04-25 16:00:07 +0200448def getNodeProvider(pepperEnv, nodeName, type='') {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100449 def salt = new com.mirantis.mk.Salt()
450 def common = new com.mirantis.mk.Common()
Jiri Broulik827d0112018-04-25 16:00:07 +0200451 def kvms = salt.getMinions(pepperEnv, 'I@salt:control')
452 for (kvm in kvms) {
453 try {
454 vms = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, kvm, 'virt.list_domains', [], null, true))
455 if (vms.toString().contains(nodeName)) {
456 if (type == 'master' && !CFG_NODE_PROVIDER?.trim()) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100457 CFG_NODE_PROVIDER = kvm
Jiri Broulik827d0112018-04-25 16:00:07 +0200458 } else {
459 return kvm
Jiri Broulik60dcab32018-03-08 17:42:06 +0100460 //break
461 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100462 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100463 } catch (Exception er) {
Jiri Broulik827d0112018-04-25 16:00:07 +0200464 common.infoMsg("${nodeName} not present on ${kvm}")
Jiri Broulik60dcab32018-03-08 17:42:06 +0100465 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100466 }
467}
468
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200469def services(pepperEnv, probe, target, action='stop') {
470 def services = ["keepalived","haproxy","nginx","nova-api","cinder","glance","heat","neutron","apache2","rabbitmq-server"]
471 if (action == 'stop') {
472 def openstack = new com.mirantis.mk.Openstack()
473 openstack.stopServices(pepperEnv, probe, target, services, INTERACTIVE.toBoolean())
Jiri Broulik60dcab32018-03-08 17:42:06 +0100474 } else {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200475 def salt = new com.mirantis.mk.Salt()
476 for (s in services) {
Dmitry Ukovfbb18ee2018-09-04 17:57:03 +0400477 def outputServicesStr = salt.getReturnValues(salt.cmdRun(pepperEnv, probe, "service --status-all | grep ${s} | awk \'{print \$4}\'"))
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200478 def servicesList = outputServicesStr.tokenize("\n").init() //init() returns the items from the Iterable excluding the last item
479 if (servicesList) {
480 for (name in servicesList) {
481 if (!name.contains('Salt command')) {
482 salt.runSaltProcessStep(pepperEnv, "${target}*", 'service.start', ["${name}"])
483 }
484 }
485 }
486 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100487 }
488}
489
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200490// must be treated separately due to OC on Trusty
491def contrailServices(pepperEnv, target, action='stop') {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100492 def salt = new com.mirantis.mk.Salt()
493 def common = new com.mirantis.mk.Common()
494 def services = []
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200495 if (action == 'stop') {
496 services.add('supervisor-control')
497 services.add('supervisor-config')
498 services.add('supervisor-database')
499 services.add('zookeeper')
500 services.add('ifmap-server')
501 services.add('haproxy')
502 services.add('keepalived')
503 } else {
504 services.add('keepalived')
505 services.add('haproxy')
506 services.add('ifmap-server')
507 services.add('zookeeper')
508 services.add('supervisor-database')
509 services.add('supervisor-config')
510 services.add('supervisor-control')
511 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100512 for (s in services) {
513 try {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200514 salt.runSaltProcessStep(pepperEnv, target, "service.${action}", [s], null, true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100515 } catch (Exception er) {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200516 common.warningMsg(er)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100517 }
518 }
519}
520
Jiri Broulik059d2df2018-06-15 14:03:34 +0200521def periodicCheck(pepperEnv, target, maxRetries=50) {
522 def salt = new com.mirantis.mk.Salt()
523 def common = new com.mirantis.mk.Common()
524 def count = 0
525 while(count < maxRetries) {
526 try {
527 sleep(10)
Martin Polreich5ec90ee2018-08-21 16:27:40 +0200528 salt.minionsReachable(pepperEnv, 'I@salt:master', target, null, wait)
Jiri Broulik059d2df2018-06-15 14:03:34 +0200529 break
530 } catch (Exception e) {
531 common.warningMsg("${target} not ready yet. Waiting ...")
532 }
533 count++
534 }
535}
536
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200537def highstate(pepperEnv, target, type) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100538 def salt = new com.mirantis.mk.Salt()
539 def common = new com.mirantis.mk.Common()
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200540 def highstates = TARGET_HIGHSTATE.tokenize(",").collect{it -> it.trim()}
541 def reboots = TARGET_REBOOT.tokenize(",").collect{it -> it.trim()}
542 // optionally run highstate
543 if (highstates.contains(type)) {
544 stage("Apply highstate on ${target} nodes") {
545 try {
546 common.retry(3){
Martin Polreich372d9b92018-10-04 16:44:56 +0200547 out = salt.enforceHighstate(pepperEnv, target)
548 salt.printSaltCommandResult(out)
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200549 }
550 } catch (Exception e) {
551 common.errorMsg(e)
552 if (INTERACTIVE.toBoolean()) {
553 input message: "Highstate failed on ${target}. Fix it manually or run rollback on ${target}."
554 } else {
555 throw new Exception("highstate failed")
556 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100557 }
558 }
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200559 } else if (!reboots.contains(type) && STOP_SERVICES.toBoolean() && type != 'cid') {
560 if (type == 'ntw' || type == 'nal') {
561 contrailServices(pepperEnv, target, 'start')
562 } else {
563 def probe = salt.getFirstMinion(pepperEnv, "${target}")
564 services(pepperEnv, probe, target, 'start')
565 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100566 }
567 // optionally reboot
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200568 if (reboots.contains(type)) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100569 stage("Reboot ${target} nodes") {
Jiri Broulik059d2df2018-06-15 14:03:34 +0200570 if (type == 'cfg') {
571 try {
572 salt.runSaltProcessStep(pepperEnv, target, 'system.reboot', null, null, true, 5)
573 } catch (Exception e) {
574 periodicCheck(pepperEnv, target)
575 }
576 } else {
577 salt.runSaltProcessStep(pepperEnv, target, 'system.reboot', null, null, true, 5)
578 sleep 10
Martin Polreich5ec90ee2018-08-21 16:27:40 +0200579 salt.minionsReachable(pepperEnv, 'I@salt:master', target, null, wait)
Jiri Broulik059d2df2018-06-15 14:03:34 +0200580 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100581 }
582 }
583}
584
585def rollback(pepperEnv, tgt, generalTarget) {
586 def common = new com.mirantis.mk.Common()
587 try {
588 if (INTERACTIVE.toBoolean()) {
589 input message: "Are you sure to rollback ${generalTarget}? To rollback click on PROCEED. To skip rollback click on ABORT."
590 }
591 } catch (Exception er) {
592 common.infoMsg('skipping rollback')
593 return
594 }
595 try {
596 rollbackLiveSnapshot(pepperEnv, tgt, generalTarget)
597 } catch (Exception err) {
598 common.errorMsg(err)
599 if (INTERACTIVE.toBoolean()) {
600 input message: "Rollback for ${tgt} failed please fix it manually before clicking PROCEED."
601 } else {
602 throw new Exception("Rollback failed for ${tgt}")
603 }
604 }
605}
606
607def liveSnapshot(pepperEnv, tgt, generalTarget) {
608 def salt = new com.mirantis.mk.Salt()
609 def common = new com.mirantis.mk.Common()
610 def virsh = new com.mirantis.mk.Virsh()
611 def domain = salt.getDomainName(pepperEnv)
612 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
613 common.warningMsg(target_hosts)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100614 for (t in target_hosts) {
615 def target = salt.stripDomainName(t)
Jiri Broulik827d0112018-04-25 16:00:07 +0200616 def nodeProvider = getNodeProvider(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100617 virsh.liveSnapshotPresent(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100618 }
619}
620
621def mergeSnapshot(pepperEnv, tgt, generalTarget='') {
622 def salt = new com.mirantis.mk.Salt()
623 def virsh = new com.mirantis.mk.Virsh()
624 def domain = salt.getDomainName(pepperEnv)
625 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
Jiri Broulik60dcab32018-03-08 17:42:06 +0100626 for (t in target_hosts) {
627 if (tgt == 'I@salt:master') {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200628 def master = salt.getReturnValues(salt.getPillar(pepperEnv, t, 'linux:network:hostname'))
Jiri Broulik827d0112018-04-25 16:00:07 +0200629 getNodeProvider(pepperEnv, master, 'master')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100630 virsh.liveSnapshotMerge(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME)
631 } else {
632 def target = salt.stripDomainName(t)
Jiri Broulik827d0112018-04-25 16:00:07 +0200633 def nodeProvider = getNodeProvider(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100634 virsh.liveSnapshotMerge(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
635 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100636 }
Martin Polreich5ec90ee2018-08-21 16:27:40 +0200637 salt.minionsReachable(pepperEnv, 'I@salt:master', tgt, null, wait)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100638}
639
640
641
642def rollbackLiveSnapshot(pepperEnv, tgt, generalTarget) {
643 def salt = new com.mirantis.mk.Salt()
644 def virsh = new com.mirantis.mk.Virsh()
645 def common = new com.mirantis.mk.Common()
646 def domain = salt.getDomainName(pepperEnv)
647 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
648 // first destroy all vms
Jiri Broulik60dcab32018-03-08 17:42:06 +0100649 for (t in target_hosts) {
650 def target = salt.stripDomainName(t)
Jiri Broulik827d0112018-04-25 16:00:07 +0200651 def nodeProvider = getNodeProvider(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100652 salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.destroy', ["${target}.${domain}"], null, true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100653 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100654 // rollback vms
655 for (t in target_hosts) {
656 def target = salt.stripDomainName(t)
Jiri Broulik827d0112018-04-25 16:00:07 +0200657 def nodeProvider = getNodeProvider(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100658 virsh.liveSnapshotRollback(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100659 }
660 try {
661 salt.minionsReachable(pepperEnv, 'I@salt:master', tgt)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100662 } catch (Exception e) {
663 common.errorMsg(e)
664 if (INTERACTIVE.toBoolean()) {
Andrei Danin67d3df22018-10-11 14:24:36 -0700665 input message: "Not all minions ${tgt} returned after snapshot revert. Do you want to PROCEED?."
Jiri Broulik60dcab32018-03-08 17:42:06 +0100666 } else {
Andrei Danin67d3df22018-10-11 14:24:36 -0700667 throw new Exception("Not all minions ${tgt} returned after snapshot revert")
Jiri Broulik60dcab32018-03-08 17:42:06 +0100668 }
669 }
670}
671
672def removeNode(pepperEnv, tgt, generalTarget) {
673 def salt = new com.mirantis.mk.Salt()
674 def virsh = new com.mirantis.mk.Virsh()
675 def common = new com.mirantis.mk.Common()
676 def domain = salt.getDomainName(pepperEnv)
677 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
678 // first destroy all vms
Jiri Broulik60dcab32018-03-08 17:42:06 +0100679 for (t in target_hosts) {
680 def target = salt.stripDomainName(t)
Jiri Broulik827d0112018-04-25 16:00:07 +0200681 def nodeProvider = getNodeProvider(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100682 salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.destroy', ["${target}.${domain}"], null, true)
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200683 //salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.undefine', ["${target}.${domain}"], null, true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100684 try {
685 salt.cmdRun(pepperEnv, 'I@salt:master', "salt-key -d ${target}.${domain} -y")
686 } catch (Exception e) {
687 common.warningMsg('does not match any accepted, unaccepted or rejected keys. They were probably already removed. We should continue to run')
688 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100689 }
690}
691
Jiri Broulik906e9972018-03-26 16:12:00 +0200692def saltMasterBackup(pepperEnv) {
693 def salt = new com.mirantis.mk.Salt()
694 salt.enforceState(pepperEnv, 'I@salt:master', 'backupninja')
695 salt.cmdRun(pepperEnv, 'I@salt:master', "su root -c 'backupninja -n --run /etc/backup.d/200.backup.rsync'")
696}
697
Jiri Broulik60dcab32018-03-08 17:42:06 +0100698def backupCeph(pepperEnv, tgt) {
699 def salt = new com.mirantis.mk.Salt()
700 salt.enforceState(pepperEnv, 'I@ceph:backup:server', 'ceph.backup')
701 salt.enforceState(pepperEnv, "I@ceph:backup:client and ${tgt}", 'ceph.backup')
702 salt.cmdRun(pepperEnv, "I@ceph:backup:client and ${tgt}", "su root -c '/usr/local/bin/ceph-backup-runner-call.sh -s'")
703}
704
705def backupGalera(pepperEnv) {
706 def salt = new com.mirantis.mk.Salt()
707 salt.enforceState(pepperEnv, 'I@xtrabackup:server', ['linux.system.repo', 'xtrabackup'])
708 salt.enforceState(pepperEnv, 'I@xtrabackup:client', ['linux.system.repo', 'openssh.client'])
709 salt.cmdRun(pepperEnv, 'I@xtrabackup:client', "su root -c 'salt-call state.sls xtrabackup'")
710 salt.cmdRun(pepperEnv, 'I@xtrabackup:client', "su root -c '/usr/local/bin/innobackupex-runner.sh -s -f'")
711}
712
713// cluster galera - wsrep_cluster_size
714def clusterGalera(pepperEnv) {
715 def salt = new com.mirantis.mk.Salt()
716 def common = new com.mirantis.mk.Common()
717 try {
718 salt.runSaltProcessStep(pepperEnv, 'I@galera:slave', 'service.stop', ['mysql'])
719 } catch (Exception er) {
720 common.warningMsg('Mysql service already stopped')
721 }
722 try {
723 salt.runSaltProcessStep(pepperEnv, 'I@galera:master', 'service.stop', ['mysql'])
724 } catch (Exception er) {
725 common.warningMsg('Mysql service already stopped')
726 }
727 try {
728 salt.cmdRun(pepperEnv, 'I@galera:slave', "rm /var/lib/mysql/ib_logfile*")
729 } catch (Exception er) {
730 common.warningMsg('Files are not present')
731 }
732 salt.cmdRun(pepperEnv, 'I@galera:master', "sed -i '/gcomm/c\\wsrep_cluster_address=\"gcomm://\"' /etc/mysql/my.cnf")
733 salt.runSaltProcessStep(pepperEnv, 'I@galera:master', 'service.start', ['mysql'])
734 // wait until mysql service on galera master is up
735 try {
736 salt.commandStatus(pepperEnv, 'I@galera:master', 'service mysql status', 'running')
737 } catch (Exception er) {
738 if (INTERACTIVE.toBoolean()) {
739 input message: "Database is not running please fix it first and only then click on PROCEED."
740 } else {
741 throw new Exception("Database is not running correctly")
742 }
743 }
744 salt.runSaltProcessStep(pepperEnv, 'I@galera:slave', 'service.start', ['mysql'])
745}
746
747def restoreGalera(pepperEnv) {
748 def salt = new com.mirantis.mk.Salt()
749 def common = new com.mirantis.mk.Common()
Martin Polreich208c4872019-02-15 10:09:10 +0100750 def galera = new com.mirantis.mk.Galera()
751 galera.restoreGaleraDb(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100752}
753
754def backupZookeeper(pepperEnv) {
755 def salt = new com.mirantis.mk.Salt()
756 def common = new com.mirantis.mk.Common()
757 salt.enforceState(pepperEnv, 'I@zookeeper:backup:server', 'zookeeper.backup')
758 salt.enforceState(pepperEnv, 'I@zookeeper:backup:client', 'zookeeper.backup')
759 try {
760 salt.cmdRun(pepperEnv, 'I@opencontrail:control', "su root -c '/usr/local/bin/zookeeper-backup-runner.sh -s'")
761 } catch (Exception er) {
762 throw new Exception('Zookeeper failed to backup. Please fix it before continuing.')
763 }
764}
765
766def backupCassandra(pepperEnv) {
767 def salt = new com.mirantis.mk.Salt()
768 def common = new com.mirantis.mk.Common()
769
770 salt.enforceState(pepperEnv, 'I@cassandra:backup:server', 'cassandra.backup')
771 salt.enforceState(pepperEnv, 'I@cassandra:backup:client', 'cassandra.backup')
772 try {
773 salt.cmdRun(pepperEnv, 'I@cassandra:backup:client', "su root -c '/usr/local/bin/cassandra-backup-runner-call.sh -s'")
774 } catch (Exception er) {
775 throw new Exception('Cassandra failed to backup. Please fix it before continuing.')
776 }
777}
778
779def backupContrail(pepperEnv) {
780 backupZookeeper(pepperEnv)
781 backupCassandra(pepperEnv)
782}
783
784// cassandra and zookeeper
785def restoreContrailDb(pepperEnv) {
786 def salt = new com.mirantis.mk.Salt()
787 def common = new com.mirantis.mk.Common()
788 build job: "deploy-zookeeper-restore", parameters: [
789 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
790 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: SALT_MASTER_URL]
791 ]
792 build job: "deploy-cassandra-db-restore", parameters: [
793 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
794 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: SALT_MASTER_URL]
795 ]
796}
797
Jiri Broulikd2dd5632018-03-27 15:44:56 +0200798def verifyAPIs(pepperEnv, target) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100799 def salt = new com.mirantis.mk.Salt()
800 def common = new com.mirantis.mk.Common()
William Konitzerb147e842018-06-15 15:03:40 -0500801 def cmds = ["openstack service list",
802 "openstack image list",
803 "openstack flavor list",
804 "openstack compute service list",
805 "openstack server list",
806 "openstack network list",
807 "openstack volume list",
808 "openstack orchestration service list"]
809 def sourcerc = ". /root/keystonercv3;"
810 def cmdOut = ">/dev/null 2>&1;echo \$?"
811 for (c in cmds) {
812 def command = sourcerc + c + cmdOut
813 def out = salt.cmdRun(pepperEnv, target, "${command}")
814 if (!out.toString().toLowerCase().contains('0')) {
815 common.errorMsg(out)
816 if (INTERACTIVE.toBoolean()) {
817 input message: "APIs are not working as expected. Please fix it manually."
818 } else {
819 throw new Exception("APIs are not working as expected")
820 }
Jiri Broulikad606d02018-03-28 14:22:43 +0200821 }
822 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100823}
824
Jiri Broulikad606d02018-03-28 14:22:43 +0200825def verifyGalera(pepperEnv, target, count=0, maxRetries=200) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100826 def salt = new com.mirantis.mk.Salt()
827 def common = new com.mirantis.mk.Common()
Jiri Broulikad606d02018-03-28 14:22:43 +0200828 def out
829 while(count < maxRetries) {
830 try {
William Konitzer667143f2018-06-15 14:21:17 -0500831 out = salt.getReturnValues(salt.cmdRun(pepperEnv, target, 'salt-call -l quiet mysql.status | grep -A1 wsrep_cluster_size'))
Jiri Broulikad606d02018-03-28 14:22:43 +0200832 } catch (Exception er) {
833 common.infoMsg(er)
834 }
835 if ((!out.toString().contains('wsrep_cluster_size')) || (out.toString().contains('0'))) {
836 count++
837 if (count == maxRetries) {
838 if (INTERACTIVE.toBoolean()) {
839 input message: "Galera is not working as expected. Please check it and fix it first before clicking on PROCEED."
840 } else {
841 common.errorMsg(out)
842 throw new Exception("Galera is not working as expected")
843 }
844 }
845 sleep(time: 500, unit: 'MILLISECONDS')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100846 } else {
Jiri Broulikad606d02018-03-28 14:22:43 +0200847 break
Jiri Broulik60dcab32018-03-08 17:42:06 +0100848 }
849 }
850}
851
852def verifyContrail(pepperEnv, target) {
853 def salt = new com.mirantis.mk.Salt()
854 def common = new com.mirantis.mk.Common()
855 salt.commandStatus(pepperEnv, target, "contrail-status | grep -v == | grep -v \'disabled on boot\' | grep -v nodemgr | grep -v active | grep -v backup", null, false)
856}
857
858
859def verifyService(pepperEnv, target, service) {
860 def salt = new com.mirantis.mk.Salt()
861 def common = new com.mirantis.mk.Common()
862 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
863 for (t in targetHosts) {
864 try {
865 salt.commandStatus(pepperEnv, t, "service ${service} status", 'running')
866 } catch (Exception er) {
867 common.errorMsg(er)
868 if (INTERACTIVE.toBoolean()) {
869 input message: "${service} service is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
870 } else {
871 throw new Exception("${service} service is not running correctly on ${t}")
872 }
873 }
874 }
875}
876
877def verifyCeph(pepperEnv, target, type) {
878 def salt = new com.mirantis.mk.Salt()
879 def common = new com.mirantis.mk.Common()
880 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
881 for (t in targetHosts) {
882 def hostname = salt.getReturnValues(salt.getPillar(pepperEnv, t, 'linux:network:hostname'))
883 try {
884 salt.commandStatus(pepperEnv, t, "systemctl status ceph-${type}${hostname}", 'running')
885 } catch (Exception er) {
886 common.errorMsg(er)
887 if (INTERACTIVE.toBoolean()) {
888 input message: "Ceph-${type}${hostname} service is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
889 } else {
890 throw new Exception("Ceph-${type}${hostname} service is not running correctly on ${t}")
891 }
892 }
893 }
894}
895
896def verifyCephOsds(pepperEnv, target) {
897 def salt = new com.mirantis.mk.Salt()
898 def common = new com.mirantis.mk.Common()
899 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
900 for (t in targetHosts) {
901 def osd_ids = []
902 // get list of osd disks of the host
903 salt.runSaltProcessStep(pepperEnv, t, 'saltutil.sync_grains', [], null, true, 5)
904 def cephGrain = salt.getGrain(pepperEnv, t, 'ceph')
905 if(cephGrain['return'].isEmpty()){
906 throw new Exception("Ceph salt grain cannot be found!")
907 }
908 common.print(cephGrain)
909 def ceph_disks = cephGrain['return'][0].values()[0].values()[0]['ceph_disk']
910 for (i in ceph_disks) {
911 def osd_id = i.getKey().toString()
912 osd_ids.add('osd.' + osd_id)
913 print("Will check osd." + osd_id)
914 }
915 for (i in osd_ids) {
916 try {
917 salt.commandStatus(pepperEnv, t, "ceph osd tree | grep -w ${i}", 'up')
918 } catch (Exception er) {
919 common.errorMsg(er)
920 if (INTERACTIVE.toBoolean()) {
921 input message: "Ceph ${i} is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
922 } else {
923 throw new Exception("Ceph ${i} is not running correctly on ${t}")
924 }
925 }
926 }
927 }
928}
929
930
931timeout(time: 12, unit: 'HOURS') {
932 node() {
933 try {
Andrei Danin3f46c582018-10-23 16:32:18 -0700934 if(RUN_CVP_TESTS.toBoolean() == true){
Richard Felklaedc89b2018-06-26 23:50:49 +0200935 stage('Run CVP tests before upgrade.') {
936 build job: "cvp-sanity"
937 build job: "cvp-func"
938 build job: "cvp-ha"
939 build job: "cvp-perf"
940 }
941 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100942
943 stage('Setup virtualenv for Pepper') {
944 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
945 }
946
947 // TODO, add possibility to update just specific components like kernel, openstack, contrail, ovs, rabbitmq, galera, etc.
948
949 /*
950 * Update section
951 */
Vasyl Saienkod63721d2018-11-13 18:04:41 +0200952
953 // Go through applications that using orchestrated deployment.
954 orchestrate.OrchestrateApplications(pepperEnv, "I@salt:master", "orchestration.deploy.applications")
955
Jiri Broulik60dcab32018-03-08 17:42:06 +0100956 if (updates.contains("cfg")) {
957 def target = 'I@salt:master'
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200958 def type = 'cfg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100959 if (salt.testTarget(pepperEnv, target)) {
960 def master = salt.getReturnValues(salt.getPillar(pepperEnv, target, 'linux:network:hostname'))
Jiri Broulik827d0112018-04-25 16:00:07 +0200961 getNodeProvider(pepperEnv, master, 'master')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100962 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
963 virsh.liveSnapshotPresent(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME)
Jiri Broulik906e9972018-03-26 16:12:00 +0200964 } else {
965 saltMasterBackup(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100966 }
967 if (PER_NODE.toBoolean()) {
968 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
969 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200970 updatePkgs(pepperEnv, t, type)
971 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100972 }
973 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200974 updatePkgs(pepperEnv, target, type)
975 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100976 }
977 }
978 }
979
Jiri Broulik60dcab32018-03-08 17:42:06 +0100980 if (updates.contains("msg")) {
981 def target = MSG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200982 def type = 'msg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100983 if (salt.testTarget(pepperEnv, target)) {
984 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200985 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100986 }
987 if (PER_NODE.toBoolean()) {
988 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
989 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200990 updatePkgs(pepperEnv, t, type)
991 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100992 }
993 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200994 updatePkgs(pepperEnv, target, type)
995 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100996 }
997 verifyService(pepperEnv, target, 'rabbitmq-server')
998 }
999 }
1000
1001 if (updates.contains("dbs")) {
1002 def target = DBS_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001003 def type = 'dbs'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001004 if (salt.testTarget(pepperEnv, target)) {
1005 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001006 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001007 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001008 }
Jiri Broulik7ba05e42018-04-06 11:39:25 +02001009 if (reboots.contains(type) || PER_NODE.toBoolean()) {
Jiri Broulik60dcab32018-03-08 17:42:06 +01001010 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001011 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001012 updatePkgs(pepperEnv, t, type)
1013 highstate(pepperEnv, t, type)
Jiri Broulikad606d02018-03-28 14:22:43 +02001014 verifyGalera(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001015 }
1016 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001017 updatePkgs(pepperEnv, target, type)
1018 highstate(pepperEnv, target, type)
Jiri Broulikad606d02018-03-28 14:22:43 +02001019 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001020 }
Jiri Broulik60dcab32018-03-08 17:42:06 +01001021 }
1022 }
1023
1024 if (updates.contains("ntw")) {
1025 def target = NTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001026 def type = 'ntw'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001027 if (salt.testTarget(pepperEnv, target)) {
1028 backupContrail(pepperEnv)
1029 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001030 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001031 }
1032 if (PER_NODE.toBoolean()) {
1033 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1034 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001035 updatePkgs(pepperEnv, t, type)
1036 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001037 verifyContrail(pepperEnv, t)
1038 }
1039 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001040 updatePkgs(pepperEnv, target, type)
1041 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001042 verifyContrail(pepperEnv, target)
1043 }
1044 }
1045 }
1046
1047 if (updates.contains("nal")) {
1048 def target = NAL_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001049 def type = 'nal'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001050 if (salt.testTarget(pepperEnv, target)) {
1051 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001052 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001053 }
1054 if (PER_NODE.toBoolean()) {
1055 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1056 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001057 updatePkgs(pepperEnv, t, type)
1058 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001059 }
1060 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001061 updatePkgs(pepperEnv, target, type)
1062 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001063 }
1064 verifyContrail(pepperEnv, target)
1065 }
1066 }
1067
Jiri Broulik60dcab32018-03-08 17:42:06 +01001068 if (updates.contains("cmn")) {
1069 def target = CMN_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001070 def type = 'cmn'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001071 if (salt.testTarget(pepperEnv, target)) {
1072 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001073 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001074 } else {
Jiri Broulik906e9972018-03-26 16:12:00 +02001075 backupCeph(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001076 }
1077 if (PER_NODE.toBoolean()) {
1078 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1079 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001080 updatePkgs(pepperEnv, t, type)
1081 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001082 }
1083 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001084 updatePkgs(pepperEnv, target, type)
1085 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001086 }
1087 verifyCeph(pepperEnv, target, 'mon@')
1088 }
1089 }
1090
1091 if (updates.contains("rgw")) {
1092 def target = RGW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001093 def type = 'rgw'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001094 if (salt.testTarget(pepperEnv, target)) {
1095 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001096 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001097 }
1098 if (PER_NODE.toBoolean()) {
1099 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1100 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001101 updatePkgs(pepperEnv, t, type)
1102 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001103 }
1104 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001105 updatePkgs(pepperEnv, target, type)
1106 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001107 }
1108 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1109 }
1110 }
1111
1112 if (updates.contains("log")) {
1113 def target = LOG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001114 def type = 'log'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001115 if (salt.testTarget(pepperEnv, target)) {
1116 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001117 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001118 }
1119 if (PER_NODE.toBoolean()) {
1120 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1121 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001122 updatePkgs(pepperEnv, t, type)
1123 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001124 }
1125 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001126 updatePkgs(pepperEnv, target, type)
1127 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001128 }
1129 }
1130 }
1131
1132 if (updates.contains("mon")) {
1133 def target = MON_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001134 def type = 'mon'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001135 if (salt.testTarget(pepperEnv, target)) {
1136 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001137 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001138 }
1139 if (PER_NODE.toBoolean()) {
1140 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1141 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001142 updatePkgs(pepperEnv, t, type)
1143 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001144 }
1145 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001146 updatePkgs(pepperEnv, target, type)
1147 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001148 }
1149 }
1150 }
1151
1152 if (updates.contains("mtr")) {
1153 def target = MTR_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001154 def type = 'mtr'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001155 if (salt.testTarget(pepperEnv, target)) {
1156 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001157 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001158 }
1159 if (PER_NODE.toBoolean()) {
1160 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1161 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001162 updatePkgs(pepperEnv, t, type)
1163 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001164 }
1165 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001166 updatePkgs(pepperEnv, target, type)
1167 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001168 }
1169 }
1170 }
1171
1172 if (updates.contains("cid")) {
1173 def target = CID_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001174 def type = 'cid'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001175 if (salt.testTarget(pepperEnv, target)) {
1176 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001177 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001178 }
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001179 updatePkgs(pepperEnv, target, type)
1180 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001181 verifyService(pepperEnv, target, 'docker')
1182 }
1183 }
1184
Jiri Broulik60dcab32018-03-08 17:42:06 +01001185 if (updates.contains("kvm")) {
1186 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001187 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001188 if (salt.testTarget(pepperEnv, target)) {
1189 if (PER_NODE.toBoolean()) {
1190 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1191 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001192 updatePkgs(pepperEnv, t, type)
1193 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001194 }
1195 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001196 updatePkgs(pepperEnv, target, type)
1197 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001198 }
1199 verifyService(pepperEnv, target, 'libvirt-bin')
1200 }
1201 }
1202
1203 if (updates.contains("osd")) {
1204 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001205 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001206 if (salt.testTarget(pepperEnv, target)) {
1207 if (PER_NODE.toBoolean()) {
1208 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1209 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001210 updatePkgs(pepperEnv, t, type)
1211 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001212 }
1213 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001214 updatePkgs(pepperEnv, target, type)
1215 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001216 }
1217 verifyCephOsds(pepperEnv, target)
1218 }
1219 }
1220
Jiri Broulik60dcab32018-03-08 17:42:06 +01001221 /*
1222 * Rollback section
1223 */
Jiri Broulik906e9972018-03-26 16:12:00 +02001224 /* if (rollbacks.contains("cfg")) {
Jiri Broulik60dcab32018-03-08 17:42:06 +01001225 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1226 stage('ROLLBACK_CFG') {
1227 input message: "To rollback CFG nodes run the following commands on kvm nodes hosting the CFG nodes: virsh destroy cfg0X.domain; virsh define /var/lib/libvirt/images/cfg0X.domain.xml; virsh start cfg0X.domain; virsh snapshot-delete cfg0X.domain --metadata ${SNAPSHOT_NAME}; rm /var/lib/libvirt/images/cfg0X.domain.${SNAPSHOT_NAME}.qcow2; rm /var/lib/libvirt/images/cfg0X.domain.xml; At the end restart 'docker' service on all cicd nodes and run 'linux.system.repo' Salt states on cicd nodes. After running the previous commands current pipeline job will be killed."
1228 //rollbackSaltMaster(pepperEnv, 'I@salt:master')
1229 //finishSaltMasterRollback(pepperEnv, 'I@salt:master')
1230 }
1231 }
1232 } */
1233
Jiri Broulik60dcab32018-03-08 17:42:06 +01001234 if (rollbacks.contains("msg")) {
1235 def target = MSG_TARGET
1236 if (salt.testTarget(pepperEnv, target)) {
1237 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1238 rollback(pepperEnv, target, 'msg')
1239 salt.enforceState(pepperEnv, target, 'rabbitmq')
1240 verifyService(pepperEnv, target, 'rabbitmq-server')
1241 } else {
1242 removeNode(pepperEnv, target, 'msg')
1243 }
1244 }
1245 }
1246
1247 if (rollbacks.contains("dbs")) {
1248 def target = DBS_TARGET
1249 if (salt.testTarget(pepperEnv, target)) {
1250 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1251 rollback(pepperEnv, target, 'dbs')
1252 clusterGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001253 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001254 } else {
1255 removeNode(pepperEnv, target, 'dbs')
1256 }
1257 }
1258 }
1259
1260 if (rollbacks.contains("ntw")) {
1261 def target = NTW_TARGET
1262 if (salt.testTarget(pepperEnv, target)) {
1263 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1264 rollback(pepperEnv, target, 'ntw')
1265 verifyContrail(pepperEnv, target)
1266 } else {
1267 removeNode(pepperEnv, target, 'ntw')
1268 }
1269 }
1270 }
1271
1272 if (rollbacks.contains("nal")) {
1273 def target = NAL_TARGET
1274 if (salt.testTarget(pepperEnv, target)) {
1275 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1276 rollback(pepperEnv, target, 'nal')
1277 verifyContrail(pepperEnv, target)
1278 } else {
1279 removeNode(pepperEnv, target, 'nal')
1280 }
1281 }
1282 }
1283
Jiri Broulik60dcab32018-03-08 17:42:06 +01001284 if (rollbacks.contains("cmn")) {
1285 def target = CMN_TARGET
1286 if (salt.testTarget(pepperEnv, target)) {
1287 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1288 rollback(pepperEnv, target, 'cmn')
1289 verifyCeph(pepperEnv, target, 'mon@')
1290 } else {
1291 removeNode(pepperEnv, target, 'cmn')
1292 }
1293 }
1294 }
1295
1296 if (rollbacks.contains("rgw")) {
1297 def target = RGW_TARGET
1298 if (salt.testTarget(pepperEnv, target)) {
1299 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1300 rollback(pepperEnv, target, 'rgw')
1301 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1302 } else {
1303 removeNode(pepperEnv, target, 'rgw')
1304 }
1305 }
1306 }
1307
1308 if (rollbacks.contains("log")) {
1309 def target = LOG_TARGET
1310 if (salt.testTarget(pepperEnv, target)) {
1311 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1312 rollback(pepperEnv, target, 'log')
1313 } else {
1314 removeNode(pepperEnv, target, 'log')
1315 }
1316 }
1317 }
1318
1319 if (rollbacks.contains("mon")) {
1320 def target = MON_TARGET
1321 if (salt.testTarget(pepperEnv, target)) {
1322 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1323 rollback(pepperEnv, target, 'mon')
1324 } else {
1325 removeNode(pepperEnv, target, 'mon')
1326 }
1327 }
1328 }
1329
1330 if (rollbacks.contains("mtr")) {
1331 def target = MTR_TARGET
1332 if (salt.testTarget(pepperEnv, target)) {
1333 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1334 rollback(pepperEnv, target, 'mtr')
1335 } else {
1336 removeNode(pepperEnv, target, 'mtr')
1337 }
1338 }
1339 }
1340 /*
1341 if (ROLLBACK_CID.toBoolean()) {
1342 def target = 'cid*'
1343 if (salt.testTarget(pepperEnv, target)) {
1344 stage('ROLLBACK_CID') {
1345 input message: "To rollback CICD nodes run the following commands on kvm nodes hosting the cicd nodes: virsh destroy cid0X.domain; virsh define /var/lib/libvirt/images/cid0X.domain.xml; virsh start cid0X.domain; virsh snapshot-delete cid0X.domain --metadata ${SNAPSHOT_NAME}; rm /var/lib/libvirt/images/cid0X.domain.${SNAPSHOT_NAME}.qcow2; rm /var/lib/libvirt/images/cid0X.domain.xml; At the end restart 'docker' service on all cicd nodes and run 'linux.system.repo' Salt states on cicd nodes. After running the previous commands current pipeline job will be killed."
1346 }
1347 }
1348 } */
1349
Jiri Broulik60dcab32018-03-08 17:42:06 +01001350 if (rollbacks.contains("kvm")) {
1351 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001352 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001353 if (salt.testTarget(pepperEnv, target)) {
1354 if (PER_NODE.toBoolean()) {
1355 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1356 for (t in targetHosts) {
1357 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001358 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001359 }
1360 } else {
1361 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001362 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001363 }
1364 verifyService(pepperEnv, target, 'libvirt-bin')
1365 }
1366 }
1367
1368 if (rollbacks.contains("osd")) {
1369 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001370 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001371 if (salt.testTarget(pepperEnv, target)) {
1372 if (PER_NODE.toBoolean()) {
1373 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1374 for (t in targetHosts) {
1375 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001376 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001377 }
1378 } else {
1379 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001380 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001381 }
1382 verifyCephOsds(pepperEnv, target)
1383 }
1384 }
1385
Jiri Broulik60dcab32018-03-08 17:42:06 +01001386 /*
1387 * Merge snapshots section
1388 */
1389 if (merges.contains("cfg")) {
1390 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1391 mergeSnapshot(pepperEnv, 'I@salt:master')
1392 }
1393 }
1394
Jiri Broulik60dcab32018-03-08 17:42:06 +01001395 if (merges.contains("msg")) {
1396 if (salt.testTarget(pepperEnv, MSG_TARGET)) {
1397 mergeSnapshot(pepperEnv, MSG_TARGET, 'msg')
Jiri Broulik906e9972018-03-26 16:12:00 +02001398 verifyService(pepperEnv, MSG_TARGET, 'rabbitmq-server')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001399 }
1400 }
1401
1402 if (merges.contains("dbs")) {
1403 if (salt.testTarget(pepperEnv, DBS_TARGET)) {
1404 mergeSnapshot(pepperEnv, DBS_TARGET, 'dbs')
Jiri Broulikad606d02018-03-28 14:22:43 +02001405 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik906e9972018-03-26 16:12:00 +02001406 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001407 }
1408 }
1409
1410 if (merges.contains("ntw")) {
1411 if (salt.testTarget(pepperEnv, NTW_TARGET)) {
1412 mergeSnapshot(pepperEnv, NTW_TARGET, 'ntw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001413 verifyContrail(pepperEnv, NTW_TARGET)
1414 backupContrail(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001415 }
1416 }
1417
1418 if (merges.contains("nal")) {
1419 if (salt.testTarget(pepperEnv, NAL_TARGET)) {
1420 mergeSnapshot(pepperEnv, NAL_TARGET, 'nal')
Jiri Broulik906e9972018-03-26 16:12:00 +02001421 verifyContrail(pepperEnv, NAL_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001422 }
1423 }
1424
Jiri Broulik60dcab32018-03-08 17:42:06 +01001425 if (merges.contains("cmn")) {
1426 if (salt.testTarget(pepperEnv, CMN_TARGET)) {
1427 mergeSnapshot(pepperEnv, CMN_TARGET, 'cmn')
Jiri Broulik906e9972018-03-26 16:12:00 +02001428 verifyCeph(pepperEnv, CMN_TARGET, 'mon@')
1429 backupCeph(pepperEnv, CMN_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001430 }
1431 }
1432
1433 if (merges.contains("rgw")) {
1434 if (salt.testTarget(pepperEnv, RGW_TARGET)) {
1435 mergeSnapshot(pepperEnv, RGW_TARGET, 'rgw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001436 verifyCeph(pepperEnv, RGW_TARGET, 'radosgw@rgw.')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001437 }
1438 }
1439
1440 if (merges.contains("log")) {
1441 if (salt.testTarget(pepperEnv, LOG_TARGET)) {
Jiri Broulik3bd7adf2018-06-29 09:17:28 +02001442 mergeSnapshot(pepperEnv, LOG_TARGET, 'log')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001443 }
1444 }
1445
1446 if (merges.contains("mon")) {
1447 if (salt.testTarget(pepperEnv, MON_TARGET)) {
1448 mergeSnapshot(pepperEnv, MON_TARGET, 'mon')
1449 }
1450 }
1451
1452 if (merges.contains("mtr")) {
1453 if (salt.testTarget(pepperEnv, MTR_TARGET)) {
1454 mergeSnapshot(pepperEnv, MTR_TARGET, 'mtr')
1455 }
1456 }
1457
1458 if (merges.contains("cid")) {
1459 if (salt.testTarget(pepperEnv, CID_TARGET)) {
1460 mergeSnapshot(pepperEnv, CID_TARGET, 'cid')
Jiri Broulik906e9972018-03-26 16:12:00 +02001461 verifyService(pepperEnv, CID_TARGET, 'docker')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001462 }
1463 }
1464
1465 if (RESTORE_GALERA.toBoolean()) {
1466 restoreGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001467 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001468 }
1469
1470 if (RESTORE_CONTRAIL_DB.toBoolean()) {
1471 restoreContrailDb(pepperEnv)
Jiri Broulik906e9972018-03-26 16:12:00 +02001472 // verification is already present in restore pipelines
Jiri Broulik60dcab32018-03-08 17:42:06 +01001473 }
1474
Andrei Danin3f46c582018-10-23 16:32:18 -07001475 if(RUN_CVP_TESTS.toBoolean() == true){
Richard Felklaedc89b2018-06-26 23:50:49 +02001476 stage('Run CVP tests after upgrade.') {
1477 build job: "cvp-sanity"
1478 build job: "cvp-func"
1479 build job: "cvp-ha"
1480 build job: "cvp-perf"
1481 }
1482 }
1483
Jiri Broulik60dcab32018-03-08 17:42:06 +01001484 } catch (Throwable e) {
1485 // If there was an error or exception thrown, the build failed
1486 currentBuild.result = "FAILURE"
1487 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
1488 throw e
1489 }
1490 }
1491}