blob: 96c883672ab051ca9d431a439505c9ae653a5d72 [file] [log] [blame]
Alena Kiseleva895bc7a2018-12-07 17:03:02 +03001/**
Alena Kiselevaf99b1162019-06-12 13:16:33 +03002 * Update packages
Alena Kiseleva895bc7a2018-12-07 17:03:02 +03003 *
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].
Alena Kiseleva895bc7a2018-12-07 17:03:02 +03007 */
8
9pepperEnv = "pepperEnv"
Denis Egorenko82309ca2021-06-18 17:14:45 +040010def common = new com.mirantis.mk.Common()
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040011def salt = new com.mirantis.mk.Salt()
12def ceph = new com.mirantis.mk.Ceph()
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030013def python = new com.mirantis.mk.Python()
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030014def packages
15def command
16def commandKwargs
17def selMinions = []
Ivan Berezovskiy4c39c7d2019-11-19 20:04:12 +040018def flags = CLUSTER_FLAGS ? CLUSTER_FLAGS.tokenize(',') : []
Mateusz Losc5de5c82020-05-11 10:37:23 +020019def runHighState = RUNHIGHSTATE
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030020
Denis Egorenko82309ca2021-06-18 17:14:45 +040021def collectPkgVersion(target, packageName) {
22 def salt = new com.mirantis.mk.Salt()
23 return salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], "pkg.version", true, packageName)
24}
25
26def getChangedPkgs(oldVersions, newVersions) {
27 def common = new com.mirantis.mk.Common()
28 def changedPkgs = [:]
29 def updated = false
30 newVersions.each { k, v ->
31 changedPkgs[k] = [:]
32 if (v == null || !v['return'] || oldVersions[k] == null || !oldVersions[k]['return']) {
33 common.warningMsg("Can't detect package version changes for ceph-${k} packages")
34 changedPkgs[k]["*"] = true
35 updated = true
36 return
37 }
38
39 // since run was not in batch mode, get only 0 element which contains all output
40 v['return'][0].each { tgt, newPgkVersion ->
41 oldVersion = oldVersions[k]['return'][0].get(tgt, "")
42 if (oldVersion == newPgkVersion) {
43 changedPkgs[k][tgt] = false
44 return
45 }
46 common.infoMsg("${tgt} has updated ceph ${k} packages ${oldVersion} -> ${newPgkVersion}")
47 updated = true
48 changedPkgs[k][tgt] = true
49 }
50 }
51 return ["updated": updated, "changed": changedPkgs]
52}
53
54// if some map contains tgt and has true value - restart needed
55def needToRestart(infoPkgs, daemon, tgt) {
56 if (infoPkgs[daemon].get("*", false) || infoPkgs[daemon].get(tgt, false) || infoPkgs["common"].get(tgt, false)) {
57 return true
58 }
59 return false
60}
61
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030062timeout(time: 12, unit: 'HOURS') {
63 node() {
64 try {
Alena Kiselevaf99b1162019-06-12 13:16:33 +030065 def targets = ["common": "ceph-common", "osd": "ceph-osd", "mon": "ceph-mon",
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040066 "mgr" : "ceph-mgr", "radosgw": "radosgw"]
Alena Kiselevaf99b1162019-06-12 13:16:33 +030067
Denis Egorenko82309ca2021-06-18 17:14:45 +040068 def oldPackageVersions = [:]
69 def newPackageVersions = [:]
70
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030071 stage('Setup virtualenv for Pepper') {
72 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
73 }
74
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030075 stage('Apply package upgrades on all nodes') {
Alena Kiselevaf99b1162019-06-12 13:16:33 +030076 targets.each { key, value ->
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040077 target = "I@ceph:${key}"
Denis Egorenko82309ca2021-06-18 17:14:45 +040078 packages = value
79 // check package versions before upgrade to compare it after update run
80 oldPackageVersions[key] = collectPkgVersion(target, packages)
81 salt.enforceState(pepperEnv, target, 'linux.system.repo', true)
82 command = "pkg.install"
83 commandKwargs = ['only_upgrade': 'true', 'force_yes': 'true']
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +040084 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': target, 'type': 'compound'], command, true, packages, commandKwargs)
85 salt.printSaltCommandResult(out)
Denis Egorenko82309ca2021-06-18 17:14:45 +040086 // check package version after update
87 newPackageVersions[key] = collectPkgVersion(target, packages)
Alena Kiseleva895bc7a2018-12-07 17:03:02 +030088 }
89 }
90
Denis Egorenko82309ca2021-06-18 17:14:45 +040091 def packageChanges = getChangedPkgs(oldPackageVersions, newPackageVersions)
92
93 if (!packageChanges["updated"]) {
94 common.infoMsg("Ceph packages were not updated, skipping service restart")
95 return
96 }
97
Mateusz Losc5de5c82020-05-11 10:37:23 +020098 stage('Set cluster flags') {
Denis Egorenko82309ca2021-06-18 17:14:45 +040099 common.infoMsg("Ceph packages update detected, setting cluster noout flag")
Mateusz Losc5de5c82020-05-11 10:37:23 +0200100 if (flags.size() > 0) {
101 stage('Set cluster flags') {
102 for (flag in flags) {
103 salt.cmdRun(pepperEnv, "I@ceph:mon and I@ceph:common:keyring:admin", 'ceph osd set ' + flag)
104 }
105 }
106 }
107 }
108
Denis Egorenko82309ca2021-06-18 17:14:45 +0400109 stage("Restart MONs/MGRs") {
110 ["mon", "mgr"].each {daemon ->
111 selMinions = salt.getMinions(pepperEnv, "I@ceph:${daemon}")
112 for (tgt in selMinions) {
113 if (!needToRestart(packageChanges["changed"], daemon, tgt)) {
114 common.infoMsg("Node ${tgt} has no updated ceph packages, skipping service restart on it")
115 continue
116 }
117 // runSaltProcessStep 'service.restart' don't work for this services
118 salt.cmdRun(pepperEnv, tgt, "systemctl restart ceph-${daemon}.target")
119 ceph.waitForHealthy(pepperEnv, tgt, flags)
120 if (runHighState) {
121 salt.enforceHighstate(pepperEnv, tgt)
122 }
Mateusz Losc5de5c82020-05-11 10:37:23 +0200123 }
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300124 }
125 }
126
127 stage('Restart OSDs') {
Mateusz Los2ae66db2020-04-28 16:36:11 +0200128 def device_grain_name = "ceph_disk"
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300129 selMinions = salt.getMinions(pepperEnv, "I@ceph:osd")
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300130 for (tgt in selMinions) {
Denis Egorenko82309ca2021-06-18 17:14:45 +0400131 if (!needToRestart(packageChanges["changed"], "osd", tgt)) {
132 common.infoMsg("Node ${tgt} has no updated ceph packages, skipping service restart on it")
133 continue
134 }
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300135 salt.runSaltProcessStep(pepperEnv, tgt, 'saltutil.sync_grains', [], null, true, 5)
mjedynski12955c72019-12-09 15:17:58 +0100136 def ceph_disks = salt.getGrain(pepperEnv, tgt, 'ceph')['return'][0].values()[0].values()[0][device_grain_name]
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300137
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300138 def osd_ids = []
139 for (i in ceph_disks) {
140 def osd_id = i.getKey().toString()
141 osd_ids.add('osd.' + osd_id)
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300142 }
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300143
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +0400144 salt.cmdRun(pepperEnv, tgt, 'ceph osd set noout')
Ivan Berezovskiy4c39c7d2019-11-19 20:04:12 +0400145 flags = 'noout' in flags ? flags : flags + ['noout']
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300146
147 for (i in osd_ids) {
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +0400148 salt.runSaltProcessStep(pepperEnv, tgt, 'service.restart', ['ceph-osd@' + i.replaceAll('osd.', '')], null, true)
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300149 // wait for healthy cluster
Tomek Jaroszyk08ad67e2020-11-09 13:58:02 +0100150 ceph.waitForHealthy(pepperEnv, tgt, flags, 100)
Alena Kiselevaf99b1162019-06-12 13:16:33 +0300151 }
152
Mateusz Losc5de5c82020-05-11 10:37:23 +0200153 if (runHighState) {
154 salt.enforceHighstate(pepperEnv, tgt)
155 }
156
Ivan Berezovskiy19c685a2019-11-05 17:42:57 +0400157 salt.cmdRun(pepperEnv, tgt, 'ceph osd unset noout')
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300158 }
159 }
160
Mateusz Losc5de5c82020-05-11 10:37:23 +0200161 stage('Restart RGWs') {
162 selMinions = salt.getMinions(pepperEnv, "I@ceph:radosgw")
163 for (tgt in selMinions) {
Denis Egorenko82309ca2021-06-18 17:14:45 +0400164 if (!needToRestart(packageChanges["changed"], "radosgw", tgt)) {
165 common.infoMsg("Node ${tgt} has no updated ceph packages, skipping service restart on it")
166 continue
167 }
Mateusz Losc5de5c82020-05-11 10:37:23 +0200168 salt.cmdRun(pepperEnv, tgt, "systemctl restart ceph-radosgw.target")
169 ceph.waitForHealthy(pepperEnv, tgt, flags)
170 if (runHighState) {
171 salt.enforceHighstate(pepperEnv, tgt)
172 }
173 }
174 }
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300175 } catch (Throwable e) {
176 // If there was an error or exception thrown, the build failed
Mateusz Los05849762020-05-11 09:59:32 +0200177 if (flags.size() > 0) {
178 stage('Unset cluster flags') {
179 for (flag in flags) {
180 salt.cmdRun(pepperEnv, "I@ceph:mon and I@ceph:common:keyring:admin", 'ceph osd unset ' + flag)
181 }
182 }
183 }
Alena Kiseleva895bc7a2018-12-07 17:03:02 +0300184 currentBuild.result = "FAILURE"
185 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
186 throw e
187 }
188 }
Tomek Jaroszyk6d8a3aa2020-07-07 12:07:40 +0200189}