blob: 8c0b56eaaa536c62886aef0e5554e56d336a53b9 [file] [log] [blame]
Jakub Josef79ecec32017-02-17 14:36:28 +01001package com.mirantis.mk
2
3/**
4 *
5 * Common functions
6 *
7 */
8
9/**
10 * Generate current timestamp
11 *
12 * @param format Defaults to yyyyMMddHHmmss
13 */
14def getDatetime(format="yyyyMMddHHmmss") {
15 def now = new Date();
16 return now.format(format, TimeZone.getTimeZone('UTC'));
17}
18
19/**
Jakub Josef79ecec32017-02-17 14:36:28 +010020 * Return workspace.
21 * Currently implemented by calling pwd so it won't return relevant result in
22 * dir context
23 */
24def getWorkspace() {
25 def workspace = sh script: 'pwd', returnStdout: true
26 workspace = workspace.trim()
27 return workspace
28}
29
30/**
31 * Get credentials from store
32 *
33 * @param id Credentials name
34 */
Jakub Josef3d9d9ab2017-03-14 15:09:03 +010035def getCredentials(id, cred_type = "username_password") {
36 def credClass;
37 if(cred_type == "username_password"){
38 credClass = com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class
39 }else if(cred_type == "key"){
40 credClass = com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.class
41 }
Jakub Josef79ecec32017-02-17 14:36:28 +010042 def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
Jakub Josef3d9d9ab2017-03-14 15:09:03 +010043 credClass,
Jakub Josef79ecec32017-02-17 14:36:28 +010044 jenkins.model.Jenkins.instance
45 )
46
47 for (Iterator<String> credsIter = creds.iterator(); credsIter.hasNext();) {
48 c = credsIter.next();
49 if ( c.id == id ) {
50 return c;
51 }
52 }
53
54 throw new Exception("Could not find credentials for ID ${id}")
55}
56
57/**
58 * Abort build, wait for some time and ensure we will terminate
59 */
60def abortBuild() {
61 currentBuild.build().doStop()
62 sleep(180)
63 // just to be sure we will terminate
64 throw new InterruptedException()
65}
66
67/**
68 * Print informational message
69 *
70 * @param msg
71 * @param color Colorful output or not
72 */
73def infoMsg(msg, color = true) {
74 printMsg(msg, "cyan")
75}
76
77/**
78 * Print error message
79 *
80 * @param msg
81 * @param color Colorful output or not
82 */
83def errorMsg(msg, color = true) {
84 printMsg(msg, "red")
85}
86
87/**
88 * Print success message
89 *
90 * @param msg
91 * @param color Colorful output or not
92 */
93def successMsg(msg, color = true) {
94 printMsg(msg, "green")
95}
96
97/**
98 * Print warning message
99 *
100 * @param msg
101 * @param color Colorful output or not
102 */
103def warningMsg(msg, color = true) {
104 printMsg(msg, "blue")
105}
106
107/**
108 * Print message
109 *
110 * @param msg Message to be printed
111 * @param level Level of message (default INFO)
112 * @param color Color to use for output or false (default)
113 */
114def printMsg(msg, color = false) {
115 colors = [
116 'red' : '\u001B[31m',
117 'black' : '\u001B[30m',
118 'green' : '\u001B[32m',
119 'yellow': '\u001B[33m',
120 'blue' : '\u001B[34m',
121 'purple': '\u001B[35m',
122 'cyan' : '\u001B[36m',
123 'white' : '\u001B[37m',
124 'reset' : '\u001B[0m'
125 ]
126 if (color != false) {
127 wrap([$class: 'AnsiColorBuildWrapper']) {
128 print "${colors[color]}${msg}${colors.reset}"
129 }
130 } else {
131 print "[${level}] ${msg}"
132 }
133}
134
135/**
136 * Traverse directory structure and return list of files
137 *
138 * @param path Path to search
139 * @param type Type of files to search (groovy.io.FileType.FILES)
140 */
141@NonCPS
142def getFiles(path, type=groovy.io.FileType.FILES) {
143 files = []
144 new File(path).eachFile(type) {
145 files[] = it
146 }
147 return files
148}
149
150/**
151 * Helper method to convert map into form of list of [key,value] to avoid
152 * unserializable exceptions
153 *
154 * @param m Map
155 */
156@NonCPS
157def entries(m) {
158 m.collect {k, v -> [k, v]}
159}
160
161/**
162 * Opposite of build-in parallel, run map of steps in serial
163 *
164 * @param steps Map of String<name>: CPSClosure2<step>
165 */
166def serial(steps) {
167 stepsArray = entries(steps)
168 for (i=0; i < stepsArray.size; i++) {
169 s = stepsArray[i]
170 dummySteps = ["${s[0]}": s[1]]
171 parallel dummySteps
172 }
173}
174
175/**
176 * Get password credentials from store
177 *
178 * @param id Credentials name
179 */
180def getPasswordCredentials(id) {
181 def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
182 com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
183 jenkins.model.Jenkins.instance
184 )
185
186 for (Iterator<String> credsIter = creds.iterator(); credsIter.hasNext();) {
187 c = credsIter.next();
188 if ( c.id == id ) {
189 return c;
190 }
191 }
192
193 throw new Exception("Could not find credentials for ID ${id}")
194}
195
196/**
197 * Get SSH credentials from store
198 *
199 * @param id Credentials name
200 */
201def getSshCredentials(id) {
202 def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
203 com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
204 jenkins.model.Jenkins.instance
205 )
206
207 for (Iterator<String> credsIter = creds.iterator(); credsIter.hasNext();) {
208 c = credsIter.next();
209 if ( c.id == id ) {
210 return c;
211 }
212 }
213
214 throw new Exception("Could not find credentials for ID ${id}")
215}
Jakub Josef79ecec32017-02-17 14:36:28 +0100216
217/**
218 * Tests Jenkins instance for existence of plugin with given name
219 * @param pluginName plugin short name to test
220 * @return boolean result
221 */
222@NonCPS
223def jenkinsHasPlugin(pluginName){
224 return Jenkins.instance.pluginManager.plugins.collect{p -> p.shortName}.contains(pluginName)
225}
226
227@NonCPS
228def _needNotification(notificatedTypes, buildStatus, jobName) {
229 if(notificatedTypes && notificatedTypes.contains("onchange")){
230 if(jobName){
231 def job = Jenkins.instance.getItem(jobName)
232 def numbuilds = job.builds.size()
233 if (numbuilds > 0){
234 //actual build is first for some reasons, so last finished build is second
235 def lastBuild = job.builds[1]
236 if(lastBuild){
237 if(lastBuild.result.toString().toLowerCase().equals(buildStatus)){
238 println("Build status didn't changed since last build, not sending notifications")
239 return false;
240 }
241 }
242 }
243 }
244 }else if(!notificatedTypes.contains(buildStatus)){
245 return false;
246 }
247 return true;
248}
249
250/**
251 * Send notification to all enabled notifications services
252 * @param buildStatus message type (success, warning, error), null means SUCCESSFUL
253 * @param msgText message text
254 * @param enabledNotifications list of enabled notification types, types: slack, hipchat, email, default empty
255 * @param notificatedTypes types of notifications will be sent, default onchange - notificate if current build result not equal last result;
256 * otherwise use - ["success","unstable","failed"]
257 * @param jobName optional job name param, if empty env.JOB_NAME will be used
258 * @param buildNumber build number param, if empty env.JOB_NAME will be used
259 * @param buildUrl build url param, if empty env.JOB_NAME will be used
260 * @param mailFrom mail FROM param, if empty "jenkins" will be used, it's mandatory for sending email notifications
261 * @param mailTo mail TO param, it's mandatory for sending email notifications
262 */
263def sendNotification(buildStatus, msgText="", enabledNotifications = [], notificatedTypes=["onchange"], jobName=null, buildNumber=null, buildUrl=null, mailFrom="jenkins", mailTo=null){
264 // Default values
265 def colorName = 'blue'
266 def colorCode = '#0000FF'
267 def buildStatusParam = buildStatus != null && buildStatus != "" ? buildStatus : "SUCCESS"
268 def jobNameParam = jobName != null && jobName != "" ? jobName : env.JOB_NAME
269 def buildNumberParam = buildNumber != null && buildNumber != "" ? buildNumber : env.BUILD_NUMBER
270 def buildUrlParam = buildUrl != null && buildUrl != "" ? buildUrl : env.BUILD_URL
271 def subject = "${buildStatusParam}: Job '${jobNameParam} [${buildNumberParam}]'"
272 def summary = "${subject} (${buildUrlParam})"
273
274 if(msgText != null && msgText != ""){
275 summary+="\n${msgText}"
276 }
277 if(buildStatusParam.toLowerCase().equals("success")){
278 colorCode = "#00FF00"
279 colorName = "green"
280 }else if(buildStatusParam.toLowerCase().equals("unstable")){
281 colorCode = "#FFFF00"
282 colorName = "yellow"
283 }else if(buildStatusParam.toLowerCase().equals("failure")){
284 colorCode = "#FF0000"
285 colorName = "red"
286 }
287 if(_needNotification(notificatedTypes, buildStatusParam.toLowerCase(), jobNameParam)){
288 if(enabledNotifications.contains("slack") && jenkinsHasPlugin("slack")){
289 try{
290 slackSend color: colorCode, message: summary
291 }catch(Exception e){
292 println("Calling slack plugin failed")
293 e.printStackTrace()
294 }
295 }
296 if(enabledNotifications.contains("hipchat") && jenkinsHasPlugin("hipchat")){
297 try{
298 hipchatSend color: colorName.toUpperCase(), message: summary
299 }catch(Exception e){
300 println("Calling hipchat plugin failed")
301 e.printStackTrace()
302 }
303 }
304 if(enabledNotifications.contains("email") && mailTo != null && mailTo != "" && mailFrom != null && mailFrom != ""){
305 try{
306 mail body: summary, from: mailFrom, subject: subject, to: mailTo
307 }catch(Exception e){
308 println("Sending mail plugin failed")
309 e.printStackTrace()
310 }
311 }
312 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100313}