blob: cb0ca5de4f8a344af048f9bb9b4090e26d9d4ca9 [file] [log] [blame]
Ruslan Kamaldinov90d4e672016-11-11 18:31:00 +03001package com.mirantis.mcp
2
Jakub Josef9973a7f2017-06-20 13:43:48 +02003import com.cloudbees.groovy.cps.NonCPS
Sergey Reshetnyak70b1fe62017-01-31 22:27:06 +03004@Grab(group='org.yaml', module='snakeyaml', version='1.17')
5import org.yaml.snakeyaml.Yaml
6
Ruslan Kamaldinov90d4e672016-11-11 18:31:00 +03007/**
8 * https://issues.jenkins-ci.org/browse/JENKINS-26481
9 * fix groovy List.collect()
10 **/
11@NonCPS
12def constructString(ArrayList options, String keyOption, String separator = " ") {
13 return options.collect { keyOption + it }.join(separator).replaceAll("\n", "")
14}
15
16/**
17 * Generate current timestamp
18 *
19 * @param format Defaults to yyyyMMddHHmmss
20 */
21def getDatetime(format = "yyyyMMddHHmmss") {
22 def now = new Date();
23 return now.format(format, TimeZone.getTimeZone('UTC'));
Denis Egorenko8c606552016-12-07 14:22:50 +040024}
25
26/**
27 * Run tox with or without specified environment
28 * @param env String, name of environment
29 */
30def runTox(String env = null) {
31 if (env) {
32 sh "tox -v -e ${env}"
33 } else {
34 sh "tox -v"
35 }
36}
Sergey Kulanove897d8f2017-01-23 16:44:03 +020037
38/**
Sergey Reshetnyak70b1fe62017-01-31 22:27:06 +030039 * Convert YAML document to Map object
40 * @param data YAML string
41 */
42@NonCPS
43def loadYAML(String data) {
44 def yaml = new Yaml()
45 return yaml.load(data)
46}
47
48/**
49 * Convert Map object to YAML string
50 * @param map Map object
51 */
52@NonCPS
53def dumpYAML(Map map) {
54 def yaml = new Yaml()
55 return yaml.dump(map)
56}
57
58/**
Sergey Kulanov21c936c2017-02-02 13:43:14 +020059 * Render jinja template
60 * @param templateVars String, A dict, a dict subclass, json or some keyword arguments
61 * @param templateFile String, jinja template file path
62 * @param resultFile String, result/generate file path
63 *
64 * Usage example:
65 *
66 * def common = new com.mirantis.mcp.Common()
67 * common.renderJinjaTemplate(
68 * "${NODE_JSON}",
69 * "${WORKSPACE}/inventory/inventory.cfg",
70 * "${WORKSPACE}/inventory/inventory.cfg")
71 * where NODE_JSON= data in json format
72 */
73def renderJinjaTemplate(String templateVars, String templateFile, String resultFile) {
74
75 sh """
76 python -c "
77import sys
78import jinja2
79from jinja2 import Template
80
81# Useful for very coarse version differentiation.
82PY2 = sys.version_info[0] == 2
83PY3 = sys.version_info[0] == 3
84PY34 = sys.version_info[0:2] >= (3, 4)
85
86if PY3:
87 string_types = str,
88else:
89 string_types = basestring
90
91
92def to_bool(a):
93 ''' return a bool for the arg '''
94 if a is None or type(a) == bool:
95 return a
96 if isinstance(a, string_types):
97 a = a.lower()
98 if a in ['yes', 'on', '1', 'true', 1]:
99 return True
100 else:
101 return False
102
103
104def generate(templateVars, templateFile, resultFile):
105 templateLoader = jinja2.FileSystemLoader(searchpath='/')
106 templateEnv = jinja2.Environment(loader=templateLoader)
107 templateEnv.filters['bool'] = to_bool
108 template = templateEnv.get_template(templateFile)
109 outputText = template.render(templateVars)
110 Template(outputText).stream().dump(resultFile)
111
112generate(${templateVars}, '${templateFile}', '${resultFile}')
113"
114 cat ${resultFile}
115 """
116}
117
118/**
Sergey Kulanove897d8f2017-01-23 16:44:03 +0200119 * Run function on k8s cluster
120 *
121 * @param config LinkedHashMap
122 * config includes next parameters:
123 * - label, pod label
124 * - function, code that should be run on k8s cluster
125 * - jnlpImg, jnlp slave image
126 * - slaveImg, slave image
127 *
128 * Usage example:
129 *
130 * def runFunc = new com.mirantis.mcp.Common()
131 * runFunc.runOnKubernetes ([
132 * function : this.&buildCalicoContainers,
133 * jnlpImg: 'docker-prod-virtual.docker.mirantis.net/mirantis/jenkins-slave-images/jnlp-slave:latest',
134 * slaveImg : 'sandbox-docker-dev-local.docker.mirantis.net/skulanov/jenkins-slave-images/calico-slave:1'
135 * ])
136 * // promotion example. In case of promotion we need only jnlp container
137 * def runFunc = new com.mirantis.mcp.Common()
138 * runFunc.runOnKubernetes ([
139 * jnlpImg: 'docker-prod-virtual.docker.mirantis.net/mirantis/jenkins-slave-images/jnlp-slave:latest',
140 * function : this.&promote_artifacts
141 * ])
142 */
143def runOnKubernetes(LinkedHashMap config) {
144
145
146 def jenkinsSlaveImg = config.get('slaveImg', 'none')
147 def jnlpSlaveImg = config.get('jnlpImg', 'none')
148 def lbl = config.get('label', "buildpod.${env.JOB_NAME}.${env.BUILD_NUMBER}".replace('-', '_').replace('/', '_'))
149 def toRun = config.get('function', 'none')
150
Sergey Kulanovb1aa0ff2017-01-23 17:48:44 +0200151 if (jnlpSlaveImg == 'none') {
Sergey Kulanove897d8f2017-01-23 16:44:03 +0200152 error('jnlp Slave image MUST be defined')
153 }
154
155 if (toRun == 'none'){
156 error('Code that should be run on k8s MUST be passed along with function parameter')
157 }
158
159 if (jenkinsSlaveImg == 'none'){
160 // we are running jnlp container only, since no jenkinsSlaveImg is specified, so
161 // we are in promotion mode
162 podTemplate(label: lbl,
163 containers: [
164 containerTemplate(
165 name: 'jnlp',
166 image: jnlpSlaveImg,
167 args: '${computer.jnlpmac} ${computer.name}'
168 )
169 ],
170 ) {
171 node(lbl){
172 container('jnlp') {
173 toRun()
174 }
175 }
176 }
177
178 } else {
179 podTemplate(label: lbl,
180 containers: [
181 containerTemplate(
182 name: 'jnlp',
183 image: jnlpSlaveImg,
184 args: '${computer.jnlpmac} ${computer.name}'
185 ),
186 containerTemplate(
187 name: 'k8s-slave',
188 image: jenkinsSlaveImg,
189 alwaysPullImage: false,
190 ttyEnabled: true,
191 privileged: true
192 )
193 ],
194 ) {
195 node(lbl){
196 container('k8s-slave') {
Sergey Kulanovb36e36e2017-01-23 18:26:40 +0200197 return toRun()
Sergey Kulanove897d8f2017-01-23 16:44:03 +0200198 }
199 }
200 }
201 } //else
202
203}