blob: 88b624d09b5170369cf5099251b2a9ad837ce2d7 [file] [log] [blame]
Sergey Kolekonovba203982016-12-21 18:32:17 +04001package com.mirantis.mk
2
3/**
4 *
5 * Python functions
6 *
7 */
8
9/**
10 * Install python virtualenv
11 *
12 * @param path Path to virtualenv
13 * @param python Version of Python (python/python3)
14 * @param reqs Environment requirements in list format
15 */
16def setupVirtualenv(path, python = 'python2', reqs = []) {
17 virtualenv_cmd = "virtualenv ${path} --python ${python}"
18
19 echo("[Python ${path}] Setup ${python} environment")
20 sh(returnStdout: true, script: virtualenv_cmd)
21 args = ""
22 for (req in reqs) {
23 args = args + "${req}\n"
24 }
25 writeFile file: "${path}/requirements.txt", text: args
26 runVirtualenvCommand(path, "pip install -r ${path}/requirements.txt")
27}
28
29/**
30 * Run command in specific python virtualenv
31 *
32 * @param path Path to virtualenv
33 * @param cmd Command to be executed
34 */
35def runVirtualenvCommand(path, cmd) {
36 virtualenv_cmd = ". ${path}/bin/activate; ${cmd}"
37 echo("[Python ${path}] Run command ${cmd}")
38 output = sh(
39 returnStdout: true,
40 script: virtualenv_cmd
41 ).trim()
42 return output
43}
44
45@NonCPS
46def loadJson(rawData) {
47 return new groovy.json.JsonSlurperClassic().parseText(rawData)
48}
49
50/**
51 * Parse content from markup-text tables to variables
52 *
53 * @param tableStr String representing the table
54 * @param mode Either list (1st row are keys) or item (key, value rows)
55 * @param format Format of the table
56 */
57def parseTextTable(tableStr, type = 'item', format = 'rest') {
Ales Komarek0e558ee2016-12-23 13:02:55 +010058 parserFile = "${env.WORKSPACE}/textTableParser.py"
59 parserScript = """import json
60import argparse
61from docutils.parsers.rst import tableparser
62from docutils import statemachine
63
64def parse_item_table(raw_data):
65 i = 1
66 pretty_raw_data = []
67 for datum in raw_data:
68 if datum != "":
69 if datum[3] != ' ' and i > 4:
70 pretty_raw_data.append(raw_data[0])
71 if i == 3:
72 pretty_raw_data.append(datum.replace('-', '='))
73 else:
74 pretty_raw_data.append(datum)
75 i += 1
76 parser = tableparser.GridTableParser()
77 block = statemachine.StringList(pretty_raw_data)
78 docutils_data = parser.parse(block)
79 final_data = {}
80 for line in docutils_data[2]:
81 key = ' '.join(line[0][3]).strip()
82 value = ' '.join(line[1][3]).strip()
83 if key != "":
84 try:
85 value = json.loads(value)
86 except:
87 pass
88 final_data[key] = value
89 i+=1
90 return final_data
91
92def parse_list_table(raw_data):
93 i = 1
94 pretty_raw_data = []
95 for datum in raw_data:
96 if datum != "":
97 if datum[3] != ' ' and i > 4:
98 pretty_raw_data.append(raw_data[0])
99 if i == 3:
100 pretty_raw_data.append(datum.replace('-', '='))
101 else:
102 pretty_raw_data.append(datum)
103 i += 1
104 parser = tableparser.GridTableParser()
105 block = statemachine.StringList(pretty_raw_data)
106 docutils_data = parser.parse(block)
107 final_data = []
108 keys = []
109 for line in docutils_data[1]:
110 for item in line:
111 keys.append(' '.join(item[3]).strip())
112 for line in docutils_data[2]:
113 final_line = {}
114 key = ' '.join(line[0][3]).strip()
115 value = ' '.join(line[1][3]).strip()
116 if key != "":
117 try:
118 value = json.loads(value)
119 except:
120 pass
121 final_data[key] = value
122 i+=1
123 return final_data
124
125def parse_list_table(raw_data):
126 i = 1
127 pretty_raw_data = []
128 for datum in raw_data:
129 if datum != "":
130 if datum[3] != ' ' and i > 4:
131 pretty_raw_data.append(raw_data[0])
132 if i == 3:
133 pretty_raw_data.append(datum.replace('-', '='))
134 else:
135 pretty_raw_data.append(datum)
136 i += 1
137 parser = tableparser.GridTableParser()
138 block = statemachine.StringList(pretty_raw_data)
139 docutils_data = parser.parse(block)
140 final_data = []
141 keys = []
142 for line in docutils_data[1]:
143 for item in line:
144 keys.append(' '.join(item[3]).strip())
145 for line in docutils_data[2]:
146 final_line = {}
147 i = 0
148 for item in line:
149 value = ' '.join(item[3]).strip()
150 try:
151 value = json.loads(value)
152 except:
153 pass
154 final_line[keys[i]] = value
155 i += 1
156 final_data.append(final_line)
157 return final_data
158
159def read_table_file(file):
160 table_file = open(file, 'r')
Ales Komarekc000c152016-12-23 15:32:54 +0100161 raw_data = table_file.read().split('\\n')
Ales Komarek0e558ee2016-12-23 13:02:55 +0100162 table_file.close()
163 return raw_data
164
165parser = argparse.ArgumentParser()
166parser.add_argument('-f','--file', help='File with table data', required=True)
167parser.add_argument('-t','--type', help='Type of table (list/item)', required=True)
168args = vars(parser.parse_args())
169
170raw_data = read_table_file(args['file'])
171
172if args['type'] == 'list':
173 final_data = parse_list_table(raw_data)
174else:
175 final_data = parse_item_table(raw_data)
176
177print json.dumps(final_data)
178"""
179 writeFile file: parserFile, text: parserScript
Sergey Kolekonovba203982016-12-21 18:32:17 +0400180 tableFile = "${env.WORKSPACE}/prettytable.txt"
181 writeFile file: tableFile, text: tableStr
182 rawData = sh (
Ales Komarek0e558ee2016-12-23 13:02:55 +0100183 script: "python ${parserFile} --file '${tableFile}' --type ${type}",
Sergey Kolekonovba203982016-12-21 18:32:17 +0400184 returnStdout: true
185 ).trim()
186 data = loadJson(rawData)
187 echo("[Parsed table] ${data}")
188 return data
189}
190
191/**
192 * Install cookiecutter in isolated environment
193 *
194 * @param path Path where virtualenv is created
195 */
196def setupCookiecutterVirtualenv(path) {
197 requirements = [
198 'cookiecutter',
199 ]
200 setupVirtualenv(path, 'python2', requirements)
201}
202
203/**
204 * Generate the cookiecutter templates with given context
205 *
206 * @param path Path where virtualenv is created
207 */
208def buildCookiecutterTemplate (template, context, path = none) {
209 contextFile = "default_context.json"
210 contextString = "parameters:\n"
211 for (parameter in context) {
212 contextString = "${contextString} ${parameter.key}: ${parameter.value}\n"
213 }
214 writeFile file: contextFile, text: contextString
215 command = ". ./${work_dir}/bin/activate; cookiecutter --config-file ${cookiecutter_context_file} --overwrite-if-exists --verbose --no-input ${template_dir}"
216 output = sh (returnStdout: true, script: command)
217 echo("[Cookiecutter build] Output: ${output}")
218}
219
220/**
221 * Install jinja rendering in isolated environment
222 *
223 * @param path Path where virtualenv is created
224 */
225def setupJinjaVirtualenv(path) {
226 requirements = [
227 'jinja2-cli',
228 'pyyaml',
229 ]
230 setupVirtualenv(path, 'python2', requirements)
231}
232
233/**
234 * Generate the Jinja templates with given context
235 *
236 * @param path Path where virtualenv is created
237 */
238def jinjaBuildTemplate (template, context, path = none) {
239 contextFile = "jinja_context.yml"
240 contextString = ""
241 for (parameter in context) {
242 contextString = "${contextString}${parameter.key}: ${parameter.value}\n"
243 }
244 writeFile file: contextFile, text: contextString
245 cmd = "jinja2 ${template} ${contextFile} --format=yaml"
246 data = sh (returnStdout: true, script: cmd)
247 echo(data)
248 return data
249}