blob: 14c2056116d9d7a50eab97eef2cb407f712d0fbe [file] [log] [blame]
Ales Komarek1fe5b8f2017-03-06 11:07:54 +01001/**
Ales Komarek374cc382017-03-16 08:49:01 +01002 * Update packages on given nodes
Ales Komarek1fe5b8f2017-03-06 11:07:54 +01003 *
4 * Expected parameters:
Ales Komarek374cc382017-03-16 08:49:01 +01005 * SALT_MASTER_CREDENTIALS Credentials to the Salt API.
6 * SALT_MASTER_URL Full Salt API address [https://10.10.10.1:8000].
7 * TARGET_SERVERS Salt compound target to match nodes to be updated [*, G@osfamily:debian].
8 * TARGET_PACKAGES Space delimited list of packages to be updates [package1=version package2=version], empty string means all updating all packages to the latest version.
Denis Egorenkoca6aeca2019-08-19 19:41:27 +04009 * BATCH_SIZE Use batching for large amount of target nodes
Ales Komarek1fe5b8f2017-03-06 11:07:54 +010010 *
11**/
Denis Egorenkoa9909262019-04-15 16:50:51 +040012
Pavel Cizinskyaf889c32018-08-15 15:20:42 +020013pepperEnv = "pepperEnv"
14salt = new com.mirantis.mk.Salt()
Denis Egorenkoa9909262019-04-15 16:50:51 +040015common = new com.mirantis.mk.Common()
Denis Egorenko4b54e7f2019-02-26 16:05:03 +040016
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040017def batch_size = ''
18if (common.validInputParam('BATCH_SIZE')) {
19 batch_size = "${BATCH_SIZE}"
20}
21
22def installSaltStack(target, pkgs, batch, masterUpdate = false){
Denis Egorenko4b54e7f2019-02-26 16:05:03 +040023 salt.cmdRun(pepperEnv, "I@salt:master", "salt -C '${target}' --async pkg.install force_yes=True pkgs='$pkgs'")
24 def minions_reachable = target
25 if (masterUpdate) {
26 // in case of update Salt Master packages - check all minions are good
27 minions_reachable = '*'
28 }
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040029 salt.checkTargetMinionsReady(['saltId': pepperEnv, 'target': target, 'target_reachable': minions_reachable, 'batch': batch])
Pavel Cizinskyaf889c32018-08-15 15:20:42 +020030}
31
Jakub Josefa63f9862018-01-11 17:58:38 +010032timeout(time: 12, unit: 'HOURS') {
33 node() {
34 try {
Denis Egorenkoa9909262019-04-15 16:50:51 +040035 def python = new com.mirantis.mk.Python()
36 def command = 'pkg.upgrade'
37 def commandKwargs = null
38 def packages = null
Jakub Josefa63f9862018-01-11 17:58:38 +010039 stage('Setup virtualenv for Pepper') {
40 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Tomáš Kukráld73cef02017-04-05 15:24:57 +020041 }
42
Denis Egorenkoa9909262019-04-15 16:50:51 +040043 def targetLiveAll = ''
44 stage('Get target servers') {
45 def minions = salt.getMinions(pepperEnv, TARGET_SERVERS)
Jakub Josefa63f9862018-01-11 17:58:38 +010046 if (minions.isEmpty()) {
47 throw new Exception("No minion was targeted")
48 }
Jakub Josefa63f9862018-01-11 17:58:38 +010049 targetLiveAll = minions.join(' or ')
50 common.infoMsg("Found nodes: ${targetLiveAll}")
Ales Komarek374cc382017-03-16 08:49:01 +010051 }
Tomáš Kukráld73cef02017-04-05 15:24:57 +020052
Jakub Josefa63f9862018-01-11 17:58:38 +010053 stage("List package upgrades") {
Denis Egorenkoa9909262019-04-15 16:50:51 +040054 common.infoMsg("Listing all the packages that have a new update available on nodes: ${targetLiveAll}")
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040055 salt.runSaltProcessStep(pepperEnv, targetLiveAll, 'pkg.list_upgrades', [], batch_size, true)
Denis Egorenkoa9909262019-04-15 16:50:51 +040056 if (TARGET_PACKAGES != '' && TARGET_PACKAGES != '*') {
Denis Egorenkodb1c9b02019-10-01 14:17:02 +040057 if (ALLOW_DEPENDENCY_UPDATE.toBoolean()) {
58 common.warningMsg("Note that the \"${TARGET_PACKAGES}\" and it new dependencies would be installed from the above list of available updates on the ${targetLiveAll}")
59 } else {
60 common.warningMsg("Note that only the \"${TARGET_PACKAGES}\" would be installed from the above list of available updates on the ${targetLiveAll}")
61 commandKwargs = ['only_upgrade': 'true']
62 }
Denis Egorenkoa9909262019-04-15 16:50:51 +040063 command = "pkg.install"
64 packages = TARGET_PACKAGES.tokenize(' ')
Martin Polreich6cb53622018-08-15 16:45:29 +020065 }
Jakub Josefa63f9862018-01-11 17:58:38 +010066 }
67
68 stage('Confirm package upgrades on all nodes') {
Jakub Josef4a013752017-03-16 17:37:51 +010069 timeout(time: 2, unit: 'HOURS') {
Denis Egorenkoa9909262019-04-15 16:50:51 +040070 input message: "Approve package upgrades on ${targetLiveAll} nodes?"
Jakub Josef4a013752017-03-16 17:37:51 +010071 }
Ales Komarek374cc382017-03-16 08:49:01 +010072 }
Jakub Josefc5407c42017-03-16 18:31:10 +010073
Jakub Josefa63f9862018-01-11 17:58:38 +010074 stage('Apply package upgrades on all nodes') {
Denis Egorenkoa9909262019-04-15 16:50:51 +040075 if (packages == null || packages.contains("salt-master") || packages.contains("salt-common") || packages.contains("salt-minion") || packages.contains("salt-api")) {
76 common.warningMsg('Detected update for some Salt package (master or minion). Updating it first.')
77 def saltTargets = (targetLiveAll.split(' or ').collect { it as String })
78 for (int i = 0; i < saltTargets.size(); i++ ) {
Pavel Cizinskyaf889c32018-08-15 15:20:42 +020079 common.retry(10, 5) {
Denis Egorenkoa9909262019-04-15 16:50:51 +040080 if (salt.getMinions(pepperEnv, "I@salt:master and ${saltTargets[i]}")) {
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040081 installSaltStack("I@salt:master and ${saltTargets[i]}", '["salt-master", "salt-common", "salt-api", "salt-minion"]', null, true)
Denis Egorenkoa9909262019-04-15 16:50:51 +040082 } else if (salt.getMinions(pepperEnv, "I@salt:minion and not I@salt:master and ${saltTargets[i]}")) {
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040083 installSaltStack("I@salt:minion and not I@salt:master and ${saltTargets[i]}", '["salt-minion"]', batch_size)
Denis Egorenkoa9909262019-04-15 16:50:51 +040084 } else {
85 error("Minion ${saltTargets[i]} is not reachable!")
Pavel Cizinskyaf889c32018-08-15 15:20:42 +020086 }
87 }
88 }
89 }
Denis Egorenkoa9909262019-04-15 16:50:51 +040090 common.infoMsg('Starting package upgrades...')
Denis Egorenkoca6aeca2019-08-19 19:41:27 +040091 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, batch_size, packages, commandKwargs)
Jakub Josefa63f9862018-01-11 17:58:38 +010092 salt.printSaltCommandResult(out)
Martin Polreich6cb53622018-08-15 16:45:29 +020093 for(value in out.get("return")[0].values()){
94 if (value.containsKey('result') && value.result == false) {
Denis Egorenkoa9909262019-04-15 16:50:51 +040095 throw new Exception("The package upgrade on nodes has failed. Please check the Salt run result above for more information.")
Martin Polreich6cb53622018-08-15 16:45:29 +020096 }
97 }
Ales Komarek374cc382017-03-16 08:49:01 +010098 }
Ales Komarek374cc382017-03-16 08:49:01 +010099
Denis Egorenkoa9909262019-04-15 16:50:51 +0400100 common.warningMsg("Pipeline has finished successfully, but please, check if any packages have been kept back.")
101
Jakub Josefa63f9862018-01-11 17:58:38 +0100102 } catch (Throwable e) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100103 currentBuild.result = "FAILURE"
104 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
105 throw e
Ales Komarek374cc382017-03-16 08:49:01 +0100106 }
Ales Komarek1fe5b8f2017-03-06 11:07:54 +0100107 }
108}