blob: 6c8ffdf8c7a503a5bae5263184a40dd12c3adcdb [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
28node() {
29 try {
30
chnyda625f4b42017-10-11 14:10:31 +020031 stage('Setup virtualenv for Pepper') {
Dmitrii Kabanovf31c8962017-10-12 21:00:30 -070032 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020033 }
34
35 stage('List target servers') {
chnyda625f4b42017-10-11 14:10:31 +020036 minions = salt.getMinions(pepperEnv, TARGET_SERVERS)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020037
38 if (minions.isEmpty()) {
39 throw new Exception("No minion was targeted")
40 }
41
42 if (TARGET_SUBSET_TEST != "") {
43 targetTestSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_TEST)).join(' or ')
44 } else {
45 targetTestSubset = minions.join(' or ')
46 }
47 targetLiveSubset = minions.subList(0, Integer.valueOf(TARGET_SUBSET_LIVE)).join(' or ')
Jiri Broulik52a6b832017-06-16 13:05:08 +020048 targetTestSubsetProbe = minions.subList(0, probe).join(' or ')
49 targetLiveSubsetProbe = minions.subList(0, probe).join(' or ')
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020050
51 targetLiveAll = minions.join(' or ')
52 common.infoMsg("Found nodes: ${targetLiveAll}")
53 common.infoMsg("Selected test nodes: ${targetTestSubset}")
54 common.infoMsg("Selected sample nodes: ${targetLiveSubset}")
55 }
56
Jiri Broulik52a6b832017-06-16 13:05:08 +020057
58 stage("Add new repos on test nodes") {
chnyda625f4b42017-10-11 14:10:31 +020059 salt.enforceState(pepperEnv, targetTestSubset, 'linux.system.repo')
Jiri Broulik52a6b832017-06-16 13:05:08 +020060 }
61
62
63 opencontrail = null
64
65 try {
chnyda625f4b42017-10-11 14:10:31 +020066 opencontrail = salt.cmdRun(pepperEnv, targetTestSubsetProbe, "salt-call grains.item roles | grep opencontrail.compute")
Jiri Broulik52a6b832017-06-16 13:05:08 +020067 print(opencontrail)
68 } catch (Exception er) {
69 common.infoMsg("opencontrail is not used")
70 }
71
72 if(opencontrail != null) {
73 stage('Remove OC component from repos on test nodes') {
Jiri Broulikcbad2f12017-11-23 17:15:36 +010074 def contrail_repo_file1 = ''
75 def contrail_repo_file2 = ''
76 try {
77 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
78 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetTestSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
79 } catch (Exception er) {
80 common.warningMsg(er)
81 }
chnyda625f4b42017-10-11 14:10:31 +020082 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'")
Jiri Broulikcbad2f12017-11-23 17:15:36 +010083 try {
84 salt.cmdRun(pepperEnv, targetTestSubset, "salt-call pkg.refresh_db")
85 } catch (Exception er) {
86 common.warningMsg(er)
87 // remove the malformed repo entry
88 salt.cmdRun(pepperEnv, targetTestSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
89 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.refresh_db', [], null, true)
90 }
Jiri Broulik52a6b832017-06-16 13:05:08 +020091 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020092 }
93
94 stage("List package upgrades") {
chnyda625f4b42017-10-11 14:10:31 +020095 salt.runSaltProcessStep(pepperEnv, targetTestSubset, 'pkg.list_upgrades', [], null, true)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020096 }
97
Jiri Broulik52a6b832017-06-16 13:05:08 +020098 stage('Confirm upgrade on sample nodes') {
99 input message: "Please verify the list of packages that you want to be upgraded. Do you want to continue with upgrade?"
100 }
101
102 stage("Add new repos on sample nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200103 salt.enforceState(pepperEnv, targetLiveSubset, 'linux.system.repo')
Jiri Broulik52a6b832017-06-16 13:05:08 +0200104 }
105
106 if(opencontrail != null) {
107 stage('Remove OC component from repos on sample nodes') {
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100108 def contrail_repo_file1 = ''
109 def contrail_repo_file2 = ''
110 try {
111 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
112 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveSubset, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
113 } catch (Exception er) {
114 common.warningMsg(er)
115 }
chnyda625f4b42017-10-11 14:10:31 +0200116 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'")
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100117 try {
118 salt.cmdRun(pepperEnv, targetLiveSubset, "salt-call pkg.refresh_db")
119 } catch (Exception er) {
120 common.warningMsg(er)
121 // remove the malformed repo entry
122 salt.cmdRun(pepperEnv, targetLiveSubset, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
123 salt.runSaltProcessStep(pepperEnv, targetLiveSubset, 'pkg.refresh_db', [], null, true)
124 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200125 }
126 }
127
Jiri Broulik52a6b832017-06-16 13:05:08 +0200128 args = "apt-get -y -s -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
129
130 stage('Test upgrade on sample') {
131 try {
chnyda625f4b42017-10-11 14:10:31 +0200132 salt.cmdRun(pepperEnv, targetLiveSubset, args)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200133 } catch (Exception er) {
134 print(er)
135 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200136 }
137
Jiri Broulik52a6b832017-06-16 13:05:08 +0200138 stage('Confirm upgrade on sample') {
139 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?"
140 }
141
142 command = "cmd.run"
Jiri Broulikf555b1f2017-06-20 23:04:08 +0200143 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
Jiri Broulik52a6b832017-06-16 13:05:08 +0200144
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200145 stage('Apply package upgrades on sample') {
chnyda625f4b42017-10-11 14:10:31 +0200146 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200147 salt.printSaltCommandResult(out)
148 }
149
Jiri Broulik52a6b832017-06-16 13:05:08 +0200150 openvswitch = null
151
152 try {
chnyda625f4b42017-10-11 14:10:31 +0200153 openvswitch = salt.cmdRun(pepperEnv, targetLiveSubsetProbe, "salt-call grains.item roles | grep neutron.compute")
Jiri Broulik52a6b832017-06-16 13:05:08 +0200154 } catch (Exception er) {
155 common.infoMsg("openvswitch is not used")
156 }
157
158 if(openvswitch != null) {
159 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
160
161 stage('Start ovs on sample nodes') {
chnyda625f4b42017-10-11 14:10:31 +0200162 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik52a6b832017-06-16 13:05:08 +0200163 salt.printSaltCommandResult(out)
164 }
Jiri Broulikf20c7672017-06-19 21:20:52 +0200165 stage("Run salt states on sample nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200166 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'neutron'])
Jiri Broulik52a6b832017-06-16 13:05:08 +0200167 }
168 } else {
169 stage("Run salt states on sample nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200170 salt.enforceState(pepperEnv, targetLiveSubset, ['nova', 'linux.system.repo'])
Jiri Broulik07292b42017-06-22 18:45:49 +0200171 }
172 }
173
174 stage("Run Highstate on sample nodes") {
175 try {
chnyda625f4b42017-10-11 14:10:31 +0200176 salt.enforceHighstate(pepperEnv, targetLiveSubset)
Jiri Broulik07292b42017-06-22 18:45:49 +0200177 } catch (Exception er) {
178 common.errorMsg("Highstate was executed on ${targetLiveSubset} but something failed. Please check it and fix it accordingly.")
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200179 }
180 }
181
Jiri Broulikf20c7672017-06-19 21:20:52 +0200182 stage('Confirm upgrade on all targeted nodes') {
Jiri Broulik52a6b832017-06-16 13:05:08 +0200183 timeout(time: 2, unit: 'HOURS') {
184 input message: "Verify that the upgraded sample nodes are working correctly. If so, do you want to approve live upgrade on ${targetLiveAll} nodes?"
185 }
186 }
187
Jiri Broulik77e7c432017-06-22 17:58:09 +0200188 stage("Add new repos on all targeted nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200189 salt.enforceState(pepperEnv, targetLiveAll, 'linux.system.repo')
Jiri Broulik77e7c432017-06-22 17:58:09 +0200190 }
191
Jiri Broulik52a6b832017-06-16 13:05:08 +0200192 if(opencontrail != null) {
Jiri Broulikf20c7672017-06-19 21:20:52 +0200193 stage('Remove OC component from repos on all targeted nodes') {
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100194 def contrail_repo_file1 = ''
195 def contrail_repo_file2 = ''
196 try {
197 contrail_repo_file1 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\$\\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
198 contrail_repo_file2 = salt.cmdRun(pepperEnv, targetLiveAll, "grep -Eorl \\ oc\\([0-9]*\\ \\) /etc/apt/sources.list*")['return'][0].values()[0].split("\n")[0]
199 } catch (Exception er) {
200 common.warningMsg(er)
201 }
chnyda625f4b42017-10-11 14:10:31 +0200202 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'")
Jiri Broulikcbad2f12017-11-23 17:15:36 +0100203 try {
204 salt.cmdRun(pepperEnv, targetLiveAll, "salt-call pkg.refresh_db")
205 } catch (Exception er) {
206 common.warningMsg(er)
207 // remove the malformed repo entry
208 salt.cmdRun(pepperEnv, targetLiveAll, "rm ${contrail_repo_file1} ${contrail_repo_file2}")
209 salt.runSaltProcessStep(pepperEnv, targetLiveAll, 'pkg.refresh_db', [], null, true)
210 }
Jiri Broulik52a6b832017-06-16 13:05:08 +0200211 }
212 }
213
Jiri Broulikf555b1f2017-06-20 23:04:08 +0200214 args = 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade;'
Jiri Broulik52a6b832017-06-16 13:05:08 +0200215
Jiri Broulikf20c7672017-06-19 21:20:52 +0200216 stage('Apply package upgrades on all targeted nodes') {
chnyda625f4b42017-10-11 14:10:31 +0200217 out = salt.runSaltCommand(pepperEnv, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200218 salt.printSaltCommandResult(out)
219 }
220
Jiri Broulik52a6b832017-06-16 13:05:08 +0200221 if(openvswitch != null) {
222 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
223
Jiri Broulikf20c7672017-06-19 21:20:52 +0200224 stage('Start ovs 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 Broulikf20c7672017-06-19 21:20:52 +0200228 stage("Run salt states on all targeted nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200229 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'neutron'])
Jiri Broulik52a6b832017-06-16 13:05:08 +0200230 }
231 } else {
Jiri Broulikf20c7672017-06-19 21:20:52 +0200232 stage("Run salt states on all targeted nodes") {
chnyda625f4b42017-10-11 14:10:31 +0200233 salt.enforceState(pepperEnv, targetLiveAll, ['nova', 'linux.system.repo'])
Jiri Broulik07292b42017-06-22 18:45:49 +0200234 }
235 }
236
237 stage("Run Highstate on all targeted nodes") {
238 try {
chnyda625f4b42017-10-11 14:10:31 +0200239 salt.enforceHighstate(pepperEnv, targetLiveAll)
Jiri Broulik07292b42017-06-22 18:45:49 +0200240 } catch (Exception er) {
241 common.errorMsg("Highstate was executed ${targetLiveAll} but something failed. Please check it and fix it accordingly.")
Jiri Broulik52a6b832017-06-16 13:05:08 +0200242 }
243 }
244
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200245 } catch (Throwable e) {
246 // If there was an error or exception thrown, the build failed
247 currentBuild.result = "FAILURE"
Jakub Josefd2efd7d2017-08-22 17:49:57 +0200248 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200249 throw e
250 }
251}
Jiri Broulik52a6b832017-06-16 13:05:08 +0200252