blob: a59fc08ca0d4871d2e5052c49102c13ea1fcb2b0 [file] [log] [blame]
Jiri Broulik9b73d6c2017-06-02 12:27:05 +02001/**
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 * TARGET_SERVERS Salt compound target to match nodes to be updated [*, G@osfamily:debian].
Jiri Broulik9b73d6c2017-06-02 12:27:05 +02008 * TARGET_SUBSET_TEST Number of nodes to list package updates, empty string means all targetted nodes.
9 * TARGET_SUBSET_LIVE Number of selected nodes to live apply selected package update.
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020010 *
11**/
12
13def common = new com.mirantis.mk.Common()
14def salt = new com.mirantis.mk.Salt()
chnyda625f4b42017-10-11 14:10:31 +020015def python = new com.mirantis.mk.Python()
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020016
chnyda625f4b42017-10-11 14:10:31 +020017def pepperEnv = "pepperEnv"
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020018def targetTestSubset
19def targetLiveSubset
20def targetLiveAll
21def minions
22def result
Jiri Broulik52a6b832017-06-16 13:05:08 +020023def args
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020024def command
25def commandKwargs
Jiri Broulik52a6b832017-06-16 13:05:08 +020026def probe = 1
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020027
Jakub Josefa63f9862018-01-11 17:58:38 +010028timeout(time: 12, unit: 'HOURS') {
29 node() {
Jiri Broulik52a6b832017-06-16 13:05:08 +020030 try {
Jiri Broulik52a6b832017-06-16 13:05:08 +020031
Jakub Josefa63f9862018-01-11 17:58:38 +010032 stage('Setup virtualenv for Pepper') {
33 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Jiri Broulik52a6b832017-06-16 13:05:08 +020034 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020035
Jakub Josefa63f9862018-01-11 17:58:38 +010036 stage('List target servers') {
37 minions = salt.getMinions(pepperEnv, TARGET_SERVERS)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020038
Jakub Josefa63f9862018-01-11 17:58:38 +010039 if (minions.isEmpty()) {
40 throw new Exception("No minion was targeted")
Jiri Broulikcbad2f12017-11-23 17:15:36 +010041 }
Jakub Josefa63f9862018-01-11 17:58:38 +010042
43 if (TARGET_SUBSET_TEST != "") {
44 targetTestSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_TEST)).join(' or ')
45 } else {
46 targetTestSubset = minions.join(' or ')
Jiri Broulikcbad2f12017-11-23 17:15:36 +010047 }
Jakub Josefa63f9862018-01-11 17:58:38 +010048 targetLiveSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_LIVE)).join(' or ')
49 targetTestSubsetProbe = minions.subList(0, probe).join(' or ')
50 targetLiveSubsetProbe = minions.subList(0, probe).join(' or ')
51
52 targetLiveAll = minions.join(' or ')
53 common.infoMsg("Found nodes: ${targetLiveAll}")
54 common.infoMsg("Selected test nodes: ${targetTestSubset}")
55 common.infoMsg("Selected sample nodes: ${targetLiveSubset}")
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020056 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020057
Jiri Broulik52a6b832017-06-16 13:05:08 +020058
Jakub Josefa63f9862018-01-11 17:58:38 +010059 stage("Add new repos on test nodes") {
60 salt.enforceState(pepperEnv, targetTestSubset, 'linux.system.repo')
61 }
62
63
64 opencontrail = null
65
Jiri Broulik52a6b832017-06-16 13:05:08 +020066 try {
Jakub Josefa63f9862018-01-11 17:58:38 +010067 opencontrail = salt.cmdRun(pepperEnv, targetTestSubsetProbe, "salt-call grains.item roles | grep opencontrail.compute")
68 print(opencontrail)
Jiri Broulik52a6b832017-06-16 13:05:08 +020069 } catch (Exception er) {
Jakub Josefa63f9862018-01-11 17:58:38 +010070 common.infoMsg("opencontrail is not used")
Jiri Broulik52a6b832017-06-16 13:05:08 +020071 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020072
Jakub Josefa63f9862018-01-11 17:58:38 +010073 if(opencontrail != null) {
74 stage('Remove OC component from repos on test nodes') {
75 def contrail_repo_file1 = ''
76 def contrail_repo_file2 = ''
77 try {
78 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
79 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
80 } catch (Exception er) {
81 common.warningMsg(er)
82 }
83 salt.cmdRun(pepperEnv, targetTestSubset, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g;s/ oc([0-9]*\$)//g'")
84 try {
85 salt.cmdRun(pepperEnv, targetTestSubset, "salt-call pkg.refresh_db")
86 } catch (Exception er) {
87 common.warningMsg(er)
88 // remove the malformed repo entry
89 salt.cmdRun(pepperEnv, targetTestSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
90 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.refresh_db', [], null, true)
91 }
92 }
93 }
Jiri Broulik52a6b832017-06-16 13:05:08 +020094
Jakub Josefa63f9862018-01-11 17:58:38 +010095 stage("List package upgrades") {
96 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.list_upgrades', [], null, true)
97 }
Jiri Broulik52a6b832017-06-16 13:05:08 +020098
Jakub Josefa63f9862018-01-11 17:58:38 +010099 stage('Confirm upgrade on sample nodes') {
100 input message: "Please verify the list of packages that you want to be upgraded. Do you want to continue with upgrade?"
101 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200102
Jakub Josefa63f9862018-01-11 17:58:38 +0100103 stage("Add new repos on sample nodes") {
104 salt.enforceState(pepperEnv, targetLiveSubset, 'linux.system.repo')
105 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200106
Jakub Josefa63f9862018-01-11 17:58:38 +0100107 if(opencontrail != null) {
108 stage('Remove OC component from repos on sample nodes') {
109 def contrail_repo_file1 = ''
110 def contrail_repo_file2 = ''
111 try {
112 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
113 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
114 } catch (Exception er) {
115 common.warningMsg(er)
116 }
117 salt.cmdRun(pepperEnv, targetLiveSubset, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g;s/ oc([0-9]*\$)//g'")
118 try {
119 salt.cmdRun(pepperEnv, targetLiveSubset, "salt-call pkg.refresh_db")
120 } catch (Exception er) {
121 common.warningMsg(er)
122 // remove the malformed repo entry
123 salt.cmdRun(pepperEnv, targetLiveSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
124 salt.runSaltProcessStep(pepperEnv, targetLiveSubset, 'pkg.refresh_db', [], null, true)
125 }
126 }
127 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200128
Jakub Josefa63f9862018-01-11 17:58:38 +0100129 args = "apt-get -y -s -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200130
Jakub Josefa63f9862018-01-11 17:58:38 +0100131 stage('Test upgrade on sample') {
132 try {
133 salt.cmdRun(pepperEnv, targetLiveSubset, args)
134 } catch (Exception er) {
135 print(er)
136 }
137 }
138
139 stage('Confirm upgrade on sample') {
140 input message: "Please verify if there are packages that it wants to downgrade. If so, execute apt-cache policy on them and verify if everything is fine. Do you want to continue with upgrade?"
141 }
142
143 command = "cmd.run"
144 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
145
146 stage('Apply package upgrades on sample') {
chnyda625f4b42017-10-11 14:10:31 +0200147 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200148 salt.printSaltCommandResult(out)
149 }
Jiri Broulik07292b42017-06-22 18:45:49 +0200150
Jakub Josefa63f9862018-01-11 17:58:38 +0100151 openvswitch = null
152
Jiri Broulik07292b42017-06-22 18:45:49 +0200153 try {
Jakub Josefa63f9862018-01-11 17:58:38 +0100154 openvswitch = salt.cmdRun(pepperEnv, targetLiveSubsetProbe, "salt-call grains.item roles | grep neutron.compute")
Jiri Broulik07292b42017-06-22 18:45:49 +0200155 } catch (Exception er) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100156 common.infoMsg("openvswitch is not used")
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200157 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200158
Jakub Josefa63f9862018-01-11 17:58:38 +0100159 if(openvswitch != null) {
160 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200161
Jakub Josefa63f9862018-01-11 17:58:38 +0100162 stage('Start ovs on sample nodes') {
163 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
164 salt.printSaltCommandResult(out)
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100165 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100166 stage("Run salt states on sample nodes") {
167 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'neutron'])
168 }
169 } else {
170 stage("Run salt states on sample nodes") {
171 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'linux.system.repo'])
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100172 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200173 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200174
Jakub Josefa63f9862018-01-11 17:58:38 +0100175 stage("Run Highstate on sample nodes") {
176 try {
177 salt.enforceHighstate(pepperEnv, targetLiveSubset)
178 } catch (Exception er) {
179 common.errorMsg("Highstate was executed on ${targetLiveSubset} but something failed. Please check it and fix it accordingly.")
180 }
181 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200182
Jakub Josefa63f9862018-01-11 17:58:38 +0100183 stage('Confirm upgrade on all targeted nodes') {
184 timeout(time: 2, unit: 'HOURS') {
185 input message: "Verify that the upgraded sample nodes are working correctly. If so, do you want to approve live upgrade on ${targetLiveAll} nodes?"
186 }
187 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200188
Jakub Josefa63f9862018-01-11 17:58:38 +0100189 stage("Add new repos on all targeted nodes") {
190 salt.enforceState(pepperEnv, targetLiveAll, 'linux.system.repo')
191 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200192
Jakub Josefa63f9862018-01-11 17:58:38 +0100193 if(opencontrail != null) {
194 stage('Remove OC component from repos on all targeted nodes') {
195 def contrail_repo_file1 = ''
196 def contrail_repo_file2 = ''
197 try {
198 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
199 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
200 } catch (Exception er) {
201 common.warningMsg(er)
202 }
203 salt.cmdRun(pepperEnv, targetLiveAll, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g;s/ oc([0-9]*\$)//g'")
204 try {
205 salt.cmdRun(pepperEnv, targetLiveAll, "salt-call pkg.refresh_db")
206 } catch (Exception er) {
207 common.warningMsg(er)
208 // remove the malformed repo entry
209 salt.cmdRun(pepperEnv, targetLiveAll, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
210 salt.runSaltProcessStep(pepperEnv, targetLiveAll, 'pkg.refresh_db', [], null, true)
211 }
212 }
213 }
214
215 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
216
217 stage('Apply package upgrades on all targeted nodes') {
chnyda625f4b42017-10-11 14:10:31 +0200218 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200219 salt.printSaltCommandResult(out)
220 }
Jiri Broulik07292b42017-06-22 18:45:49 +0200221
Jakub Josefa63f9862018-01-11 17:58:38 +0100222 if(openvswitch != null) {
223 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200224
Jakub Josefa63f9862018-01-11 17:58:38 +0100225 stage('Start ovs on all targeted nodes') {
226 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
227 salt.printSaltCommandResult(out)
228 }
229 stage("Run salt states on all targeted nodes") {
230 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'neutron'])
231 }
232 } else {
233 stage("Run salt states on all targeted nodes") {
234 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'linux.system.repo'])
235 }
236 }
237
238 stage("Run Highstate on all targeted nodes") {
239 try {
240 salt.enforceHighstate(pepperEnv, targetLiveAll)
241 } catch (Exception er) {
242 common.errorMsg("Highstate was executed ${targetLiveAll} but something failed. Please check it and fix it accordingly.")
243 }
244 }
245
246 } catch (Throwable e) {
247 // If there was an error or exception thrown, the build failed
248 currentBuild.result = "FAILURE"
249 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
250 throw e
251 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200252 }
253}
Jiri Broulik52a6b832017-06-16 13:05:08 +0200254