blob: 2984b55cf6279250e1fdef9f468d0d1cf94e6f97 [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.
Vasyl Saienko1a034dd2018-06-22 15:33:37 +030010 * INTERACTIVE Ask interactive questions during pipeline run (bool).
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020011 *
12**/
13
14def common = new com.mirantis.mk.Common()
15def salt = new com.mirantis.mk.Salt()
chnyda625f4b42017-10-11 14:10:31 +020016def python = new com.mirantis.mk.Python()
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020017
chnyda625f4b42017-10-11 14:10:31 +020018def pepperEnv = "pepperEnv"
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020019def targetTestSubset
20def targetLiveSubset
21def targetLiveAll
22def minions
23def result
Jiri Broulik52a6b832017-06-16 13:05:08 +020024def args
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020025def command
26def commandKwargs
Jiri Broulik52a6b832017-06-16 13:05:08 +020027def probe = 1
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020028
Jakub Josefa63f9862018-01-11 17:58:38 +010029timeout(time: 12, unit: 'HOURS') {
30 node() {
Jiri Broulik52a6b832017-06-16 13:05:08 +020031 try {
Jiri Broulik52a6b832017-06-16 13:05:08 +020032
Jakub Josefa63f9862018-01-11 17:58:38 +010033 stage('Setup virtualenv for Pepper') {
34 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Jiri Broulik52a6b832017-06-16 13:05:08 +020035 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020036
Jakub Josefa63f9862018-01-11 17:58:38 +010037 stage('List target servers') {
38 minions = salt.getMinions(pepperEnv, TARGET_SERVERS)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020039
Jakub Josefa63f9862018-01-11 17:58:38 +010040 if (minions.isEmpty()) {
41 throw new Exception("No minion was targeted")
Jiri Broulikcbad2f12017-11-23 17:15:36 +010042 }
Jakub Josefa63f9862018-01-11 17:58:38 +010043
44 if (TARGET_SUBSET_TEST != "") {
45 targetTestSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_TEST)).join(' or ')
46 } else {
47 targetTestSubset = minions.join(' or ')
Jiri Broulikcbad2f12017-11-23 17:15:36 +010048 }
Jakub Josefa63f9862018-01-11 17:58:38 +010049 targetLiveSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_LIVE)).join(' or ')
50 targetTestSubsetProbe = minions.subList(0, probe).join(' or ')
51 targetLiveSubsetProbe = minions.subList(0, probe).join(' or ')
52
53 targetLiveAll = minions.join(' or ')
54 common.infoMsg("Found nodes: ${targetLiveAll}")
55 common.infoMsg("Selected test nodes: ${targetTestSubset}")
56 common.infoMsg("Selected sample nodes: ${targetLiveSubset}")
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020057 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020058
Jiri Broulik52a6b832017-06-16 13:05:08 +020059
Jakub Josefa63f9862018-01-11 17:58:38 +010060 stage("Add new repos on test nodes") {
61 salt.enforceState(pepperEnv, targetTestSubset, 'linux.system.repo')
62 }
63
64
65 opencontrail = null
66
Jiri Broulik52a6b832017-06-16 13:05:08 +020067 try {
Jakub Josefa63f9862018-01-11 17:58:38 +010068 opencontrail = salt.cmdRun(pepperEnv, targetTestSubsetProbe, "salt-call grains.item roles | grep opencontrail.compute")
69 print(opencontrail)
Jiri Broulik52a6b832017-06-16 13:05:08 +020070 } catch (Exception er) {
Jakub Josefa63f9862018-01-11 17:58:38 +010071 common.infoMsg("opencontrail is not used")
Jiri Broulik52a6b832017-06-16 13:05:08 +020072 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020073
Jakub Josefa63f9862018-01-11 17:58:38 +010074 if(opencontrail != null) {
75 stage('Remove OC component from repos on test nodes') {
76 def contrail_repo_file1 = ''
77 def contrail_repo_file2 = ''
78 try {
79 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
80 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
81 } catch (Exception er) {
82 common.warningMsg(er)
83 }
84 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'")
85 try {
86 salt.cmdRun(pepperEnv, targetTestSubset, "salt-call pkg.refresh_db")
87 } catch (Exception er) {
88 common.warningMsg(er)
89 // remove the malformed repo entry
90 salt.cmdRun(pepperEnv, targetTestSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
91 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.refresh_db', [], null, true)
92 }
93 }
94 }
Jiri Broulik52a6b832017-06-16 13:05:08 +020095
Jakub Josefa63f9862018-01-11 17:58:38 +010096 stage("List package upgrades") {
97 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.list_upgrades', [], null, true)
98 }
Jiri Broulik52a6b832017-06-16 13:05:08 +020099
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300100 if (INTERACTIVE.toBoolean()){
101 stage('Confirm upgrade on sample nodes') {
Jakub Josefa63f9862018-01-11 17:58:38 +0100102 input message: "Please verify the list of packages that you want to be upgraded. Do you want to continue with upgrade?"
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300103 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100104 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200105
Jakub Josefa63f9862018-01-11 17:58:38 +0100106 stage("Add new repos on sample nodes") {
107 salt.enforceState(pepperEnv, targetLiveSubset, 'linux.system.repo')
108 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200109
Jakub Josefa63f9862018-01-11 17:58:38 +0100110 if(opencontrail != null) {
111 stage('Remove OC component from repos on sample nodes') {
112 def contrail_repo_file1 = ''
113 def contrail_repo_file2 = ''
114 try {
115 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
116 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
117 } catch (Exception er) {
118 common.warningMsg(er)
119 }
120 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'")
121 try {
122 salt.cmdRun(pepperEnv, targetLiveSubset, "salt-call pkg.refresh_db")
123 } catch (Exception er) {
124 common.warningMsg(er)
125 // remove the malformed repo entry
126 salt.cmdRun(pepperEnv, targetLiveSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
127 salt.runSaltProcessStep(pepperEnv, targetLiveSubset, 'pkg.refresh_db', [], null, true)
128 }
129 }
130 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200131
Jakub Josefa63f9862018-01-11 17:58:38 +0100132 args = "apt-get -y -s -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200133
Jakub Josefa63f9862018-01-11 17:58:38 +0100134 stage('Test upgrade on sample') {
135 try {
136 salt.cmdRun(pepperEnv, targetLiveSubset, args)
137 } catch (Exception er) {
138 print(er)
139 }
140 }
141
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300142 if (INTERACTIVE.toBoolean()){
143 stage('Confirm upgrade on sample') {
Jakub Josefa63f9862018-01-11 17:58:38 +0100144 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?"
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300145 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100146 }
147
148 command = "cmd.run"
149 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
150
151 stage('Apply package upgrades on sample') {
chnyda625f4b42017-10-11 14:10:31 +0200152 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200153 salt.printSaltCommandResult(out)
154 }
Jiri Broulik07292b42017-06-22 18:45:49 +0200155
Jakub Josefa63f9862018-01-11 17:58:38 +0100156 openvswitch = null
157
Jiri Broulik07292b42017-06-22 18:45:49 +0200158 try {
Jakub Josefa63f9862018-01-11 17:58:38 +0100159 openvswitch = salt.cmdRun(pepperEnv, targetLiveSubsetProbe, "salt-call grains.item roles | grep neutron.compute")
Jiri Broulik07292b42017-06-22 18:45:49 +0200160 } catch (Exception er) {
Jakub Josefa63f9862018-01-11 17:58:38 +0100161 common.infoMsg("openvswitch is not used")
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200162 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200163
Jakub Josefa63f9862018-01-11 17:58:38 +0100164 if(openvswitch != null) {
165 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200166
Jakub Josefa63f9862018-01-11 17:58:38 +0100167 stage('Start ovs on sample nodes') {
168 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
169 salt.printSaltCommandResult(out)
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100170 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100171 stage("Run salt states on sample nodes") {
172 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'neutron'])
173 }
174 } else {
175 stage("Run salt states on sample nodes") {
176 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'linux.system.repo'])
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100177 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200178 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200179
Jakub Josefa63f9862018-01-11 17:58:38 +0100180 stage("Run Highstate on sample nodes") {
181 try {
182 salt.enforceHighstate(pepperEnv, targetLiveSubset)
183 } catch (Exception er) {
184 common.errorMsg("Highstate was executed on ${targetLiveSubset} but something failed. Please check it and fix it accordingly.")
185 }
186 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200187
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300188 if (INTERACTIVE.toBoolean()){
189 stage('Confirm upgrade on all targeted nodes') {
Jakub Josefa63f9862018-01-11 17:58:38 +0100190 timeout(time: 2, unit: 'HOURS') {
191 input message: "Verify that the upgraded sample nodes are working correctly. If so, do you want to approve live upgrade on ${targetLiveAll} nodes?"
192 }
Vasyl Saienko1a034dd2018-06-22 15:33:37 +0300193 }
Jakub Josefa63f9862018-01-11 17:58:38 +0100194 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200195
Jakub Josefa63f9862018-01-11 17:58:38 +0100196 stage("Add new repos on all targeted nodes") {
197 salt.enforceState(pepperEnv, targetLiveAll, 'linux.system.repo')
198 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200199
Jakub Josefa63f9862018-01-11 17:58:38 +0100200 if(opencontrail != null) {
201 stage('Remove OC component from repos on all targeted nodes') {
202 def contrail_repo_file1 = ''
203 def contrail_repo_file2 = ''
204 try {
205 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
206 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
207 } catch (Exception er) {
208 common.warningMsg(er)
209 }
210 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'")
211 try {
212 salt.cmdRun(pepperEnv, targetLiveAll, "salt-call pkg.refresh_db")
213 } catch (Exception er) {
214 common.warningMsg(er)
215 // remove the malformed repo entry
216 salt.cmdRun(pepperEnv, targetLiveAll, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
217 salt.runSaltProcessStep(pepperEnv, targetLiveAll, 'pkg.refresh_db', [], null, true)
218 }
219 }
220 }
221
222 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
223
224 stage('Apply package upgrades on all targeted nodes') {
chnyda625f4b42017-10-11 14:10:31 +0200225 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200226 salt.printSaltCommandResult(out)
227 }
Jiri Broulik07292b42017-06-22 18:45:49 +0200228
Jakub Josefa63f9862018-01-11 17:58:38 +0100229 if(openvswitch != null) {
230 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
Jiri Broulik52a6b832017-06-16 13:05:08 +0200231
Jakub Josefa63f9862018-01-11 17:58:38 +0100232 stage('Start ovs on all targeted nodes') {
233 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
234 salt.printSaltCommandResult(out)
235 }
236 stage("Run salt states on all targeted nodes") {
237 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'neutron'])
238 }
239 } else {
240 stage("Run salt states on all targeted nodes") {
241 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'linux.system.repo'])
242 }
243 }
244
245 stage("Run Highstate on all targeted nodes") {
246 try {
247 salt.enforceHighstate(pepperEnv, targetLiveAll)
248 } catch (Exception er) {
249 common.errorMsg("Highstate was executed ${targetLiveAll} but something failed. Please check it and fix it accordingly.")
250 }
251 }
252
253 } catch (Throwable e) {
254 // If there was an error or exception thrown, the build failed
255 currentBuild.result = "FAILURE"
256 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
257 throw e
258 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200259 }
260}
Jiri Broulik52a6b832017-06-16 13:05:08 +0200261