| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 1 | /** | 
 | 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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 8 |  *   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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 10 |  * | 
 | 11 | **/ | 
 | 12 |  | 
 | 13 | def common = new com.mirantis.mk.Common() | 
 | 14 | def salt = new com.mirantis.mk.Salt() | 
 | 15 |  | 
 | 16 | def saltMaster | 
 | 17 | def targetAll = ['expression': TARGET_SERVERS, 'type': 'compound'] | 
 | 18 | def targetTestSubset | 
 | 19 | def targetLiveSubset | 
 | 20 | def targetLiveAll | 
 | 21 | def minions | 
 | 22 | def result | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 23 | def args | 
| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 24 | def command | 
 | 25 | def commandKwargs | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 26 | def probe = 1 | 
| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 27 |  | 
 | 28 | node() { | 
 | 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 Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 48 |             targetTestSubsetProbe = minions.subList(0, probe).join(' or ') | 
 | 49 |             targetLiveSubsetProbe = minions.subList(0, probe).join(' or ') | 
| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 50 |  | 
 | 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 Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 57 |  | 
 | 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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 77 |         } | 
 | 78 |  | 
 | 79 |         stage("List package upgrades") { | 
 | 80 |             salt.runSaltProcessStep(saltMaster, targetTestSubset, 'pkg.list_upgrades', [], null, true) | 
 | 81 |         } | 
 | 82 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 83 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 95 |             } | 
 | 96 |         } | 
 | 97 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 98 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 106 |         } | 
 | 107 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 108 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 115 |         stage('Apply package upgrades on sample') { | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 116 |             out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveSubset, 'type': 'compound'], command, null, args, commandKwargs) | 
| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 117 |             salt.printSaltCommandResult(out) | 
 | 118 |         } | 
 | 119 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 120 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 147 |             } | 
 | 148 |         } | 
 | 149 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 150 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 165 |         stage('Apply package upgrades on all nodes') { | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 166 |             out = salt.runSaltCommand(saltMaster, 'local', ['expression': targetLiveAll, 'type': 'compound'], command, null, args, commandKwargs) | 
| Jiri Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 167 |             salt.printSaltCommandResult(out) | 
 | 168 |         } | 
 | 169 |  | 
| Jiri Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 170 |         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 Broulik | 9b73d6c | 2017-06-02 12:27:05 +0200 | [diff] [blame] | 192 |     } 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 Broulik | 52a6b83 | 2017-06-16 13:05:08 +0200 | [diff] [blame] | 198 |  | 
 | 199 |  |