blob: a66e43da5cb886501b84c39f1b87ae674f301b16 [file] [log] [blame]
alshabib08d0a1f2017-01-05 15:04:28 -08001def filename = 'manifest-${branch}.xml'
Luca Prete28ca70f2017-05-18 15:21:24 -07002def manifestUrl = 'https://gerrit.opencord.org/manifest'
Luca Pretef1392332017-06-29 10:26:29 +02003def config = null;
alshabib4e1c96e2016-09-28 16:26:24 -07004
alshabib41f74fd2017-01-07 09:48:00 -08005node ('master') {
Luca Prete28ca70f2017-05-18 15:21:24 -07006 checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: "${manifestUrl}", quiet: true]
alshabib41f74fd2017-01-07 09:48:00 -08007
Luca Prete28ca70f2017-05-18 15:21:24 -07008 stage ("Generate and Copy Manifest file") {
9 sh returnStdout: true, script: 'repo manifest -r -o ' + filename
10 sh returnStdout: true, script: 'cp ' + filename + ' ' + env.JENKINS_HOME + '/tmp'
11 }
Luca Pretef1392332017-06-29 10:26:29 +020012
13 stage ("Parse deployment configuartion file") {
14 sh returnStdout: true, script: 'rm -rf ${configRepoBaseDir}'
15 sh returnStdout: true, script: 'git clone ${configRepoUrl}'
16 config = readYaml file: "${configRepoBaseDir}${configRepoFile}"
17 }
alshabib41f74fd2017-01-07 09:48:00 -080018}
19
Luca Pretef1392332017-06-29 10:26:29 +020020node ("${config.dev_node.name}") {
Luca Prete28ca70f2017-05-18 15:21:24 -070021 timeout (time: 240) {
Luca Pretef1392332017-06-29 10:26:29 +020022 stage ('Checkout cord repo') {
23 checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: "${manifestUrl}", quiet: true]
24 }
alshabib19302662017-01-05 14:27:41 -080025
Luca Pretef1392332017-06-29 10:26:29 +020026 dir('build') {
alshabib19302662017-01-05 14:27:41 -080027 try {
Luca Prete28ca70f2017-05-18 15:21:24 -070028 stage ("Re-deploy head node and Build Vagrant box") {
29 parallel(
30 maasOps: {
Luca Pretef1392332017-06-29 10:26:29 +020031 sh "maas login maas http://${config.maas.ip}/MAAS/api/2.0 ${config.maas.api_key}"
32 sh "maas maas machine release ${config.maas.head_system_id}"
alshabib19302662017-01-05 14:27:41 -080033
Luca Prete28ca70f2017-05-18 15:21:24 -070034 timeout(time: 15) {
35 waitUntil {
36 try {
Luca Pretef1392332017-06-29 10:26:29 +020037 sh "maas maas machine read ${config.maas.head_system_id} | grep Ready"
Luca Prete28ca70f2017-05-18 15:21:24 -070038 return true
39 } catch (exception) {
40 return false
41 }
alshabib19302662017-01-05 14:27:41 -080042 }
alshabibef069942016-09-09 17:08:36 -070043 }
alshabib4e1c96e2016-09-28 16:26:24 -070044
Luca Prete28ca70f2017-05-18 15:21:24 -070045 sh 'maas maas machines allocate'
Luca Pretef1392332017-06-29 10:26:29 +020046 sh "maas maas machine deploy ${config.maas.head_system_id}"
alshabib4e1c96e2016-09-28 16:26:24 -070047
Luca Prete28ca70f2017-05-18 15:21:24 -070048 timeout(time: 30) {
49 waitUntil {
50 try {
Luca Pretef1392332017-06-29 10:26:29 +020051 sh "maas maas machine read ${config.maas.head_system_id} | grep Deployed"
Luca Prete28ca70f2017-05-18 15:21:24 -070052 return true
53 } catch (exception) {
54 return false
55 }
alshabib19302662017-01-05 14:27:41 -080056 }
alshabibef069942016-09-09 17:08:36 -070057 }
alshabib4e1c96e2016-09-28 16:26:24 -070058
Luca Prete28ca70f2017-05-18 15:21:24 -070059 }, vagrantOps: {
60 sh 'vagrant up corddev'
61 }, failFast : true
62 )
63 }
alshabib4e1c96e2016-09-28 16:26:24 -070064
Luca Prete28ca70f2017-05-18 15:21:24 -070065 stage ("Fetch CORD packages") {
Luca Pretef1392332017-06-29 10:26:29 +020066 sh "vagrant ssh -c \"cd /cord/build; ./gradlew fetch\" corddev"
Luca Prete28ca70f2017-05-18 15:21:24 -070067 }
alshabib4e1c96e2016-09-28 16:26:24 -070068
Luca Prete28ca70f2017-05-18 15:21:24 -070069 stage ("Build CORD Images") {
Luca Pretef1392332017-06-29 10:26:29 +020070 sh "vagrant ssh -c \"cd /cord/build; ./gradlew buildImages\" corddev"
Luca Prete28ca70f2017-05-18 15:21:24 -070071 }
alshabib61509fb2016-09-09 02:43:20 -070072
Luca Prete28ca70f2017-05-18 15:21:24 -070073 stage ("Downloading CORD POD configuration") {
Luca Pretef1392332017-06-29 10:26:29 +020074 sh "vagrant ssh -c \"cd /cord/build/config; git clone ${config.pod_config.repo_url}\" corddev"
Luca Prete28ca70f2017-05-18 15:21:24 -070075 }
Jonathan Hart1719e9a2017-03-13 21:53:47 -070076
Luca Prete28ca70f2017-05-18 15:21:24 -070077 stage ("Publish to headnode") {
Luca Pretef1392332017-06-29 10:26:29 +020078 sh "vagrant ssh -c \"cd /cord/build; ./gradlew -PtargetReg=${config.head.ip}:5000 -PdeployConfig=config/pod-configs/${config.pod_config.file_name} publish\" corddev"
Luca Prete28ca70f2017-05-18 15:21:24 -070079 }
alshabib61509fb2016-09-09 02:43:20 -070080
Luca Prete28ca70f2017-05-18 15:21:24 -070081 stage ("Deploy") {
Luca Pretef1392332017-06-29 10:26:29 +020082 sh "vagrant ssh -c \"cd /cord/build; ./gradlew -PtargetReg=${config.head.ip}:5000 -PdeployConfig=config/pod-configs/${config.pod_config.file_name} deploy\" corddev"
Luca Prete28ca70f2017-05-18 15:21:24 -070083 }
alshabib4e1c96e2016-09-28 16:26:24 -070084
Luca Prete9ab62272017-05-24 09:56:06 -070085 stage ("Power cycle compute nodes") {
Luca Pretef1392332017-06-29 10:26:29 +020086 for(int i=0; i < config.compute_nodes.size(); i++) {
87 sh "ipmitool -U ${config.compute_nodes[i].ipmi.user} -P ${config.compute_nodes[i].ipmi.pass} -H ${config.compute_nodes[i].ipmi.ip} power cycle"
88 }
Luca Prete28ca70f2017-05-18 15:21:24 -070089 }
alshabib7f3be8d2016-09-27 18:04:56 -070090
Luca Prete560f8192017-06-30 10:59:26 +020091 try {
92 def provCompleted = 0
93 for(int i=0; i < config.fabric_switches.size(); i++) {
94 def count = runCmd("${config.head.ip}",
95 "${config.head.user}",
96 "${config.head.pass}",
97 "cord prov list '|' grep -i ${config.fabric_switches[i].ip} '|' grep -i complete '|' wc -l").trim()
98 provCompleted = provCompleted + count.toInteger()
99 }
100 return provCompleted == config.fabric_switches.size()
101 } catch (exception) {
102 return false
103 }
Luca Prete28ca70f2017-05-18 15:21:24 -0700104 stage ("Wait for compute nodes to get deployed") {
Luca Pretef1392332017-06-29 10:26:29 +0200105 sh "ssh-keygen -f /home/${config.dev_node.user}/.ssh/known_hosts -R ${config.head.ip}"
106 def cordApiKey = runCmd("${config.head.ip}",
107 "${config.head.user}",
108 "${config.head.pass}",
109 "sudo maas-region-admin apikey --username ${config.head.user}")
110 runCmd("${config.head.ip}",
111 "${config.head.user}",
112 "${config.head.pass}",
113 "maas login pod-maas http://${config.head.ip}/MAAS/api/1.0 ${cordApiKey}")
Luca Prete28ca70f2017-05-18 15:21:24 -0700114 timeout(time: 45) {
115 waitUntil {
116 try {
Luca Pretef1392332017-06-29 10:26:29 +0200117 num = runCmd("${config.head.ip}",
118 "${config.head.user}",
119 "${config.head.pass}",
120 "maas pod-maas nodes list | grep -i deployed | wc -l").trim()
Luca Prete28ca70f2017-05-18 15:21:24 -0700121 return num == '2'
122 } catch (exception) {
123 return false
124 }
alshabib19302662017-01-05 14:27:41 -0800125 }
alshabib4e1c96e2016-09-28 16:26:24 -0700126 }
127 }
alshabib4e1c96e2016-09-28 16:26:24 -0700128
Luca Prete28ca70f2017-05-18 15:21:24 -0700129 stage ("Wait for computes nodes to be provisioned") {
Luca Pretef1392332017-06-29 10:26:29 +0200130 ip = runCmd("${config.head.ip}",
131 "${config.head.user}",
132 "${config.head.pass}",
133 "docker inspect --format '{{.NetworkSettings.Networks.maas_default.IPAddress}}' provisioner").trim()
Luca Prete28ca70f2017-05-18 15:21:24 -0700134 timeout(time:45) {
135 waitUntil {
136 try {
Luca Pretef1392332017-06-29 10:26:29 +0200137 out = runCmd("${config.head.ip}",
138 "${config.head.user}",
139 "${config.head.pass}",
140 "curl -sS http://$ip:4243/provision/ | jq -c '.[] | select(.status | contains(2))'").trim()
Luca Prete28ca70f2017-05-18 15:21:24 -0700141 return out != ""
142 } catch (exception) {
143 return false
144 }
alshabib19302662017-01-05 14:27:41 -0800145 }
alshabib7f3be8d2016-09-27 18:04:56 -0700146 }
147 }
alshabib19302662017-01-05 14:27:41 -0800148
Luca Pretef1392332017-06-29 10:26:29 +0200149 if (config.fabric_switches != null) {
Luca Prete9ab62272017-05-24 09:56:06 -0700150 stage("Reserve IPs for fabric switches and restart maas-dhcp service") {
Luca Pretef1392332017-06-29 10:26:29 +0200151 for(int i=0; i < config.fabric_switches.size(); i++) {
Luca Prete9ab62272017-05-24 09:56:06 -0700152 def append = "";
153 if (i!=0) {
154 append = "-a";
155 }
Luca Pretef1392332017-06-29 10:26:29 +0200156 def str = createMACIPbindingStr(i+1,
157 "${config.fabric_switches[i].mac}",
158 "${config.fabric_switches[i].ip}")
159 runCmd("${config.head.ip}",
160 "${config.head.user}",
161 "${config.head.pass}",
162 "echo -e $str '|' sudo tee $append /etc/dhcp/dhcpd.reservations > /dev/null")
Luca Prete9ab62272017-05-24 09:56:06 -0700163 }
Luca Pretef1392332017-06-29 10:26:29 +0200164 runCmd("${config.head.ip}",
165 "${config.head.user}",
166 "${config.head.pass}",
167 "sudo restart maas-dhcpd")
168
169 runCmd("${config.head.ip}",
170 "${config.head.user}",
171 "${config.head.pass}",
172 "cord harvest go")
Luca Prete9ab62272017-05-24 09:56:06 -0700173 }
174
175 stage ("Wait for fabric switches to get deployed") {
Luca Pretef1392332017-06-29 10:26:29 +0200176 for(int i=0; i < config.fabric_switches.size(); i++) {
177 runFabricCmd("${config.head.ip}",
178 "${config.head.user}",
179 "${config.head.pass}",
180 "${config.fabric_switches[i].ip}",
181 "${config.fabric_switches[i].user}",
182 "${config.fabric_switches[i].pass}",
183 "sudo onl-onie-boot-mode install")
184
185 runFabricCmd("${config.head.ip}",
186 "${config.head.user}",
187 "${config.head.pass}",
188 "${config.fabric_switches[i].ip}",
189 "${config.fabric_switches[i].user}",
190 "${config.fabric_switches[i].pass}",
191 "sudo reboot")
Luca Prete9ab62272017-05-24 09:56:06 -0700192 }
193 timeout(time: 45) {
194 waitUntil {
195 try {
Luca Pretef1392332017-06-29 10:26:29 +0200196 def harvestCompleted = runCmd("${config.head.ip}",
197 "${config.head.user}",
198 "${config.head.pass}",
199 "cord harvest list '|' grep -i fabric '|' wc -l").trim()
200 return harvestCompleted == config.fabric_switches.size().toString()
Luca Prete9ab62272017-05-24 09:56:06 -0700201 } catch (exception) {
202 return false
203 }
204 }
205 }
206 }
207
208 stage ("Wait for fabric switches to be provisioned") {
209 timeout(time:45) {
210 waitUntil {
211 try {
212 def provCompleted = 0
Luca Pretef1392332017-06-29 10:26:29 +0200213 for(int i=0; i < config.fabric_switches.size(); i++) {
214 def count = runCmd("${config.head.ip}",
215 "${config.head.user}",
216 "${config.head.pass}",
217 "cord prov list '|' grep -i ${config.fabric_switches[i].ip} '|' grep -i complete '|' wc -l").trim()
Luca Prete9ab62272017-05-24 09:56:06 -0700218 provCompleted = provCompleted + count.toInteger()
Luca Prete9ab62272017-05-24 09:56:06 -0700219 }
Luca Pretef1392332017-06-29 10:26:29 +0200220 return provCompleted == config.fabric_switches.size()
Luca Prete9ab62272017-05-24 09:56:06 -0700221 } catch (exception) {
222 return false
223 }
224 }
225 }
226 }
227 }
228
Luca Pretef1392332017-06-29 10:26:29 +0200229 if (config.make_release == true) {
230 stage ("Trigger Build") {
231 url = 'https://jenkins.opencord.org/job/release-build/job/' + params.branch + '/build'
232 httpRequest authentication: 'auto-release', httpMode: 'POST', url: url, validResponseCodes: '201'
233 }
Luca Prete28ca70f2017-05-18 15:21:24 -0700234 }
alshabib19302662017-01-05 14:27:41 -0800235
236 currentBuild.result = 'SUCCESS'
237 } catch (err) {
238 currentBuild.result = 'FAILURE'
Jonathan Hart1719e9a2017-03-13 21:53:47 -0700239 step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${notificationEmail}", sendToIndividuals: false])
alshabib19302662017-01-05 14:27:41 -0800240 } finally {
241 sh 'vagrant destroy -f corddev'
Jonathan Hart1719e9a2017-03-13 21:53:47 -0700242 sh 'rm -rf config/pod-configs'
alshabib7f3be8d2016-09-27 18:04:56 -0700243 }
alshabib19302662017-01-05 14:27:41 -0800244 echo "RESULT: ${currentBuild.result}"
245 }
alshabib19302662017-01-05 14:27:41 -0800246 }
alshabib152823c2016-09-07 23:49:12 -0700247}
Luca Prete28ca70f2017-05-18 15:21:24 -0700248
249/**
Luca Prete28ca70f2017-05-18 15:21:24 -0700250 * Returns a string used to bind IPs and MAC addresses, substituting the values
251 * given.
252 *
Luca Prete9ab62272017-05-24 09:56:06 -0700253 * @param counter the counter used to generate the host name
254 * @param mac the MAC address to substitute
255 * @param ip the IP address to substitute
Luca Prete28ca70f2017-05-18 15:21:24 -0700256 */
Luca Prete9ab62272017-05-24 09:56:06 -0700257def createMACIPbindingStr(counter, mac, ip) {
258 return """\\'host fabric${counter} {'\n'hardware ethernet ${mac}';''\n'fixed-address ${ip}';''\n'}\\'"""
Luca Prete28ca70f2017-05-18 15:21:24 -0700259}
260
261/**
Luca Pretef1392332017-06-29 10:26:29 +0200262 * Runs a command on a remote host using sshpass.
Luca Prete28ca70f2017-05-18 15:21:24 -0700263 *
Luca Pretef1392332017-06-29 10:26:29 +0200264 * @param ip the node IP address
265 * @param user the node user name
266 * @param pass the node password
267 * @param command the command to run
Luca Prete9ab62272017-05-24 09:56:06 -0700268 * @return the output of the command
Luca Prete28ca70f2017-05-18 15:21:24 -0700269 */
Luca Pretef1392332017-06-29 10:26:29 +0200270def runCmd(ip, user, pass, command) {
271 return sh(returnStdout: true, script: "sshpass -p ${pass} ssh -oStrictHostKeyChecking=no -l ${user} ${ip} ${command}")
Luca Prete28ca70f2017-05-18 15:21:24 -0700272}
Luca Prete9ab62272017-05-24 09:56:06 -0700273
274/**
275 * Runs a command on a fabric switch.
276 *
Luca Pretef1392332017-06-29 10:26:29 +0200277 * @param headIp the head node IP address
278 * @param headUser the head node user name
279 * @param headPass the head node password
Luca Prete9ab62272017-05-24 09:56:06 -0700280 * @param ip the mgmt IP of the fabric switch, reachable from the head node
Luca Pretef1392332017-06-29 10:26:29 +0200281 * @param user the mgmt user name of the fabric switch
282 * @param pass the mgmt password of the fabric switch
283 * @param command the command to run on the fabric switch
Luca Prete9ab62272017-05-24 09:56:06 -0700284 * @return the output of the command
285 */
Luca Prete560f8192017-06-30 10:59:26 +0200286def runFabricCmd(headIp, headUser, headPass, ip, user, pass, command) {
Luca Pretef1392332017-06-29 10:26:29 +0200287 return runCmd("${haedIp}",
288 "${headUser}",
289 "${headPass}",
290 "sshpass -p ${pass} ssh -oStrictHostKeyChecking=no -l ${user} ${ip} ${command}")
Luca Prete9ab62272017-05-24 09:56:06 -0700291}