blob: 33e082543b888a0bdec198c318a05e849b280e8e [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()
15
16def saltMaster
17def targetAll = ['expression': TARGET_SERVERS, 'type': 'compound']
18def 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
31 stage('Connect to Salt master') {
32 saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
33 }
34
35 stage('List target servers') {
36 minions = salt.getMinions(saltMaster, targetAll)
37
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") {
59 salt.enforceState(saltMaster, targetTestSubset, 'linux.system.repo')
60 }
61
62
63 opencontrail = null
64
65 try {
66 opencontrail = salt.cmdRun(saltMaster, targetTestSubsetProbe, "salt-call grains.item roles | grep opencontrail.compute")
67 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') {
74 salt.cmdRun(saltMaster, targetTestSubset, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g'")
75 salt.runSaltProcessStep(saltMaster, targetTestSubset, 'pkg.refresh_db', [], null, true)
76 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020077 }
78
79 stage("List package upgrades") {
80 salt.runSaltProcessStep(saltMaster, targetTestSubset, 'pkg.list_upgrades', [], null, true)
81 }
82
Jiri Broulik52a6b832017-06-16 13:05:08 +020083 stage('Confirm upgrade on sample nodes') {
84 input message: "Please verify the list of packages that you want to be upgraded. Do you want to continue with upgrade?"
85 }
86
87 stage("Add new repos on sample nodes") {
88 salt.enforceState(saltMaster, targetLiveSubset, 'linux.system.repo')
89 }
90
91 if(opencontrail != null) {
92 stage('Remove OC component from repos on sample nodes') {
93 salt.cmdRun(saltMaster, targetLiveSubset, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g'")
94 salt.runSaltProcessStep(saltMaster, targetLiveSubset, 'pkg.refresh_db', [], null, true)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +020095 }
96 }
97
Jiri Broulik52a6b832017-06-16 13:05:08 +020098 args = "apt-get -y -s -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
99
100 stage('Test upgrade on sample') {
101 try {
102 salt.cmdRun(saltMaster, targetLiveSubset, args)
103 } catch (Exception er) {
104 print(er)
105 }
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200106 }
107
Jiri Broulik52a6b832017-06-16 13:05:08 +0200108 stage('Confirm upgrade on sample') {
109 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?"
110 }
111
112 command = "cmd.run"
113 args = "apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
114
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200115 stage('Apply package upgrades on sample') {
Jiri Broulik52a6b832017-06-16 13:05:08 +0200116 out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200117 salt.printSaltCommandResult(out)
118 }
119
Jiri Broulik52a6b832017-06-16 13:05:08 +0200120 openvswitch = null
121
122 try {
123 openvswitch = salt.cmdRun(saltMaster, targetLiveSubsetProbe, "salt-call grains.item roles | grep neutron.compute")
124 } catch (Exception er) {
125 common.infoMsg("openvswitch is not used")
126 }
127
128 if(openvswitch != null) {
129 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
130
131 stage('Start ovs on sample nodes') {
132 out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs)
133 salt.printSaltCommandResult(out)
134 }
135 stage("Run salt states on sample nodes and reboot them") {
136 salt.enforceState(saltMaster, targetLiveSubset, ['nova', 'neutron'])
137 try {
138 salt.runSaltProcessStep(saltMaster, targetLiveSubset, 'system.reboot', null, null, true, 5)
139 } catch (Exception er) {
140 common.infoMsg("The following nodes did not return anything because they were rebooted: ${targetLiveSubset}")
141 }
142 }
143 } else {
144 stage("Run salt states on sample nodes") {
145 salt.enforceState(saltMaster, targetLiveSubset, ['nova'])
146 salt.enforceState(saltMaster, targetLiveSubset, 'linux.system.repo')
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200147 }
148 }
149
Jiri Broulik52a6b832017-06-16 13:05:08 +0200150 stage('Confirm upgrade on all nodes') {
151 timeout(time: 2, unit: 'HOURS') {
152 input message: "Verify that the upgraded sample nodes are working correctly. If so, do you want to approve live upgrade on ${targetLiveAll} nodes?"
153 }
154 }
155
156 if(opencontrail != null) {
157 stage('Remove OC component from repos on sample nodes') {
158 salt.cmdRun(saltMaster, targetLiveAll, "find /etc/apt/sources.list* -type f -print0 | xargs -0 sed -i -r -e 's/ oc([0-9]*) / /g'")
159 salt.runSaltProcessStep(saltMaster, targetLiveAll, 'pkg.refresh_db', [], null, true)
160 }
161 }
162
163 args = "apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade"
164
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200165 stage('Apply package upgrades on all nodes') {
Jiri Broulik52a6b832017-06-16 13:05:08 +0200166 out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200167 salt.printSaltCommandResult(out)
168 }
169
Jiri Broulik52a6b832017-06-16 13:05:08 +0200170 if(openvswitch != null) {
171 args = "sudo /usr/share/openvswitch/scripts/ovs-ctl start"
172
173 stage('Start ovs on sample nodes') {
174 out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs)
175 salt.printSaltCommandResult(out)
176 }
177 stage("Run salt states on sample nodes and reboot them") {
178 salt.enforceState(saltMaster, targetLiveAll, ['nova', 'neutron'])
179 try {
180 salt.runSaltProcessStep(saltMaster, targetLiveAll, 'system.reboot', null, null, true, 5)
181 } catch (Exception er) {
182 common.infoMsg("The following nodes did not return anything because they were rebooted: ${targetLiveAll}")
183 }
184 }
185 } else {
186 stage("Run salt states on sample nodes") {
187 salt.enforceState(saltMaster, targetLiveAll, ['nova'])
188 salt.enforceState(saltMaster, targetLiveAll, 'linux.system.repo')
189 }
190 }
191
Jiri Broulik9b73d6c2017-06-02 12:27:05 +0200192 } catch (Throwable e) {
193 // If there was an error or exception thrown, the build failed
194 currentBuild.result = "FAILURE"
195 throw e
196 }
197}
Jiri Broulik52a6b832017-06-16 13:05:08 +0200198
199