blob: 9a33c365710bc7bf8b2962718197681eceea4d51 [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)
Jiri Broulikba6d85d2018-04-05 13:29:07 +020013 * TARGET_KERNEL_UPDATES Comma separated list of nodes to update kernel if newer version is available (Valid values are cfg,ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cid,cmp,kvm,osd,gtw-physical)
14 * TARGET_REBOOT Comma separated list of nodes to reboot after update or physical machine rollback (Valid values are cfg,ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cid,cmp,kvm,osd,gtw-physical)
15 * TARGET_HIGHSTATE Comma separated list of nodes to run Salt Highstate on after update or physical machine rollback (Valid values are cfg,ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cid,cmp,kvm,osd,gtw-physical)
Jiri Broulik60dcab32018-03-08 17:42:06 +010016 * TARGET_UPDATES Comma separated list of nodes to update (Valid values are cfg,ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cid,cmp,kvm,osd,gtw-physical)
Jiri Broulik906e9972018-03-26 16:12:00 +020017 * TARGET_ROLLBACKS Comma separated list of nodes to rollback (Valid values are ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cmp,kvm,osd,gtw-physical)
Jiri Broulik5dac8d82018-03-29 13:34:39 +020018 * TARGET_SNAPSHOT_MERGES Comma separated list of nodes to merge live snapshot for (Valid values are cfg,ctl,prx,msg,dbs,log,mon,mtr,ntw,nal,gtw-virtual,cmn,rgw,cid)
Jiri Broulik60dcab32018-03-08 17:42:06 +010019 * CTL_TARGET Salt targeted CTL nodes (ex. ctl*)
20 * PRX_TARGET Salt targeted PRX nodes (ex. prx*)
21 * MSG_TARGET Salt targeted MSG nodes (ex. msg*)
22 * DBS_TARGET Salt targeted DBS nodes (ex. dbs*)
23 * LOG_TARGET Salt targeted LOG nodes (ex. log*)
24 * MON_TARGET Salt targeted MON nodes (ex. mon*)
25 * MTR_TARGET Salt targeted MTR nodes (ex. mtr*)
26 * NTW_TARGET Salt targeted NTW nodes (ex. ntw*)
27 * NAL_TARGET Salt targeted NAL nodes (ex. nal*)
28 * CMN_TARGET Salt targeted CMN nodes (ex. cmn*)
29 * RGW_TARGET Salt targeted RGW nodes (ex. rgw*)
30 * CID_TARGET Salt targeted CID nodes (ex. cid*)
31 * CMP_TARGET Salt targeted physical compute nodes (ex. cmp001*)
32 * KVM_TARGET Salt targeted physical KVM nodes (ex. kvm01*)
33 * CEPH_OSD_TARGET Salt targeted physical Ceph OSD nodes (ex. osd001*)
Jiri Broulik906e9972018-03-26 16:12:00 +020034 * GTW_TARGET Salt targeted physical or virtual GTW nodes (ex. gtw01*)
Jiri Broulik906e9972018-03-26 16:12:00 +020035 * 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)
36 * PURGE_PKGS Space separated list of pkgs=versions to be purged on physical targeted machines (ex. pkg_name1=pkg_version1 pkg_name2=pkg_version2)
37 * 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 +010038 * RESTORE_GALERA Restore Galera DB (bool)
39 * RESTORE_CONTRAIL_DB Restore Cassandra and Zookeeper DBs for OpenContrail (bool)
40 *
41**/
42def common = new com.mirantis.mk.Common()
43def salt = new com.mirantis.mk.Salt()
44def python = new com.mirantis.mk.Python()
45def virsh = new com.mirantis.mk.Virsh()
46
47def updates = TARGET_UPDATES.tokenize(",").collect{it -> it.trim()}
48def rollbacks = TARGET_ROLLBACKS.tokenize(",").collect{it -> it.trim()}
Jiri Broulik5dac8d82018-03-29 13:34:39 +020049def merges = TARGET_SNAPSHOT_MERGES.tokenize(",").collect{it -> it.trim()}
Jiri Broulik7ba05e42018-04-06 11:39:25 +020050def reboots = TARGET_REBOOT.tokenize(",").collect{it -> it.trim()}
Jiri Broulik60dcab32018-03-08 17:42:06 +010051
52def pepperEnv = "pepperEnv"
53def minions
54def result
55def packages
56def command
57def commandKwargs
58
59def updatePkgs(pepperEnv, target, targetType="", targetPackages="") {
60 def salt = new com.mirantis.mk.Salt()
61 def common = new com.mirantis.mk.Common()
Jiri Broulikba6d85d2018-04-05 13:29:07 +020062 def kernelUpdates = TARGET_KERNEL_UPDATES.tokenize(",").collect{it -> it.trim()}
63 def distUpgrade = false
Jiri Broulik60dcab32018-03-08 17:42:06 +010064 def commandKwargs
Jiri Broulik60dcab32018-03-08 17:42:06 +010065 def pkgs
66 def out
67
68 salt.enforceState(pepperEnv, target, 'linux.system.repo')
69
70 stage("List package upgrades") {
71 common.infoMsg("Listing all the packages that have a new update available on ${target}")
Jiri Broulikba6d85d2018-04-05 13:29:07 +020072 if (kernelUpdates.contains(targetType)) {
73 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', [], null, true))
74 } else {
75 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', ['dist_upgrade=False'], null, true))
76 }
Jiri Broulik60dcab32018-03-08 17:42:06 +010077 if(targetPackages != "" && targetPackages != "*"){
78 common.infoMsg("Note that only the ${targetPackages} would be installed from the above list of available updates on the ${target}")
79 }
80 }
81
82 if (INTERACTIVE.toBoolean()) {
83 stage("Confirm live package upgrades on ${target}") {
84 if (targetPackages=="") {
85 def userInput = input(
86 id: 'userInput', message: 'Insert package names for update', parameters: [
87 [$class: 'TextParameterDefinition', defaultValue: pkgs.keySet().join(",").toString(), description: 'Package names (or *)', name: 'packages']
88 ])
89 if (userInput!= "" && userInput!= "*") {
90 targetPackages = userInput
91 }
92 } else {
93 input message: "Approve live package upgrades on ${target} nodes?"
94 }
95 }
96 } else {
97 targetPackages = pkgs.keySet().join(",").toString()
98 }
99
100 if (targetPackages != "") {
101 // list installed versions of pkgs that will be upgraded
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200102 if (targetType == 'kvm' || targetType == 'cmp' || targetType == 'osd' || targetType == 'gtw-physical') {
103 def installedPkgs = []
104 def newPkgs = []
105 def targetPkgList = targetPackages.tokenize(',')
106 for (pkg in targetPkgList) {
107 def version
108 try {
109 def pkgsDetails = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.info_installed', [pkg], null, true))
110 version = pkgsDetails.get(pkg).get('version')
111 } catch (Exception er) {
112 common.infoMsg("${pkg} not installed yet")
113 }
114 if (version?.trim()) {
115 installedPkgs.add(pkg + '=' + version)
116 } else {
117 newPkgs.add(pkg)
118 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100119 }
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200120 common.warningMsg("the following list of pkgs will be upgraded")
121 common.warningMsg(installedPkgs.join(" "))
122 common.warningMsg("the following list of pkgs will be newly installed")
123 common.warningMsg(newPkgs.join(" "))
Jiri Broulik60dcab32018-03-08 17:42:06 +0100124 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100125 // set variables
126 command = "pkg.install"
127 packages = targetPackages
128 commandKwargs = ['only_upgrade': 'true','force_yes': 'true']
129
130 }else {
131 command = "pkg.upgrade"
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200132 if (kernelUpdates.contains(targetType)) {
133 commandKwargs = ['dist_upgrade': 'true']
134 distUpgrade = true
135 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100136 packages = null
137 }
138
Jiri Broulik60dcab32018-03-08 17:42:06 +0100139 stage("stop services on ${target}") {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200140 if ((STOP_SERVICES.toBoolean()) && (targetType != 'cid')) {
141 if (targetType == 'ntw' || targetType == 'nal') {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200142 contrailServices(pepperEnv, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100143 } else {
144 def probe = salt.getFirstMinion(pepperEnv, "${target}")
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200145 services(pepperEnv, probe, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100146 }
147 }
148 }
149
150 stage('Apply package upgrades') {
151 // salt master pkg
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200152 if (targetType == 'cfg') {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100153 common.warningMsg('salt-master pkg upgrade, rerun the pipeline if disconnected')
154 salt.runSaltProcessStep(pepperEnv, target, 'pkg.install', ['salt-master'], null, true, 5)
155 salt.minionsReachable(pepperEnv, 'I@salt:master', '*')
156 }
157 // salt minion pkg
158 salt.runSaltProcessStep(pepperEnv, target, 'pkg.install', ['salt-minion'], null, true, 5)
159 salt.minionsReachable(pepperEnv, 'I@salt:master', target)
160 common.infoMsg('Performing pkg upgrades ... ')
161 common.retry(3){
162 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], command, true, packages, commandKwargs)
163 salt.printSaltCommandResult(out)
164 }
165 def osRelease = salt.getGrain(pepperEnv, target, 'lsb_distrib_codename')
166 if (osRelease.toString().toLowerCase().contains('trusty')) {
167 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --force-yes -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" '
168 } else {
169 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q -f --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" '
170 }
171 if (out.toString().contains('errors:')) {
172 try {
173 if (packages?.trim()) {
174 packages = packages.replaceAll(',', ' ')
175 common.retry(3){
176 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install ' + packages])
177 }
178 } else {
179 if (distUpgrade) {
180 common.retry(3){
181 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' dist-upgrade'])
182 }
183 } else {
184 common.retry(3){
185 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' upgrade'])
186 }
187 } }
188 if (out.toString().contains('E: ')) {
189 common.errorMsg(out)
190 if (INTERACTIVE.toBoolean()) {
191 input message: "Pkgs update failed to be updated on ${target}. Please fix it manually."
192 } else {
193 salt.printSaltCommandResult(out)
194 throw new Exception("Pkgs update failed")
195 }
196 }
197 } catch (Exception e) {
198 common.errorMsg(out)
199 common.errorMsg(e)
200 if (INTERACTIVE.toBoolean()) {
201 input message: "Pkgs update failed to be updated on ${target}. Please fix it manually."
202 } else {
203 throw new Exception("Pkgs update failed")
204 }
205 }
206 }
207 }
208}
209
210def rollbackPkgs(pepperEnv, target, targetType = "", targetPackages="") {
211 def salt = new com.mirantis.mk.Salt()
212 def common = new com.mirantis.mk.Common()
213 def probe = salt.getFirstMinion(pepperEnv, "${target}")
214 def distUpgrade
215 def pkgs
216 def out
217
218 salt.enforceState(pepperEnv, target, 'linux.system.repo')
219
220 if (ROLLBACK_PKG_VERSIONS == "") {
221 stage("List package upgrades") {
222 common.infoMsg("Listing all the packages that have a new update available on ${target}")
223 pkgs = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, target, 'pkg.list_upgrades', [], null, true))
224 if(targetPackages != "" && targetPackages != "*"){
225 common.infoMsg("Note that only the ${targetPackages} would be installed from the above list of available updates on the ${target}")
226 }
227 }
228
229 if (INTERACTIVE.toBoolean()) {
230 stage("Confirm live package upgrades on ${target}") {
231 if(targetPackages==""){
232 timeout(time: 2, unit: 'HOURS') {
233 def userInput = input(
234 id: 'userInput', message: 'Insert package names for update', parameters: [
235 [$class: 'TextParameterDefinition', defaultValue: pkgs.keySet().join(",").toString(), description: 'Package names (or *)', name: 'packages']
236 ])
237 if(userInput!= "" && userInput!= "*"){
238 targetPackages = userInput
239 }
240 }
241 }else{
242 timeout(time: 2, unit: 'HOURS') {
243 input message: "Approve live package upgrades on ${target} nodes?"
244 }
245 }
246 }
247 } else {
248 targetPackages = pkgs.keySet().join(",").toString()
249 }
250 } else {
251 targetPackages = ROLLBACK_PKG_VERSIONS
252 }
253
254 if (targetPackages != "") {
255 // set variables
256 packages = targetPackages
257 } else {
258 distUpgrade = true
259 packages = null
260 }
261
262 stage("stop services on ${target}") {
263 try {
264 if (INTERACTIVE.toBoolean()) {
265 input message: "Click PROCEED to interactively stop services on ${target}. Otherwise click ABORT to skip stopping them and continue."
266 }
267 } catch (Exception er) {
268 common.infoMsg('skipping stopping services')
269 return
270 }
271 if (STOP_SERVICES.toBoolean()) {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200272 services(pepperEnv, probe, target, 'stop')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100273 }
274 }
275
276 stage('Apply package downgrades') {
277 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" '
278 common.infoMsg('Performing pkgs purge/remove ... ')
279 try {
280 if (PURGE_PKGS != "") {
281 def purgePackages = PURGE_PKGS.replaceAll(',', ' ')
282 common.retry(3){
283 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' purge ' + purgePackages])
284 }
285 }
286 if (REMOVE_PKGS != "") {
287 def removePackages = REMOVE_PKGS.replaceAll(',', ' ')
288 common.retry(3){
289 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' remove ' + removePackages])
290 }
291 }
292 if (out.toString().contains('E: ')) {
293 common.errorMsg(out)
294 if (INTERACTIVE.toBoolean()) {
295 input message: "Pkgs ${packages} purge failed on ${target}. Please fix it manually."
296 } else {
297 salt.printSaltCommandResult(out)
298 throw new Exception("Pkgs {packages} purge failed")
299 }
300 }
301 } catch (Exception e) {
302 common.errorMsg(out)
303 common.errorMsg(e)
304 if (INTERACTIVE.toBoolean()) {
305 input message: "Pkgs {packages} purge on ${target}. Please fix it manually."
306 } else {
307 throw new Exception("Pkgs {packages} purge failed")
308 }
309 }
310
311 common.infoMsg('Performing pkg downgrades ... ')
312 try {
313 packages = packages.replaceAll(',', ' ')
314 if (packages?.trim()) {
315 packages = packages.replaceAll(',', ' ')
316 common.retry(3){
317 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install salt-minion'], null, true, 5)
318 }
319 salt.minionsReachable(pepperEnv, 'I@salt:master', target)
320 common.retry(3){
321 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' install ' + packages])
322 }
323 } else {
324 if (distUpgrade) {
325 common.retry(3){
326 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' dist-upgrade'])
327 }
328 } else {
329 common.retry(3){
330 out = salt.runSaltProcessStep(pepperEnv, target, 'cmd.run', [args + ' upgrade'])
331 }
332 }
333 }
334 if (out.toString().contains('E: ')) {
335 common.errorMsg(out)
336 if (INTERACTIVE.toBoolean()) {
337 input message: "Pkgs rollback failed on ${target}. Please fix it manually."
338 } else {
339 salt.printSaltCommandResult(out)
340 throw new Exception("Pkgs rollback failed")
341 }
342 }
343 } catch (Exception e) {
344 common.errorMsg(out)
345 common.errorMsg(e)
346 if (INTERACTIVE.toBoolean()) {
347 input message: "Pkgs rollback failed on ${target}. Please fix it manually."
348 } else {
349 throw new Exception("Pkgs rollback failed")
350 }
351 }
352 }
353}
354
355def getCfgNodeProvider(pepperEnv, master_name) {
356 def salt = new com.mirantis.mk.Salt()
357 def common = new com.mirantis.mk.Common()
358 if (!CFG_NODE_PROVIDER?.trim()) {
359 kvms = salt.getMinions(pepperEnv, 'I@salt:control')
360 for (kvm in kvms) {
361 try {
362 vms = salt.getReturnValues(salt.runSaltProcessStep(pepperEnv, kvm, 'virt.list_active_vms', [], null, true))
363 if (vms.toString().contains(master_name)) {
364 CFG_NODE_PROVIDER = kvm
365 //break
366 }
367 } catch (Exception er) {
368 common.infoMsg("${master_name} not present on ${kvm}")
369 }
370 }
371 }
372}
373
374/*
375def rollbackSaltMaster(pepperEnv, target, path='/var/lib/libvirt/images') {
376 def salt = new com.mirantis.mk.Salt()
377 def common = new com.mirantis.mk.Common()
378 try {
379 input message: "PART1 - Are you sure to rollback ${target}? To rollback click on PROCEED. To skip rollback PART1 click on ABORT."
380 } catch (Exception er) {
381 common.infoMsg("skipping rollback of ${target}")
382 return
383 }
384 def domain = salt.getDomainName(pepperEnv)
385 def master = salt.getReturnValues(salt.getPillar(pepperEnv, target, 'linux:network:hostname'))
386 getCfgNodeProvider(pepperEnv, master)
387 try {
388 try {
389 salt.getReturnValues(salt.cmdRun(pepperEnv, CFG_NODE_PROVIDER, "ls -la ${path}/${master}.${domain}.xml"))
390 common.errorMsg('Pipeline is about to disconnect from salt-api. You will have to rerun the pipeline with ROLLBACK_CFG checked and skip PART1 to finish rollback.')
391 salt.cmdRun(pepperEnv, CFG_NODE_PROVIDER, "virsh destroy ${master}.${domain}; virsh define ${path}/${master}.${domain}.xml; virsh start ${master}.${domain} ")
392 } catch (Exception er) {
393 common.errorMsg(er)
394 input message: "Rollback for ${target} failed. Rollback manually."
395 }
396 } catch (Exception er) {
397 common.errorMsg(er)
398 input message: "Rollback for ${target} failed. Rollback manually."
399 }
400}
401
402def finishSaltMasterRollback(pepperEnv, target, path='/var/lib/libvirt/images') {
403 def salt = new com.mirantis.mk.Salt()
404 def common = new com.mirantis.mk.Common()
405 def virsh = new com.mirantis.mk.Virsh()
406 try {
407 input message: "PART2 - Are you sure to finalize ${target} rollback? Click on PROCEED. To skip rollback click on ABORT."
408 } catch (Exception er) {
409 common.infoMsg("skipping finalize rollback of ${target}")
410 return
411 }
412 salt.minionsReachable(pepperEnv, 'I@salt:master', '*')
413 def domain = salt.getDomainName(pepperEnv)
414 def master = salt.getReturnValues(salt.getPillar(pepperEnv, target, 'linux:network:hostname'))
415 getCfgNodeProvider(pepperEnv, master)
416 try {
417 virsh.liveSnapshotAbsent(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME, path)
418 // purge and setup previous repos
419 salt.enforceState(pepperEnv, target, 'linux.system.repo')
420 } catch (Exception e) {
421 common.errorMsg(e)
422 input message: "Check what failed after ${target} rollback. Do you want to PROCEED?"
423 }
424}*/
425
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200426def services(pepperEnv, probe, target, action='stop') {
427 def services = ["keepalived","haproxy","nginx","nova-api","cinder","glance","heat","neutron","apache2","rabbitmq-server"]
428 if (action == 'stop') {
429 def openstack = new com.mirantis.mk.Openstack()
430 openstack.stopServices(pepperEnv, probe, target, services, INTERACTIVE.toBoolean())
Jiri Broulik60dcab32018-03-08 17:42:06 +0100431 } else {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200432 def salt = new com.mirantis.mk.Salt()
433 for (s in services) {
434 def outputServicesStr = salt.getReturnValues(salt.cmdRun(pepperEnv, "${probe}*", "service --status-all | grep ${s} | awk \'{print \$4}\'"))
435 def servicesList = outputServicesStr.tokenize("\n").init() //init() returns the items from the Iterable excluding the last item
436 if (servicesList) {
437 for (name in servicesList) {
438 if (!name.contains('Salt command')) {
439 salt.runSaltProcessStep(pepperEnv, "${target}*", 'service.start', ["${name}"])
440 }
441 }
442 }
443 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100444 }
445}
446
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200447// must be treated separately due to OC on Trusty
448def contrailServices(pepperEnv, target, action='stop') {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100449 def salt = new com.mirantis.mk.Salt()
450 def common = new com.mirantis.mk.Common()
451 def services = []
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200452 if (action == 'stop') {
453 services.add('supervisor-control')
454 services.add('supervisor-config')
455 services.add('supervisor-database')
456 services.add('zookeeper')
457 services.add('ifmap-server')
458 services.add('haproxy')
459 services.add('keepalived')
460 } else {
461 services.add('keepalived')
462 services.add('haproxy')
463 services.add('ifmap-server')
464 services.add('zookeeper')
465 services.add('supervisor-database')
466 services.add('supervisor-config')
467 services.add('supervisor-control')
468 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100469 for (s in services) {
470 try {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200471 salt.runSaltProcessStep(pepperEnv, target, "service.${action}", [s], null, true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100472 } catch (Exception er) {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200473 common.warningMsg(er)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100474 }
475 }
476}
477
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200478def highstate(pepperEnv, target, type) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100479 def salt = new com.mirantis.mk.Salt()
480 def common = new com.mirantis.mk.Common()
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200481 def highstates = TARGET_HIGHSTATE.tokenize(",").collect{it -> it.trim()}
482 def reboots = TARGET_REBOOT.tokenize(",").collect{it -> it.trim()}
483 // optionally run highstate
484 if (highstates.contains(type)) {
485 stage("Apply highstate on ${target} nodes") {
486 try {
487 common.retry(3){
488 salt.enforceHighstate(pepperEnv, target)
489 }
490 } catch (Exception e) {
491 common.errorMsg(e)
492 if (INTERACTIVE.toBoolean()) {
493 input message: "Highstate failed on ${target}. Fix it manually or run rollback on ${target}."
494 } else {
495 throw new Exception("highstate failed")
496 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100497 }
498 }
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200499 } else if (!reboots.contains(type) && STOP_SERVICES.toBoolean() && type != 'cid') {
500 if (type == 'ntw' || type == 'nal') {
501 contrailServices(pepperEnv, target, 'start')
502 } else {
503 def probe = salt.getFirstMinion(pepperEnv, "${target}")
504 services(pepperEnv, probe, target, 'start')
505 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100506 }
507 // optionally reboot
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200508 if (reboots.contains(type)) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100509 stage("Reboot ${target} nodes") {
510 salt.runSaltProcessStep(pepperEnv, target, 'system.reboot', null, null, true, 5)
511 sleep(10)
512 salt.minionsReachable(pepperEnv, 'I@salt:master', target)
513 }
514 }
515}
516
517def rollback(pepperEnv, tgt, generalTarget) {
518 def common = new com.mirantis.mk.Common()
519 try {
520 if (INTERACTIVE.toBoolean()) {
521 input message: "Are you sure to rollback ${generalTarget}? To rollback click on PROCEED. To skip rollback click on ABORT."
522 }
523 } catch (Exception er) {
524 common.infoMsg('skipping rollback')
525 return
526 }
527 try {
528 rollbackLiveSnapshot(pepperEnv, tgt, generalTarget)
529 } catch (Exception err) {
530 common.errorMsg(err)
531 if (INTERACTIVE.toBoolean()) {
532 input message: "Rollback for ${tgt} failed please fix it manually before clicking PROCEED."
533 } else {
534 throw new Exception("Rollback failed for ${tgt}")
535 }
536 }
537}
538
539def liveSnapshot(pepperEnv, tgt, generalTarget) {
540 def salt = new com.mirantis.mk.Salt()
541 def common = new com.mirantis.mk.Common()
542 def virsh = new com.mirantis.mk.Virsh()
543 def domain = salt.getDomainName(pepperEnv)
544 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
545 common.warningMsg(target_hosts)
546 //def nodeCount = 1
547 for (t in target_hosts) {
548 def target = salt.stripDomainName(t)
549 def nodeCount = target[4]
550 common.warningMsg(nodeCount)
551 def nodeProvider = salt.getNodeProvider(pepperEnv, "${generalTarget}0${nodeCount}")
552 virsh.liveSnapshotPresent(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
553 //nodeCount++
554 }
555}
556
557def mergeSnapshot(pepperEnv, tgt, generalTarget='') {
558 def salt = new com.mirantis.mk.Salt()
559 def virsh = new com.mirantis.mk.Virsh()
560 def domain = salt.getDomainName(pepperEnv)
561 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
562 def nodeCount = 1
563 for (t in target_hosts) {
564 if (tgt == 'I@salt:master') {
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200565 def master = salt.getReturnValues(salt.getPillar(pepperEnv, t, 'linux:network:hostname'))
Jiri Broulik60dcab32018-03-08 17:42:06 +0100566 getCfgNodeProvider(pepperEnv, master)
567 virsh.liveSnapshotMerge(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME)
568 } else {
569 def target = salt.stripDomainName(t)
570 def nodeProvider = salt.getNodeProvider(pepperEnv, "${generalTarget}0${nodeCount}")
571 virsh.liveSnapshotMerge(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
572 }
573 nodeCount++
574 }
Jiri Broulik906e9972018-03-26 16:12:00 +0200575 salt.minionsReachable(pepperEnv, 'I@salt:master', tgt)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100576}
577
578
579
580def rollbackLiveSnapshot(pepperEnv, tgt, generalTarget) {
581 def salt = new com.mirantis.mk.Salt()
582 def virsh = new com.mirantis.mk.Virsh()
583 def common = new com.mirantis.mk.Common()
584 def domain = salt.getDomainName(pepperEnv)
585 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
586 // first destroy all vms
587 def nodeCount = 1
588 for (t in target_hosts) {
589 def target = salt.stripDomainName(t)
590 def nodeProvider = salt.getNodeProvider(pepperEnv, "${generalTarget}0${nodeCount}")
591 salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.destroy', ["${target}.${domain}"], null, true)
592 nodeCount++
593 }
594 nodeCount = 1
595 // rollback vms
596 for (t in target_hosts) {
597 def target = salt.stripDomainName(t)
598 def nodeProvider = salt.getNodeProvider(pepperEnv, "${generalTarget}0${nodeCount}")
599 virsh.liveSnapshotRollback(pepperEnv, nodeProvider, target, SNAPSHOT_NAME)
600 nodeCount++
601 }
602 try {
603 salt.minionsReachable(pepperEnv, 'I@salt:master', tgt)
604 // purge and setup previous repos
605 salt.enforceState(pepperEnv, tgt, 'linux.system.repo')
606 } catch (Exception e) {
607 common.errorMsg(e)
608 if (INTERACTIVE.toBoolean()) {
609 input message: "Salt state linux.system.repo on ${tgt} failed. Do you want to PROCEED?."
610 } else {
611 throw new Exception("Salt state linux.system.repo on ${tgt} failed")
612 }
613 }
614}
615
616def removeNode(pepperEnv, tgt, generalTarget) {
617 def salt = new com.mirantis.mk.Salt()
618 def virsh = new com.mirantis.mk.Virsh()
619 def common = new com.mirantis.mk.Common()
620 def domain = salt.getDomainName(pepperEnv)
621 def target_hosts = salt.getMinionsSorted(pepperEnv, "${tgt}")
622 // first destroy all vms
623 def nodeCount = 1
624 for (t in target_hosts) {
625 def target = salt.stripDomainName(t)
626 def nodeProvider = salt.getNodeProvider(pepperEnv, "${generalTarget}0${nodeCount}")
627 salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.destroy', ["${target}.${domain}"], null, true)
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200628 //salt.runSaltProcessStep(pepperEnv, "${nodeProvider}*", 'virt.undefine', ["${target}.${domain}"], null, true)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100629 try {
630 salt.cmdRun(pepperEnv, 'I@salt:master', "salt-key -d ${target}.${domain} -y")
631 } catch (Exception e) {
632 common.warningMsg('does not match any accepted, unaccepted or rejected keys. They were probably already removed. We should continue to run')
633 }
634 nodeCount++
635 }
636}
637
Jiri Broulik906e9972018-03-26 16:12:00 +0200638def saltMasterBackup(pepperEnv) {
639 def salt = new com.mirantis.mk.Salt()
640 salt.enforceState(pepperEnv, 'I@salt:master', 'backupninja')
641 salt.cmdRun(pepperEnv, 'I@salt:master', "su root -c 'backupninja -n --run /etc/backup.d/200.backup.rsync'")
642}
643
Jiri Broulik60dcab32018-03-08 17:42:06 +0100644def backupCeph(pepperEnv, tgt) {
645 def salt = new com.mirantis.mk.Salt()
646 salt.enforceState(pepperEnv, 'I@ceph:backup:server', 'ceph.backup')
647 salt.enforceState(pepperEnv, "I@ceph:backup:client and ${tgt}", 'ceph.backup')
648 salt.cmdRun(pepperEnv, "I@ceph:backup:client and ${tgt}", "su root -c '/usr/local/bin/ceph-backup-runner-call.sh -s'")
649}
650
651def backupGalera(pepperEnv) {
652 def salt = new com.mirantis.mk.Salt()
653 salt.enforceState(pepperEnv, 'I@xtrabackup:server', ['linux.system.repo', 'xtrabackup'])
654 salt.enforceState(pepperEnv, 'I@xtrabackup:client', ['linux.system.repo', 'openssh.client'])
655 salt.cmdRun(pepperEnv, 'I@xtrabackup:client', "su root -c 'salt-call state.sls xtrabackup'")
656 salt.cmdRun(pepperEnv, 'I@xtrabackup:client', "su root -c '/usr/local/bin/innobackupex-runner.sh -s -f'")
657}
658
659// cluster galera - wsrep_cluster_size
660def clusterGalera(pepperEnv) {
661 def salt = new com.mirantis.mk.Salt()
662 def common = new com.mirantis.mk.Common()
663 try {
664 salt.runSaltProcessStep(pepperEnv, 'I@galera:slave', 'service.stop', ['mysql'])
665 } catch (Exception er) {
666 common.warningMsg('Mysql service already stopped')
667 }
668 try {
669 salt.runSaltProcessStep(pepperEnv, 'I@galera:master', 'service.stop', ['mysql'])
670 } catch (Exception er) {
671 common.warningMsg('Mysql service already stopped')
672 }
673 try {
674 salt.cmdRun(pepperEnv, 'I@galera:slave', "rm /var/lib/mysql/ib_logfile*")
675 } catch (Exception er) {
676 common.warningMsg('Files are not present')
677 }
678 salt.cmdRun(pepperEnv, 'I@galera:master', "sed -i '/gcomm/c\\wsrep_cluster_address=\"gcomm://\"' /etc/mysql/my.cnf")
679 salt.runSaltProcessStep(pepperEnv, 'I@galera:master', 'service.start', ['mysql'])
680 // wait until mysql service on galera master is up
681 try {
682 salt.commandStatus(pepperEnv, 'I@galera:master', 'service mysql status', 'running')
683 } catch (Exception er) {
684 if (INTERACTIVE.toBoolean()) {
685 input message: "Database is not running please fix it first and only then click on PROCEED."
686 } else {
687 throw new Exception("Database is not running correctly")
688 }
689 }
690 salt.runSaltProcessStep(pepperEnv, 'I@galera:slave', 'service.start', ['mysql'])
691}
692
693def restoreGalera(pepperEnv) {
694 def salt = new com.mirantis.mk.Salt()
695 def common = new com.mirantis.mk.Common()
696 def openstack = new com.mirantis.mk.Openstack()
697 salt.cmdRun(pepperEnv, 'I@xtrabackup:client', "rm -rf /var/lib/mysql/*")
698 openstack.restoreGaleraDb(pepperEnv)
699}
700
701def backupZookeeper(pepperEnv) {
702 def salt = new com.mirantis.mk.Salt()
703 def common = new com.mirantis.mk.Common()
704 salt.enforceState(pepperEnv, 'I@zookeeper:backup:server', 'zookeeper.backup')
705 salt.enforceState(pepperEnv, 'I@zookeeper:backup:client', 'zookeeper.backup')
706 try {
707 salt.cmdRun(pepperEnv, 'I@opencontrail:control', "su root -c '/usr/local/bin/zookeeper-backup-runner.sh -s'")
708 } catch (Exception er) {
709 throw new Exception('Zookeeper failed to backup. Please fix it before continuing.')
710 }
711}
712
713def backupCassandra(pepperEnv) {
714 def salt = new com.mirantis.mk.Salt()
715 def common = new com.mirantis.mk.Common()
716
717 salt.enforceState(pepperEnv, 'I@cassandra:backup:server', 'cassandra.backup')
718 salt.enforceState(pepperEnv, 'I@cassandra:backup:client', 'cassandra.backup')
719 try {
720 salt.cmdRun(pepperEnv, 'I@cassandra:backup:client', "su root -c '/usr/local/bin/cassandra-backup-runner-call.sh -s'")
721 } catch (Exception er) {
722 throw new Exception('Cassandra failed to backup. Please fix it before continuing.')
723 }
724}
725
726def backupContrail(pepperEnv) {
727 backupZookeeper(pepperEnv)
728 backupCassandra(pepperEnv)
729}
730
731// cassandra and zookeeper
732def restoreContrailDb(pepperEnv) {
733 def salt = new com.mirantis.mk.Salt()
734 def common = new com.mirantis.mk.Common()
735 build job: "deploy-zookeeper-restore", parameters: [
736 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
737 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: SALT_MASTER_URL]
738 ]
739 build job: "deploy-cassandra-db-restore", parameters: [
740 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
741 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: SALT_MASTER_URL]
742 ]
743}
744
Jiri Broulikd2dd5632018-03-27 15:44:56 +0200745def verifyAPIs(pepperEnv, target) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100746 def salt = new com.mirantis.mk.Salt()
747 def common = new com.mirantis.mk.Common()
Jiri Broulikad606d02018-03-28 14:22:43 +0200748 def out = salt.cmdRun(pepperEnv, target, '. /root/keystonercv3; openstack service list; openstack image list; openstack flavor list; openstack compute service list; openstack server list; openstack network list; openstack volume list; openstack orchestration service list')
749 if (out.toString().toLowerCase().contains('error')) {
750 common.errorMsg(out)
751 if (INTERACTIVE.toBoolean()) {
752 input message: "APIs are not working as expected. Please fix it manually."
753 } else {
754 throw new Exception("APIs are not working as expected")
755 }
756 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100757}
758
Jiri Broulikad606d02018-03-28 14:22:43 +0200759def verifyGalera(pepperEnv, target, count=0, maxRetries=200) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100760 def salt = new com.mirantis.mk.Salt()
761 def common = new com.mirantis.mk.Common()
Jiri Broulikad606d02018-03-28 14:22:43 +0200762 def out
763 while(count < maxRetries) {
764 try {
765 out = salt.getReturnValues(salt.cmdRun(pepperEnv, target, 'salt-call mysql.status | grep -A1 wsrep_cluster_size'))
766 } catch (Exception er) {
767 common.infoMsg(er)
768 }
769 if ((!out.toString().contains('wsrep_cluster_size')) || (out.toString().contains('0'))) {
770 count++
771 if (count == maxRetries) {
772 if (INTERACTIVE.toBoolean()) {
773 input message: "Galera is not working as expected. Please check it and fix it first before clicking on PROCEED."
774 } else {
775 common.errorMsg(out)
776 throw new Exception("Galera is not working as expected")
777 }
778 }
779 sleep(time: 500, unit: 'MILLISECONDS')
Jiri Broulik60dcab32018-03-08 17:42:06 +0100780 } else {
Jiri Broulikad606d02018-03-28 14:22:43 +0200781 break
Jiri Broulik60dcab32018-03-08 17:42:06 +0100782 }
783 }
784}
785
786def verifyContrail(pepperEnv, target) {
787 def salt = new com.mirantis.mk.Salt()
788 def common = new com.mirantis.mk.Common()
789 salt.commandStatus(pepperEnv, target, "contrail-status | grep -v == | grep -v \'disabled on boot\' | grep -v nodemgr | grep -v active | grep -v backup", null, false)
790}
791
792
793def verifyService(pepperEnv, target, service) {
794 def salt = new com.mirantis.mk.Salt()
795 def common = new com.mirantis.mk.Common()
796 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
797 for (t in targetHosts) {
798 try {
799 salt.commandStatus(pepperEnv, t, "service ${service} status", 'running')
800 } catch (Exception er) {
801 common.errorMsg(er)
802 if (INTERACTIVE.toBoolean()) {
803 input message: "${service} service is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
804 } else {
805 throw new Exception("${service} service is not running correctly on ${t}")
806 }
807 }
808 }
809}
810
811def verifyCeph(pepperEnv, target, type) {
812 def salt = new com.mirantis.mk.Salt()
813 def common = new com.mirantis.mk.Common()
814 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
815 for (t in targetHosts) {
816 def hostname = salt.getReturnValues(salt.getPillar(pepperEnv, t, 'linux:network:hostname'))
817 try {
818 salt.commandStatus(pepperEnv, t, "systemctl status ceph-${type}${hostname}", 'running')
819 } catch (Exception er) {
820 common.errorMsg(er)
821 if (INTERACTIVE.toBoolean()) {
822 input message: "Ceph-${type}${hostname} service is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
823 } else {
824 throw new Exception("Ceph-${type}${hostname} service is not running correctly on ${t}")
825 }
826 }
827 }
828}
829
830def verifyCephOsds(pepperEnv, target) {
831 def salt = new com.mirantis.mk.Salt()
832 def common = new com.mirantis.mk.Common()
833 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
834 for (t in targetHosts) {
835 def osd_ids = []
836 // get list of osd disks of the host
837 salt.runSaltProcessStep(pepperEnv, t, 'saltutil.sync_grains', [], null, true, 5)
838 def cephGrain = salt.getGrain(pepperEnv, t, 'ceph')
839 if(cephGrain['return'].isEmpty()){
840 throw new Exception("Ceph salt grain cannot be found!")
841 }
842 common.print(cephGrain)
843 def ceph_disks = cephGrain['return'][0].values()[0].values()[0]['ceph_disk']
844 for (i in ceph_disks) {
845 def osd_id = i.getKey().toString()
846 osd_ids.add('osd.' + osd_id)
847 print("Will check osd." + osd_id)
848 }
849 for (i in osd_ids) {
850 try {
851 salt.commandStatus(pepperEnv, t, "ceph osd tree | grep -w ${i}", 'up')
852 } catch (Exception er) {
853 common.errorMsg(er)
854 if (INTERACTIVE.toBoolean()) {
855 input message: "Ceph ${i} is not running correctly on ${t}. Please fix it first manually and only then click on PROCEED."
856 } else {
857 throw new Exception("Ceph ${i} is not running correctly on ${t}")
858 }
859 }
860 }
861 }
862}
863
864
865timeout(time: 12, unit: 'HOURS') {
866 node() {
867 try {
868
869 stage('Setup virtualenv for Pepper') {
870 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
871 }
872
873 // TODO, add possibility to update just specific components like kernel, openstack, contrail, ovs, rabbitmq, galera, etc.
874
875 /*
876 * Update section
877 */
878 if (updates.contains("cfg")) {
879 def target = 'I@salt:master'
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200880 def type = 'cfg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100881 if (salt.testTarget(pepperEnv, target)) {
882 def master = salt.getReturnValues(salt.getPillar(pepperEnv, target, 'linux:network:hostname'))
883 getCfgNodeProvider(pepperEnv, master)
884 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
885 virsh.liveSnapshotPresent(pepperEnv, CFG_NODE_PROVIDER, master, SNAPSHOT_NAME)
Jiri Broulik906e9972018-03-26 16:12:00 +0200886 } else {
887 saltMasterBackup(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100888 }
889 if (PER_NODE.toBoolean()) {
890 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
891 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200892 updatePkgs(pepperEnv, t, type)
893 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100894 }
895 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200896 updatePkgs(pepperEnv, target, type)
897 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100898 }
899 }
900 }
901
902 if (updates.contains("ctl")) {
903 def target = CTL_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200904 def type = 'ctl'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100905 if (salt.testTarget(pepperEnv, target)) {
906 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200907 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100908 }
909 if (PER_NODE.toBoolean()) {
910 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
911 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200912 updatePkgs(pepperEnv, t, type)
913 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100914 }
915 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200916 updatePkgs(pepperEnv, target, type)
917 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100918 }
919 verifyAPIs(pepperEnv, target)
920 }
921 }
922
923 if (updates.contains("prx")) {
924 def target = PRX_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200925 def type = 'prx'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100926 if (salt.testTarget(pepperEnv, target)) {
927 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200928 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100929 }
930 if (PER_NODE.toBoolean()) {
931 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
932 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200933 updatePkgs(pepperEnv, t, type)
934 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100935 }
936 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200937 updatePkgs(pepperEnv, target, type)
938 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100939 }
940 verifyService(pepperEnv, target, 'nginx')
941 }
942 }
943
944 if (updates.contains("msg")) {
945 def target = MSG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200946 def type = 'msg'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100947 if (salt.testTarget(pepperEnv, target)) {
948 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200949 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100950 }
951 if (PER_NODE.toBoolean()) {
952 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
953 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200954 updatePkgs(pepperEnv, t, type)
955 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100956 }
957 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200958 updatePkgs(pepperEnv, target, type)
959 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100960 }
961 verifyService(pepperEnv, target, 'rabbitmq-server')
962 }
963 }
964
965 if (updates.contains("dbs")) {
966 def target = DBS_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200967 def type = 'dbs'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100968 if (salt.testTarget(pepperEnv, target)) {
969 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100970 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200971 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100972 }
Jiri Broulik7ba05e42018-04-06 11:39:25 +0200973 if (reboots.contains(type) || PER_NODE.toBoolean()) {
Jiri Broulik60dcab32018-03-08 17:42:06 +0100974 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100975 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200976 updatePkgs(pepperEnv, t, type)
977 highstate(pepperEnv, t, type)
Jiri Broulikad606d02018-03-28 14:22:43 +0200978 verifyGalera(pepperEnv, t)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100979 }
980 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200981 updatePkgs(pepperEnv, target, type)
982 highstate(pepperEnv, target, type)
Jiri Broulikad606d02018-03-28 14:22:43 +0200983 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100984 }
Jiri Broulik60dcab32018-03-08 17:42:06 +0100985 }
986 }
987
988 if (updates.contains("ntw")) {
989 def target = NTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200990 def type = 'ntw'
Jiri Broulik60dcab32018-03-08 17:42:06 +0100991 if (salt.testTarget(pepperEnv, target)) {
992 backupContrail(pepperEnv)
993 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200994 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +0100995 }
996 if (PER_NODE.toBoolean()) {
997 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
998 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +0200999 updatePkgs(pepperEnv, t, type)
1000 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001001 verifyContrail(pepperEnv, t)
1002 }
1003 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001004 updatePkgs(pepperEnv, target, type)
1005 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001006 verifyContrail(pepperEnv, target)
1007 }
1008 }
1009 }
1010
1011 if (updates.contains("nal")) {
1012 def target = NAL_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001013 def type = 'nal'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001014 if (salt.testTarget(pepperEnv, target)) {
1015 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001016 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001017 }
1018 if (PER_NODE.toBoolean()) {
1019 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1020 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001021 updatePkgs(pepperEnv, t, type)
1022 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001023 }
1024 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001025 updatePkgs(pepperEnv, target, type)
1026 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001027 }
1028 verifyContrail(pepperEnv, target)
1029 }
1030 }
1031
1032 if (updates.contains("gtw-virtual")) {
1033 def target = GTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001034 def type = 'gtw-virtual'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001035 if (salt.testTarget(pepperEnv, target)) {
1036 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001037 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001038 }
1039 if (PER_NODE.toBoolean()) {
1040 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1041 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001042 updatePkgs(pepperEnv, t, type)
1043 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001044 }
1045 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001046 updatePkgs(pepperEnv, target, type)
1047 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001048 }
1049 verifyService(pepperEnv, target, 'neutron-dhcp-agent')
1050 }
1051 }
1052
1053 if (updates.contains("cmn")) {
1054 def target = CMN_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001055 def type = 'cmn'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001056 if (salt.testTarget(pepperEnv, target)) {
1057 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001058 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001059 } else {
Jiri Broulik906e9972018-03-26 16:12:00 +02001060 backupCeph(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001061 }
1062 if (PER_NODE.toBoolean()) {
1063 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1064 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001065 updatePkgs(pepperEnv, t, type)
1066 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001067 }
1068 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001069 updatePkgs(pepperEnv, target, type)
1070 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001071 }
1072 verifyCeph(pepperEnv, target, 'mon@')
1073 }
1074 }
1075
1076 if (updates.contains("rgw")) {
1077 def target = RGW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001078 def type = 'rgw'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001079 if (salt.testTarget(pepperEnv, target)) {
1080 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001081 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001082 }
1083 if (PER_NODE.toBoolean()) {
1084 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1085 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001086 updatePkgs(pepperEnv, t, type)
1087 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001088 }
1089 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001090 updatePkgs(pepperEnv, target, type)
1091 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001092 }
1093 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1094 }
1095 }
1096
1097 if (updates.contains("log")) {
1098 def target = LOG_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001099 def type = 'log'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001100 if (salt.testTarget(pepperEnv, target)) {
1101 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001102 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001103 }
1104 if (PER_NODE.toBoolean()) {
1105 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1106 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001107 updatePkgs(pepperEnv, t, type)
1108 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001109 }
1110 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001111 updatePkgs(pepperEnv, target, type)
1112 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001113 }
1114 }
1115 }
1116
1117 if (updates.contains("mon")) {
1118 def target = MON_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001119 def type = 'mon'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001120 if (salt.testTarget(pepperEnv, target)) {
1121 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001122 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001123 }
1124 if (PER_NODE.toBoolean()) {
1125 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1126 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001127 updatePkgs(pepperEnv, t, type)
1128 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001129 }
1130 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001131 updatePkgs(pepperEnv, target, type)
1132 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001133 }
1134 }
1135 }
1136
1137 if (updates.contains("mtr")) {
1138 def target = MTR_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001139 def type = 'mtr'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001140 if (salt.testTarget(pepperEnv, target)) {
1141 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001142 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001143 }
1144 if (PER_NODE.toBoolean()) {
1145 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1146 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001147 updatePkgs(pepperEnv, t, type)
1148 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001149 }
1150 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001151 updatePkgs(pepperEnv, target, type)
1152 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001153 }
1154 }
1155 }
1156
1157 if (updates.contains("cid")) {
1158 def target = CID_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001159 def type = 'cid'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001160 if (salt.testTarget(pepperEnv, target)) {
1161 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001162 liveSnapshot(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001163 }
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001164 updatePkgs(pepperEnv, target, type)
1165 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001166 verifyService(pepperEnv, target, 'docker')
1167 }
1168 }
1169
1170 //
1171 //physical machines update CMP_TARGET
1172 //
1173 if (updates.contains("cmp")) {
1174 def target = CMP_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001175 def type = 'cmp'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001176 if (salt.testTarget(pepperEnv, target)) {
1177 if (PER_NODE.toBoolean()) {
1178 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1179 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001180 updatePkgs(pepperEnv, t, type)
1181 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001182 }
1183 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001184 updatePkgs(pepperEnv, target, type)
1185 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001186 }
1187 verifyService(pepperEnv, target, 'nova-compute')
1188 }
1189 }
1190
1191 if (updates.contains("kvm")) {
1192 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001193 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001194 if (salt.testTarget(pepperEnv, target)) {
1195 if (PER_NODE.toBoolean()) {
1196 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1197 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001198 updatePkgs(pepperEnv, t, type)
1199 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001200 }
1201 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001202 updatePkgs(pepperEnv, target, type)
1203 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001204 }
1205 verifyService(pepperEnv, target, 'libvirt-bin')
1206 }
1207 }
1208
1209 if (updates.contains("osd")) {
1210 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001211 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001212 if (salt.testTarget(pepperEnv, target)) {
1213 if (PER_NODE.toBoolean()) {
1214 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1215 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001216 updatePkgs(pepperEnv, t, type)
1217 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001218 }
1219 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001220 updatePkgs(pepperEnv, target, type)
1221 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001222 }
1223 verifyCephOsds(pepperEnv, target)
1224 }
1225 }
1226
1227 if (updates.contains("gtw-physical")) {
1228 def target = GTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001229 def type = 'gtw-physical'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001230 if (salt.testTarget(pepperEnv, target)) {
1231 if (PER_NODE.toBoolean()) {
1232 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1233 for (t in targetHosts) {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001234 updatePkgs(pepperEnv, t, type)
1235 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001236 }
1237 } else {
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001238 updatePkgs(pepperEnv, target, type)
1239 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001240 }
1241 verifyService(pepperEnv, target, 'neutron-dhcp-agent')
1242 }
1243 }
1244
1245 /*
1246 * Rollback section
1247 */
Jiri Broulik906e9972018-03-26 16:12:00 +02001248 /* if (rollbacks.contains("cfg")) {
Jiri Broulik60dcab32018-03-08 17:42:06 +01001249 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1250 stage('ROLLBACK_CFG') {
1251 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."
1252 //rollbackSaltMaster(pepperEnv, 'I@salt:master')
1253 //finishSaltMasterRollback(pepperEnv, 'I@salt:master')
1254 }
1255 }
1256 } */
1257
1258 if (rollbacks.contains("ctl")) {
1259 def target = CTL_TARGET
1260 if (salt.testTarget(pepperEnv, target)) {
1261 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1262 rollback(pepperEnv, target, 'ctl')
1263 verifyAPIs(pepperEnv, target)
1264 } else {
1265 removeNode(pepperEnv, target, 'ctl')
1266 }
1267 }
1268 }
1269
1270 if (rollbacks.contains("prx")) {
1271 def target = PRX_TARGET
1272 if (salt.testTarget(pepperEnv, target)) {
1273 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1274 rollback(pepperEnv, target, 'prx')
1275 verifyService(pepperEnv, target, 'nginx')
1276 } else {
1277 removeNode(pepperEnv, target, 'prx')
1278 }
1279 }
1280 }
1281
1282 if (rollbacks.contains("msg")) {
1283 def target = MSG_TARGET
1284 if (salt.testTarget(pepperEnv, target)) {
1285 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1286 rollback(pepperEnv, target, 'msg')
1287 salt.enforceState(pepperEnv, target, 'rabbitmq')
1288 verifyService(pepperEnv, target, 'rabbitmq-server')
1289 } else {
1290 removeNode(pepperEnv, target, 'msg')
1291 }
1292 }
1293 }
1294
1295 if (rollbacks.contains("dbs")) {
1296 def target = DBS_TARGET
1297 if (salt.testTarget(pepperEnv, target)) {
1298 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1299 rollback(pepperEnv, target, 'dbs')
1300 clusterGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001301 verifyGalera(pepperEnv, target)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001302 } else {
1303 removeNode(pepperEnv, target, 'dbs')
1304 }
1305 }
1306 }
1307
1308 if (rollbacks.contains("ntw")) {
1309 def target = NTW_TARGET
1310 if (salt.testTarget(pepperEnv, target)) {
1311 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1312 rollback(pepperEnv, target, 'ntw')
1313 verifyContrail(pepperEnv, target)
1314 } else {
1315 removeNode(pepperEnv, target, 'ntw')
1316 }
1317 }
1318 }
1319
1320 if (rollbacks.contains("nal")) {
1321 def target = NAL_TARGET
1322 if (salt.testTarget(pepperEnv, target)) {
1323 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1324 rollback(pepperEnv, target, 'nal')
1325 verifyContrail(pepperEnv, target)
1326 } else {
1327 removeNode(pepperEnv, target, 'nal')
1328 }
1329 }
1330 }
1331
1332 if (rollbacks.contains("gtw-virtual")) {
1333 def target = GTW_TARGET
1334 if (salt.testTarget(pepperEnv, target)) {
1335 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1336 rollback(pepperEnv, target, 'gtw')
1337 verifyService(pepperEnv, target, 'neutron-dhcp-agent')
1338 } else {
1339 removeNode(pepperEnv, target, 'gtw')
1340 }
1341 }
1342 }
1343
1344 if (rollbacks.contains("cmn")) {
1345 def target = CMN_TARGET
1346 if (salt.testTarget(pepperEnv, target)) {
1347 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1348 rollback(pepperEnv, target, 'cmn')
1349 verifyCeph(pepperEnv, target, 'mon@')
1350 } else {
1351 removeNode(pepperEnv, target, 'cmn')
1352 }
1353 }
1354 }
1355
1356 if (rollbacks.contains("rgw")) {
1357 def target = RGW_TARGET
1358 if (salt.testTarget(pepperEnv, target)) {
1359 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1360 rollback(pepperEnv, target, 'rgw')
1361 verifyCeph(pepperEnv, target, 'radosgw@rgw.')
1362 } else {
1363 removeNode(pepperEnv, target, 'rgw')
1364 }
1365 }
1366 }
1367
1368 if (rollbacks.contains("log")) {
1369 def target = LOG_TARGET
1370 if (salt.testTarget(pepperEnv, target)) {
1371 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1372 rollback(pepperEnv, target, 'log')
1373 } else {
1374 removeNode(pepperEnv, target, 'log')
1375 }
1376 }
1377 }
1378
1379 if (rollbacks.contains("mon")) {
1380 def target = MON_TARGET
1381 if (salt.testTarget(pepperEnv, target)) {
1382 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1383 rollback(pepperEnv, target, 'mon')
1384 } else {
1385 removeNode(pepperEnv, target, 'mon')
1386 }
1387 }
1388 }
1389
1390 if (rollbacks.contains("mtr")) {
1391 def target = MTR_TARGET
1392 if (salt.testTarget(pepperEnv, target)) {
1393 if (!ROLLBACK_BY_REDEPLOY.toBoolean()) {
1394 rollback(pepperEnv, target, 'mtr')
1395 } else {
1396 removeNode(pepperEnv, target, 'mtr')
1397 }
1398 }
1399 }
1400 /*
1401 if (ROLLBACK_CID.toBoolean()) {
1402 def target = 'cid*'
1403 if (salt.testTarget(pepperEnv, target)) {
1404 stage('ROLLBACK_CID') {
1405 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."
1406 }
1407 }
1408 } */
1409
1410 //
1411 //physical machines rollback CMP_TARGET
1412 //
1413 if (rollbacks.contains("cmp")) {
1414 def target = CMP_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001415 def type = 'cmp'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001416 if (salt.testTarget(pepperEnv, target)) {
1417 if (PER_NODE.toBoolean()) {
1418 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1419 for (t in targetHosts) {
1420 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001421 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001422 }
1423 } else {
1424 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001425 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001426 }
1427 verifyService(pepperEnv, target, 'nova-compute')
1428 }
1429 }
1430
1431 if (rollbacks.contains("kvm")) {
1432 def target = KVM_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001433 def type = 'kvm'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001434 if (salt.testTarget(pepperEnv, target)) {
1435 if (PER_NODE.toBoolean()) {
1436 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1437 for (t in targetHosts) {
1438 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001439 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001440 }
1441 } else {
1442 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001443 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001444 }
1445 verifyService(pepperEnv, target, 'libvirt-bin')
1446 }
1447 }
1448
1449 if (rollbacks.contains("osd")) {
1450 def target = CEPH_OSD_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001451 def type = 'osd'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001452 if (salt.testTarget(pepperEnv, target)) {
1453 if (PER_NODE.toBoolean()) {
1454 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1455 for (t in targetHosts) {
1456 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001457 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001458 }
1459 } else {
1460 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001461 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001462 }
1463 verifyCephOsds(pepperEnv, target)
1464 }
1465 }
1466
1467 if (rollbacks.contains("gtw-physical")) {
1468 def target = GTW_TARGET
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001469 def type = 'gtw-physical'
Jiri Broulik60dcab32018-03-08 17:42:06 +01001470 if (salt.testTarget(pepperEnv, target)) {
1471 if (PER_NODE.toBoolean()) {
1472 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
1473 for (t in targetHosts) {
1474 rollbackPkgs(pepperEnv, t)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001475 highstate(pepperEnv, t, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001476 }
1477 } else {
1478 rollbackPkgs(pepperEnv, target, target)
Jiri Broulikba6d85d2018-04-05 13:29:07 +02001479 highstate(pepperEnv, target, type)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001480 }
1481 verifyService(pepperEnv, target, 'neutron-dhcp-agent')
1482 }
1483 }
1484
1485 /*
1486 * Merge snapshots section
1487 */
1488 if (merges.contains("cfg")) {
1489 if (salt.testTarget(pepperEnv, 'I@salt:master')) {
1490 mergeSnapshot(pepperEnv, 'I@salt:master')
1491 }
1492 }
1493
1494 if (merges.contains("ctl")) {
1495 if (salt.testTarget(pepperEnv, CTL_TARGET)) {
1496 mergeSnapshot(pepperEnv, CTL_TARGET, 'ctl')
Jiri Broulik906e9972018-03-26 16:12:00 +02001497 verifyService(pepperEnv, CTL_TARGET, 'nova-api')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001498 }
1499 }
1500
1501 if (merges.contains("prx")) {
1502 if (salt.testTarget(pepperEnv, PRX_TARGET)) {
1503 mergeSnapshot(pepperEnv, PRX_TARGET, 'prx')
Jiri Broulik906e9972018-03-26 16:12:00 +02001504 verifyService(pepperEnv, PRX_TARGET, 'nginx')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001505 }
1506 }
1507
1508 if (merges.contains("msg")) {
1509 if (salt.testTarget(pepperEnv, MSG_TARGET)) {
1510 mergeSnapshot(pepperEnv, MSG_TARGET, 'msg')
Jiri Broulik906e9972018-03-26 16:12:00 +02001511 verifyService(pepperEnv, MSG_TARGET, 'rabbitmq-server')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001512 }
1513 }
1514
1515 if (merges.contains("dbs")) {
1516 if (salt.testTarget(pepperEnv, DBS_TARGET)) {
1517 mergeSnapshot(pepperEnv, DBS_TARGET, 'dbs')
Jiri Broulikad606d02018-03-28 14:22:43 +02001518 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik906e9972018-03-26 16:12:00 +02001519 backupGalera(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001520 }
1521 }
1522
1523 if (merges.contains("ntw")) {
1524 if (salt.testTarget(pepperEnv, NTW_TARGET)) {
1525 mergeSnapshot(pepperEnv, NTW_TARGET, 'ntw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001526 verifyContrail(pepperEnv, NTW_TARGET)
1527 backupContrail(pepperEnv)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001528 }
1529 }
1530
1531 if (merges.contains("nal")) {
1532 if (salt.testTarget(pepperEnv, NAL_TARGET)) {
1533 mergeSnapshot(pepperEnv, NAL_TARGET, 'nal')
Jiri Broulik906e9972018-03-26 16:12:00 +02001534 verifyContrail(pepperEnv, NAL_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001535 }
1536 }
1537
1538 if (merges.contains("gtw-virtual")) {
1539 if (salt.testTarget(pepperEnv, GTW_TARGET)) {
1540 mergeSnapshot(pepperEnv, GTW_TARGET, 'gtw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001541 verifyService(pepperEnv, GTW_TARGET, 'neutron-dhcp-agent')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001542 }
1543 }
1544
1545 if (merges.contains("cmn")) {
1546 if (salt.testTarget(pepperEnv, CMN_TARGET)) {
1547 mergeSnapshot(pepperEnv, CMN_TARGET, 'cmn')
Jiri Broulik906e9972018-03-26 16:12:00 +02001548 verifyCeph(pepperEnv, CMN_TARGET, 'mon@')
1549 backupCeph(pepperEnv, CMN_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001550 }
1551 }
1552
1553 if (merges.contains("rgw")) {
1554 if (salt.testTarget(pepperEnv, RGW_TARGET)) {
1555 mergeSnapshot(pepperEnv, RGW_TARGET, 'rgw')
Jiri Broulik906e9972018-03-26 16:12:00 +02001556 verifyCeph(pepperEnv, RGW_TARGET, 'radosgw@rgw.')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001557 }
1558 }
1559
1560 if (merges.contains("log")) {
1561 if (salt.testTarget(pepperEnv, LOG_TARGET)) {
1562 mergeSnapshot(pepperEnv, LOG_TARGET. 'log')
1563 }
1564 }
1565
1566 if (merges.contains("mon")) {
1567 if (salt.testTarget(pepperEnv, MON_TARGET)) {
1568 mergeSnapshot(pepperEnv, MON_TARGET, 'mon')
1569 }
1570 }
1571
1572 if (merges.contains("mtr")) {
1573 if (salt.testTarget(pepperEnv, MTR_TARGET)) {
1574 mergeSnapshot(pepperEnv, MTR_TARGET, 'mtr')
1575 }
1576 }
1577
1578 if (merges.contains("cid")) {
1579 if (salt.testTarget(pepperEnv, CID_TARGET)) {
1580 mergeSnapshot(pepperEnv, CID_TARGET, 'cid')
Jiri Broulik906e9972018-03-26 16:12:00 +02001581 verifyService(pepperEnv, CID_TARGET, 'docker')
Jiri Broulik60dcab32018-03-08 17:42:06 +01001582 }
1583 }
1584
1585 if (RESTORE_GALERA.toBoolean()) {
1586 restoreGalera(pepperEnv)
Jiri Broulikad606d02018-03-28 14:22:43 +02001587 verifyGalera(pepperEnv, DBS_TARGET)
Jiri Broulik60dcab32018-03-08 17:42:06 +01001588 }
1589
1590 if (RESTORE_CONTRAIL_DB.toBoolean()) {
1591 restoreContrailDb(pepperEnv)
Jiri Broulik906e9972018-03-26 16:12:00 +02001592 // verification is already present in restore pipelines
Jiri Broulik60dcab32018-03-08 17:42:06 +01001593 }
1594
1595 } catch (Throwable e) {
1596 // If there was an error or exception thrown, the build failed
1597 currentBuild.result = "FAILURE"
1598 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
1599 throw e
1600 }
1601 }
1602}