blob: a6c9e6b1bbfdf0a4880d5544a51e831478e00d40 [file] [log] [blame]
Milosz Wasilewski2d726a02014-09-09 14:47:54 +01001#!/usr/bin/python
2
3from optparse import OptionParser
4import json
5import logging
6import os
7import re
8import sys
9import urllib2
10
11log = logging.getLogger("jsonmerge")
12log.setLevel(logging.DEBUG)
13ch = logging.StreamHandler()
14ch.setLevel(logging.DEBUG)
15formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
16ch.setFormatter(formatter)
17log.addHandler(ch)
18
19
20def download_custom_json(url, auth=None):
21 request = urllib2.Request(url)
22 if auth:
23 request.add_header('Authorization', auth)
24 try:
25 response = urllib2.urlopen(request)
26 except urllib2.URLError, e:
27 if hasattr(e, 'reason'):
28 log.error('Failed to reach %s.' % url)
29 log.error('Reason: ', e.reason)
30 elif hasattr(e, 'code'):
31 log.error('ci.linaro.org could not fulfill the request: %s' % \
32 url)
33 log.error('Error code: ', e.code)
34 sys.exit('Failed to get last successful artifact.')
35 return response.read()
36
37
38def substitute_template_variables(template, environ):
39 """ Env variable names for substitution
40 have to start with SUB_
41 Template variables are marked with
42 %%VARIABLE%%
43 Variable names need to be uppercase
44 """
45 sub_expr = re.compile("%%(?P<variable>[_A-Z]+)%%")
46 for var in sub_expr.finditer(template):
47 var_name = var.group('variable')
48 log.debug("Substituting: SUB_%s" % (var_name))
49 var_value = environ.get("SUB_%s" % var_name)
50 if var_value:
51 template = template.replace(var.group(0), var_value)
52 else:
53 log.error("Variable SUB_%s is not set" % (var_name))
54 sys.exit("Failed to create valid JSON")
55 return template
56
57
58def main():
59 usage = "usage: %prog [OPTIONS]"
60 parser = OptionParser(usage=usage)
61 parser.add_option("-e", "--environment", dest="environ",
62 help="Environment variable for running script")
63 parser.add_option("-m", "--metadata", dest="metadata",
64 help="Metadata in JSON format \
65 to be placed in the output definition")
66 parser.add_option("-i", "--input", dest="input_file",
67 help="Input template JSON file")
68 parser.add_option("-o", "--output", dest="output",
69 help="Output file to store JSON")
70 (options, args) = parser.parse_args()
71
72 if options.environ:
73 f = open(options.environ, "r")
74 for line in f.readlines():
75 split_result = line.split("=", 1)
76 if len(split_result) > 1:
77 os.environ[split_result[0]] = split_result[1].strip()
78 f.close()
79
80 if not options.input_file:
81 parser.error("Unable to construct job definition \
82 without the template")
83
84 config_tmpl = open(options.input_file, "r")
85 config = substitute_template_variables(config_tmpl.read(), os.environ)
86 config_tmpl.close()
87 json_config = json.loads(config)
88
89 metadata_json = None
90 if options.metadata:
91 f = open(options.metadata, "r")
92 metadata = f.read()
93 try:
94 metadata_json = json.loads(metadata)
95 except:
96 log.error("Unable to parse metadata file")
97
98 metadata_url = os.environ.get("METADATA_URL", None)
99 if metadata_url:
100 metadata = download_custom_json(metadata_url)
101 try:
102 metadata_json = json.loads(metadata)
103 except:
104 log.error("Unable to parse metadata URL")
105
106 if metadata_json:
107 if 'metadata' in json_config['actions'][0]:
108 json_config['actions'][0]['metadata'].update(metadata_json)
109 else:
110 json_config['actions'][0]['metadata'] = metadata_json
111
112 if options.output:
113 f = open(options.output, "w")
114 f.write(json.dumps(json_config, indent=2))
115 f.close()
116 else:
117 print json.dumps(json_config, indent=2)
118
119
120if __name__ == '__main__':
121 main()