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