]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core.git/blob - scripts/send-error-report
conf/licenses: Add FreeType SPDX mapping
[thirdparty/openembedded/openembedded-core.git] / scripts / send-error-report
1 #!/usr/bin/env python3
2
3 # Sends an error report (if the report-error class was enabled) to a
4 # remote server.
5 #
6 # Copyright (C) 2013 Intel Corporation
7 # Author: Andreea Proca <andreea.b.proca@intel.com>
8 # Author: Michael Wood <michael.g.wood@intel.com>
9 #
10 # SPDX-License-Identifier: GPL-2.0-only
11 #
12
13 import urllib.request, urllib.error
14 import sys
15 import json
16 import os
17 import subprocess
18 import argparse
19 import logging
20
21 scripts_lib_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib')
22 sys.path.insert(0, scripts_lib_path)
23 import argparse_oe
24
25 version = "0.3"
26
27 log = logging.getLogger("send-error-report")
28 logging.basicConfig(format='%(levelname)s: %(message)s')
29
30 def getPayloadLimit(url):
31 req = urllib.request.Request(url, None)
32 try:
33 response = urllib.request.urlopen(req)
34 except urllib.error.URLError as e:
35 # Use this opportunity to bail out if we can't even contact the server
36 log.error("Could not contact server: " + url)
37 log.error(e.reason)
38 sys.exit(1)
39 try:
40 ret = json.loads(response.read())
41 max_log_size = ret.get('max_log_size', 0)
42 return int(max_log_size)
43 except:
44 pass
45
46 return 0
47
48 def ask_for_contactdetails():
49 print("Please enter your name and your email (optionally), they'll be saved in the file you send.")
50 username = input("Name (required): ")
51 email = input("E-mail (not required): ")
52 return username, email
53
54 def edit_content(json_file_path):
55 edit = input("Review information before sending? (y/n): ")
56 if 'y' in edit or 'Y' in edit:
57 editor = os.environ.get('EDITOR', None)
58 if editor:
59 subprocess.check_call([editor, json_file_path])
60 else:
61 log.error("Please set your EDITOR value")
62 sys.exit(1)
63 return True
64 return False
65
66 def prepare_data(args):
67 # attempt to get the max_log_size from the server's settings
68 max_log_size = getPayloadLimit(args.protocol+args.server+"/ClientPost/JSON")
69
70 if not os.path.isfile(args.error_file):
71 log.error("No data file found.")
72 sys.exit(1)
73
74 home = os.path.expanduser("~")
75 userfile = os.path.join(home, ".oe-send-error")
76
77 try:
78 with open(userfile, 'r') as userfile_fp:
79 if len(args.name) == 0:
80 args.name = userfile_fp.readline()
81 else:
82 #use empty readline to increment the fp
83 userfile_fp.readline()
84
85 if len(args.email) == 0:
86 args.email = userfile_fp.readline()
87 except:
88 pass
89
90 if args.assume_yes == True and len(args.name) == 0:
91 log.error("Name needs to be provided either via "+userfile+" or as an argument (-n).")
92 sys.exit(1)
93
94 while len(args.name) <= 0 or len(args.name) > 50:
95 print("\nName needs to be given and must not more than 50 characters.")
96 args.name, args.email = ask_for_contactdetails()
97
98 with open(userfile, 'w') as userfile_fp:
99 userfile_fp.write(args.name.strip() + "\n")
100 userfile_fp.write(args.email.strip() + "\n")
101
102 with open(args.error_file, 'r') as json_fp:
103 data = json_fp.read()
104
105 jsondata = json.loads(data)
106 jsondata['username'] = args.name.strip()
107 jsondata['email'] = args.email.strip()
108 jsondata['link_back'] = args.link_back.strip()
109 # If we got a max_log_size then use this to truncate to get the last
110 # max_log_size bytes from the end
111 if max_log_size != 0:
112 for fail in jsondata['failures']:
113 if len(fail['log']) > max_log_size:
114 print("Truncating log to allow for upload")
115 fail['log'] = fail['log'][-max_log_size:]
116
117 data = json.dumps(jsondata, indent=4, sort_keys=True)
118
119 # Write back the result which will contain all fields filled in and
120 # any post processing done on the log data
121 with open(args.error_file, "w") as json_fp:
122 if data:
123 json_fp.write(data)
124
125
126 if args.assume_yes == False and edit_content(args.error_file):
127 #We'll need to re-read the content if we edited it
128 with open(args.error_file, 'r') as json_fp:
129 data = json_fp.read()
130
131 return data.encode('utf-8')
132
133
134 def send_data(data, args):
135 headers={'Content-type': 'application/json', 'User-Agent': "send-error-report/"+version}
136
137 if args.json:
138 url = args.protocol+args.server+"/ClientPost/JSON/"
139 else:
140 url = args.protocol+args.server+"/ClientPost/"
141
142 req = urllib.request.Request(url, data=data, headers=headers)
143 try:
144 response = urllib.request.urlopen(req)
145 except urllib.error.HTTPError as e:
146 logging.error(str(e))
147 sys.exit(1)
148
149 print(response.read().decode('utf-8'))
150
151
152 if __name__ == '__main__':
153 arg_parse = argparse_oe.ArgumentParser(description="This scripts will send an error report to your specified error-report-web server.")
154
155 arg_parse.add_argument("error_file",
156 help="Generated error report file location",
157 type=str)
158
159 arg_parse.add_argument("-y",
160 "--assume-yes",
161 help="Assume yes to all queries and do not prompt",
162 action="store_true")
163
164 arg_parse.add_argument("-s",
165 "--server",
166 help="Server to send error report to",
167 type=str,
168 default="errors.yoctoproject.org")
169
170 arg_parse.add_argument("-e",
171 "--email",
172 help="Email address to be used for contact",
173 type=str,
174 default="")
175
176 arg_parse.add_argument("-n",
177 "--name",
178 help="Submitter name used to identify your error report",
179 type=str,
180 default="")
181
182 arg_parse.add_argument("-l",
183 "--link-back",
184 help="A url to link back to this build from the error report server",
185 type=str,
186 default="")
187
188 arg_parse.add_argument("-j",
189 "--json",
190 help="Return the result in json format, silences all other output",
191 action="store_true")
192
193 arg_parse.add_argument("--no-ssl",
194 help="Use http instead of https protocol",
195 dest="protocol",
196 action="store_const", const="http://", default="https://")
197
198
199
200 args = arg_parse.parse_args()
201
202 if (args.json == False):
203 print("Preparing to send errors to: "+args.server)
204
205 data = prepare_data(args)
206 send_data(data, args)
207
208 sys.exit(0)