blob: b76c4b2f6dc09975f8ee8138210e73292c82ec6b [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)
Mateusz Los2ae66db2020-04-28 16:36:11 +0200900 def device_grain_name = "ceph_disk"
Jiri Broulik60dcab32018-03-08 17:42:06 +0100901 for (t in targetHosts) {
902 def osd_ids = []
903 // get list of osd disks of the host
904 salt.runSaltProcessStep(pepperEnv, t, 'saltutil.sync_grains', [], null, true, 5)
905 def cephGrain = salt.getGrain(pepperEnv, t, 'ceph')
906 if(cephGrain['return'].isEmpty()){
907 throw new Exception("Ceph salt grain cannot be found!")
908 }
909 common.print(cephGrain)
mjedynski12955c72019-12-09 15:17:58 +0100910 def ceph_disks = cephGrain['return'][0].values()[0].values()[0][device_grain_name]
Jiri Broulik60dcab32018-03-08 17:42:06 +0100911 for (i in ceph_disks) {
912 def osd_id = i.getKey().toString()
913 osd_ids.add('osd.' + osd_id)
914 print("Will check osd." + osd_id)
915 }
916 for (i in osd_ids) {
917 try {
918 salt.commandStatus(pepperEnv, t, "ceph osd tree | grep -w ${i}", 'up')
919 } catch (Exception er) {
920 common.errorMsg(er)
921 if (INTERACTIVE.toBoolean()) {
922 input message: "Ceph ${i} is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
923 } else {
924 throw new Exception("Ceph ${i} is not running correctly on ${t}")
925 }
926 }
927 }
928 }
929}
930
931
932timeout(time: 12, unit: 'HOURS') {
933 node() {
934 try {
Andrei Danin3f46c582018-10-23 16:32:18 -0700935 if(RUN_CVP_TESTS.toBoolean() == true){
Richard Felklaedc89b2018-06-26 23:50:49 +0200936 stage('Run CVP tests before upgrade.') {
937 build job: "cvp-sanity"
938 build job: "cvp-func"
939 build job: "cvp-ha"
940 build job: "cvp-perf"
941 }
942 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100943
944 stage('Setup virtualenv for Pepper') {
945 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
946 }
947
948 // TODO, add possibility to update just specific components like kernel, openstack, contrail, ovs, rabbitmq, galera, etc.
949
950 /*
951 * Update section
952 */
Vasyl Saienkod63721d2018-11-13 18:04:41 +0200953
954 // Go through applications that using orchestrated deployment.
955 orchestrate.OrchestrateApplications(pepperEnv, "I@salt:master", "orchestration.deploy.applications")
956
Jiri Broulik60dcab32018-03-08 17:42:06 +0100957 if (updates.contains("cfg")) {
958 def target = 'I@salt:master'
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200959 def type = 'cfg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100960 if (salt.testTarget(pepperEnv, target)) {
961 def master = salt.getReturnValues(salt.getPillar(pepperEnv, target, 'linux:network:hostname'))
Jiri Broulik827d0112018-04-25 16:00:07 +0200962 getNodeProvider(pepperEnv, master, 'master')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100963 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
964 virsh.liveSnapshotPresent(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME)
Jiri Broulik906e9972018-03-26 16:12:00 +0200965 } else {
966 saltMasterBackup(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100967 }
968 if (PER_NODE.toBoolean()) {
969 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
970 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200971 updatePkgs(pepperEnv, t, type)
972 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100973 }
974 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200975 updatePkgs(pepperEnv, target, type)
976 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100977 }
978 }
979 }
980
Jiri Broulik60dcab32018-03-08 17:42:06 +0100981 if (updates.contains("msg")) {
982 def target = MSG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200983 def type = 'msg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100984 if (salt.testTarget(pepperEnv, target)) {
985 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200986 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100987 }
988 if (PER_NODE.toBoolean()) {
989 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
990 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200991 updatePkgs(pepperEnv, t, type)
992 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100993 }
994 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200995 updatePkgs(pepperEnv, target, type)
996 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100997 }
998 verifyService(pepperEnv, target, 'rabbitmq-server')
999 }
1000 }
1001
1002 if (updates.contains("dbs")) {
1003 def target = DBS_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001004 def type = 'dbs'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001005 if (salt.testTarget(pepperEnv, target)) {
1006 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001007 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001008 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001009 }
Jiri Broulik7ba05e42018-04-06 11:39:25 +02001010 if (reboots.contains(type) || PER_NODE.toBoolean()) {
Jiri Broulik60dcab32018-03-08 17:42:06 +01001011 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001012 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001013 updatePkgs(pepperEnv, t, type)
1014 highstate(pepperEnv, t, type)
Jiri Broulikad606d02018-03-28 14:22:43 +02001015 verifyGalera(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001016 }
1017 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001018 updatePkgs(pepperEnv, target, type)
1019 highstate(pepperEnv, target, type)
Jiri Broulikad606d02018-03-28 14:22:43 +02001020 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001021 }
Jiri Broulik60dcab32018-03-08 17:42:06 +01001022 }
1023 }
1024
1025 if (updates.contains("ntw")) {
1026 def target = NTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001027 def type = 'ntw'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001028 if (salt.testTarget(pepperEnv, target)) {
1029 backupContrail(pepperEnv)
1030 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001031 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001032 }
1033 if (PER_NODE.toBoolean()) {
1034 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1035 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001036 updatePkgs(pepperEnv, t, type)
1037 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001038 verifyContrail(pepperEnv, t)
1039 }
1040 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001041 updatePkgs(pepperEnv, target, type)
1042 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001043 verifyContrail(pepperEnv, target)
1044 }
1045 }
1046 }
1047
1048 if (updates.contains("nal")) {
1049 def target = NAL_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001050 def type = 'nal'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001051 if (salt.testTarget(pepperEnv, target)) {
1052 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001053 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001054 }
1055 if (PER_NODE.toBoolean()) {
1056 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1057 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001058 updatePkgs(pepperEnv, t, type)
1059 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001060 }
1061 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001062 updatePkgs(pepperEnv, target, type)
1063 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001064 }
1065 verifyContrail(pepperEnv, target)
1066 }
1067 }
1068
Jiri Broulik60dcab32018-03-08 17:42:06 +01001069 if (updates.contains("cmn")) {
1070 def target = CMN_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001071 def type = 'cmn'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001072 if (salt.testTarget(pepperEnv, target)) {
1073 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001074 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001075 } else {
Jiri Broulik906e9972018-03-26 16:12:00 +02001076 backupCeph(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001077 }
1078 if (PER_NODE.toBoolean()) {
1079 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1080 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001081 updatePkgs(pepperEnv, t, type)
1082 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001083 }
1084 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001085 updatePkgs(pepperEnv, target, type)
1086 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001087 }
1088 verifyCeph(pepperEnv, target, 'mon@')
1089 }
1090 }
1091
1092 if (updates.contains("rgw")) {
1093 def target = RGW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001094 def type = 'rgw'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001095 if (salt.testTarget(pepperEnv, target)) {
1096 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001097 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001098 }
1099 if (PER_NODE.toBoolean()) {
1100 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1101 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001102 updatePkgs(pepperEnv, t, type)
1103 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001104 }
1105 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001106 updatePkgs(pepperEnv, target, type)
1107 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001108 }
1109 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1110 }
1111 }
1112
1113 if (updates.contains("log")) {
1114 def target = LOG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001115 def type = 'log'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001116 if (salt.testTarget(pepperEnv, target)) {
1117 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001118 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001119 }
1120 if (PER_NODE.toBoolean()) {
1121 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1122 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001123 updatePkgs(pepperEnv, t, type)
1124 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001125 }
1126 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001127 updatePkgs(pepperEnv, target, type)
1128 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001129 }
1130 }
1131 }
1132
1133 if (updates.contains("mon")) {
1134 def target = MON_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001135 def type = 'mon'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001136 if (salt.testTarget(pepperEnv, target)) {
1137 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001138 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001139 }
1140 if (PER_NODE.toBoolean()) {
1141 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1142 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001143 updatePkgs(pepperEnv, t, type)
1144 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001145 }
1146 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001147 updatePkgs(pepperEnv, target, type)
1148 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001149 }
1150 }
1151 }
1152
1153 if (updates.contains("mtr")) {
1154 def target = MTR_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001155 def type = 'mtr'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001156 if (salt.testTarget(pepperEnv, target)) {
1157 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001158 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001159 }
1160 if (PER_NODE.toBoolean()) {
1161 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1162 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001163 updatePkgs(pepperEnv, t, type)
1164 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001165 }
1166 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001167 updatePkgs(pepperEnv, target, type)
1168 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001169 }
1170 }
1171 }
1172
1173 if (updates.contains("cid")) {
1174 def target = CID_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001175 def type = 'cid'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001176 if (salt.testTarget(pepperEnv, target)) {
1177 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001178 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001179 }
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001180 updatePkgs(pepperEnv, target, type)
1181 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001182 verifyService(pepperEnv, target, 'docker')
1183 }
1184 }
1185
Jiri Broulik60dcab32018-03-08 17:42:06 +01001186 if (updates.contains("kvm")) {
1187 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001188 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001189 if (salt.testTarget(pepperEnv, target)) {
1190 if (PER_NODE.toBoolean()) {
1191 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1192 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001193 updatePkgs(pepperEnv, t, type)
1194 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001195 }
1196 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001197 updatePkgs(pepperEnv, target, type)
1198 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001199 }
1200 verifyService(pepperEnv, target, 'libvirt-bin')
1201 }
1202 }
1203
1204 if (updates.contains("osd")) {
1205 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001206 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001207 if (salt.testTarget(pepperEnv, target)) {
1208 if (PER_NODE.toBoolean()) {
1209 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1210 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001211 updatePkgs(pepperEnv, t, type)
1212 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001213 }
1214 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001215 updatePkgs(pepperEnv, target, type)
1216 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001217 }
1218 verifyCephOsds(pepperEnv, target)
1219 }
1220 }
1221
Jiri Broulik60dcab32018-03-08 17:42:06 +01001222 /*
1223 * Rollback section
1224 */
Jiri Broulik906e9972018-03-26 16:12:00 +02001225 /* if (rollbacks.contains("cfg")) {
Jiri Broulik60dcab32018-03-08 17:42:06 +01001226 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1227 stage('ROLLBACK_CFG') {
1228 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."
1229 //rollbackSaltMaster(pepperEnv, 'I@salt:master')
1230 //finishSaltMasterRollback(pepperEnv, 'I@salt:master')
1231 }
1232 }
1233 } */
1234
Jiri Broulik60dcab32018-03-08 17:42:06 +01001235 if (rollbacks.contains("msg")) {
1236 def target = MSG_TARGET
1237 if (salt.testTarget(pepperEnv, target)) {
1238 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1239 rollback(pepperEnv, target, 'msg')
1240 salt.enforceState(pepperEnv, target, 'rabbitmq')
1241 verifyService(pepperEnv, target, 'rabbitmq-server')
1242 } else {
1243 removeNode(pepperEnv, target, 'msg')
1244 }
1245 }
1246 }
1247
1248 if (rollbacks.contains("dbs")) {
1249 def target = DBS_TARGET
1250 if (salt.testTarget(pepperEnv, target)) {
1251 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1252 rollback(pepperEnv, target, 'dbs')
1253 clusterGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001254 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001255 } else {
1256 removeNode(pepperEnv, target, 'dbs')
1257 }
1258 }
1259 }
1260
1261 if (rollbacks.contains("ntw")) {
1262 def target = NTW_TARGET
1263 if (salt.testTarget(pepperEnv, target)) {
1264 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1265 rollback(pepperEnv, target, 'ntw')
1266 verifyContrail(pepperEnv, target)
1267 } else {
1268 removeNode(pepperEnv, target, 'ntw')
1269 }
1270 }
1271 }
1272
1273 if (rollbacks.contains("nal")) {
1274 def target = NAL_TARGET
1275 if (salt.testTarget(pepperEnv, target)) {
1276 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1277 rollback(pepperEnv, target, 'nal')
1278 verifyContrail(pepperEnv, target)
1279 } else {
1280 removeNode(pepperEnv, target, 'nal')
1281 }
1282 }
1283 }
1284
Jiri Broulik60dcab32018-03-08 17:42:06 +01001285 if (rollbacks.contains("cmn")) {
1286 def target = CMN_TARGET
1287 if (salt.testTarget(pepperEnv, target)) {
1288 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1289 rollback(pepperEnv, target, 'cmn')
1290 verifyCeph(pepperEnv, target, 'mon@')
1291 } else {
1292 removeNode(pepperEnv, target, 'cmn')
1293 }
1294 }
1295 }
1296
1297 if (rollbacks.contains("rgw")) {
1298 def target = RGW_TARGET
1299 if (salt.testTarget(pepperEnv, target)) {
1300 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1301 rollback(pepperEnv, target, 'rgw')
1302 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1303 } else {
1304 removeNode(pepperEnv, target, 'rgw')
1305 }
1306 }
1307 }
1308
1309 if (rollbacks.contains("log")) {
1310 def target = LOG_TARGET
1311 if (salt.testTarget(pepperEnv, target)) {
1312 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1313 rollback(pepperEnv, target, 'log')
1314 } else {
1315 removeNode(pepperEnv, target, 'log')
1316 }
1317 }
1318 }
1319
1320 if (rollbacks.contains("mon")) {
1321 def target = MON_TARGET
1322 if (salt.testTarget(pepperEnv, target)) {
1323 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1324 rollback(pepperEnv, target, 'mon')
1325 } else {
1326 removeNode(pepperEnv, target, 'mon')
1327 }
1328 }
1329 }
1330
1331 if (rollbacks.contains("mtr")) {
1332 def target = MTR_TARGET
1333 if (salt.testTarget(pepperEnv, target)) {
1334 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1335 rollback(pepperEnv, target, 'mtr')
1336 } else {
1337 removeNode(pepperEnv, target, 'mtr')
1338 }
1339 }
1340 }
1341 /*
1342 if (ROLLBACK_CID.toBoolean()) {
1343 def target = 'cid*'
1344 if (salt.testTarget(pepperEnv, target)) {
1345 stage('ROLLBACK_CID') {
1346 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."
1347 }
1348 }
1349 } */
1350
Jiri Broulik60dcab32018-03-08 17:42:06 +01001351 if (rollbacks.contains("kvm")) {
1352 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001353 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001354 if (salt.testTarget(pepperEnv, target)) {
1355 if (PER_NODE.toBoolean()) {
1356 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1357 for (t in targetHosts) {
1358 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001359 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001360 }
1361 } else {
1362 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001363 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001364 }
1365 verifyService(pepperEnv, target, 'libvirt-bin')
1366 }
1367 }
1368
1369 if (rollbacks.contains("osd")) {
1370 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001371 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001372 if (salt.testTarget(pepperEnv, target)) {
1373 if (PER_NODE.toBoolean()) {
1374 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1375 for (t in targetHosts) {
1376 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001377 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001378 }
1379 } else {
1380 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001381 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001382 }
1383 verifyCephOsds(pepperEnv, target)
1384 }
1385 }
1386
Jiri Broulik60dcab32018-03-08 17:42:06 +01001387 /*
1388 * Merge snapshots section
1389 */
1390 if (merges.contains("cfg")) {
1391 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1392 mergeSnapshot(pepperEnv, 'I@salt:master')
1393 }
1394 }
1395
Jiri Broulik60dcab32018-03-08 17:42:06 +01001396 if (merges.contains("msg")) {
1397 if (salt.testTarget(pepperEnv, MSG_TARGET)) {
1398 mergeSnapshot(pepperEnv, MSG_TARGET, 'msg')
Jiri Broulik906e9972018-03-26 16:12:00 +02001399 verifyService(pepperEnv, MSG_TARGET, 'rabbitmq-server')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001400 }
1401 }
1402
1403 if (merges.contains("dbs")) {
1404 if (salt.testTarget(pepperEnv, DBS_TARGET)) {
1405 mergeSnapshot(pepperEnv, DBS_TARGET, 'dbs')
Jiri Broulikad606d02018-03-28 14:22:43 +02001406 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik906e9972018-03-26 16:12:00 +02001407 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001408 }
1409 }
1410
1411 if (merges.contains("ntw")) {
1412 if (salt.testTarget(pepperEnv, NTW_TARGET)) {
1413 mergeSnapshot(pepperEnv, NTW_TARGET, 'ntw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001414 verifyContrail(pepperEnv, NTW_TARGET)
1415 backupContrail(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001416 }
1417 }
1418
1419 if (merges.contains("nal")) {
1420 if (salt.testTarget(pepperEnv, NAL_TARGET)) {
1421 mergeSnapshot(pepperEnv, NAL_TARGET, 'nal')
Jiri Broulik906e9972018-03-26 16:12:00 +02001422 verifyContrail(pepperEnv, NAL_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001423 }
1424 }
1425
Jiri Broulik60dcab32018-03-08 17:42:06 +01001426 if (merges.contains("cmn")) {
1427 if (salt.testTarget(pepperEnv, CMN_TARGET)) {
1428 mergeSnapshot(pepperEnv, CMN_TARGET, 'cmn')
Jiri Broulik906e9972018-03-26 16:12:00 +02001429 verifyCeph(pepperEnv, CMN_TARGET, 'mon@')
1430 backupCeph(pepperEnv, CMN_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001431 }
1432 }
1433
1434 if (merges.contains("rgw")) {
1435 if (salt.testTarget(pepperEnv, RGW_TARGET)) {
1436 mergeSnapshot(pepperEnv, RGW_TARGET, 'rgw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001437 verifyCeph(pepperEnv, RGW_TARGET, 'radosgw@rgw.')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001438 }
1439 }
1440
1441 if (merges.contains("log")) {
1442 if (salt.testTarget(pepperEnv, LOG_TARGET)) {
Jiri Broulik3bd7adf2018-06-29 09:17:28 +02001443 mergeSnapshot(pepperEnv, LOG_TARGET, 'log')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001444 }
1445 }
1446
1447 if (merges.contains("mon")) {
1448 if (salt.testTarget(pepperEnv, MON_TARGET)) {
1449 mergeSnapshot(pepperEnv, MON_TARGET, 'mon')
1450 }
1451 }
1452
1453 if (merges.contains("mtr")) {
1454 if (salt.testTarget(pepperEnv, MTR_TARGET)) {
1455 mergeSnapshot(pepperEnv, MTR_TARGET, 'mtr')
1456 }
1457 }
1458
1459 if (merges.contains("cid")) {
1460 if (salt.testTarget(pepperEnv, CID_TARGET)) {
1461 mergeSnapshot(pepperEnv, CID_TARGET, 'cid')
Jiri Broulik906e9972018-03-26 16:12:00 +02001462 verifyService(pepperEnv, CID_TARGET, 'docker')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001463 }
1464 }
1465
1466 if (RESTORE_GALERA.toBoolean()) {
1467 restoreGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001468 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001469 }
1470
1471 if (RESTORE_CONTRAIL_DB.toBoolean()) {
1472 restoreContrailDb(pepperEnv)
Jiri Broulik906e9972018-03-26 16:12:00 +02001473 // verification is already present in restore pipelines
Jiri Broulik60dcab32018-03-08 17:42:06 +01001474 }
1475
Andrei Danin3f46c582018-10-23 16:32:18 -07001476 if(RUN_CVP_TESTS.toBoolean() == true){
Richard Felklaedc89b2018-06-26 23:50:49 +02001477 stage('Run CVP tests after upgrade.') {
1478 build job: "cvp-sanity"
1479 build job: "cvp-func"
1480 build job: "cvp-ha"
1481 build job: "cvp-perf"
1482 }
1483 }
1484
Jiri Broulik60dcab32018-03-08 17:42:06 +01001485 } catch (Throwable e) {
1486 // If there was an error or exception thrown, the build failed
1487 currentBuild.result = "FAILURE"
1488 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
1489 throw e
1490 }
1491 }
1492}