1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import base64
17 import os
18 import stat
19
20 from spacewalk.common.rhnException import rhnFault
21 from spacewalk.common.rhnConfig import CFG
22 from spacewalk.common.rhnLib import parseRPMName
23 from spacewalk.common.rhnLog import log_debug
24 from spacewalk.server import rhnSQL
25 from spacewalk.server.rhnHandler import rhnHandler
26 from spacewalk.server.rhnLib import get_crash_path, get_crashfile_path
27
28 _query_get_crash = rhnSQL.Statement("""
29 select id
30 from rhnServerCrash
31 where server_id = :server_id and
32 crash = :crash
33 """)
34
35 _query_create_crash = rhnSQL.Statement("""
36 insert into rhnServerCrash (
37 id,
38 server_id,
39 crash,
40 path,
41 count,
42 storage_path)
43 values (
44 sequence_nextval('rhn_server_crash_id_seq'),
45 :server_id,
46 :crash,
47 :path,
48 :crash_count,
49 :storage_path)
50 """)
51
52 _query_update_pkg_data1 = rhnSQL.Statement("""
53 update rhnServerCrash
54 set package_name_id = lookup_package_name(:pkg_name),
55 package_evr_id = lookup_evr(:pkg_epoch, :pkg_version, :pkg_release)
56 where id = :crash_id
57 """)
58
59 _query_update_pkg_data2 = rhnSQL.Statement("""
60 update rhnServerCrash
61 set package_name_id = lookup_package_name(:pkg_name),
62 package_evr_id = lookup_evr(:pkg_epoch, :pkg_version, :pkg_release),
63 package_arch_id = lookup_package_arch(:pkg_arch)
64 where id = :crash_id
65 """)
66
67 _query_update_watched_items = """
68 update rhnServerCrash
69 set %s = :filecontent
70 where id = :crash_id
71 """
72
73 _query_update_crash_count = """
74 update rhnServerCrash
75 set count = :crash_count
76 where server_id = :server_id and
77 crash = :crash
78 """
79
80 _query_get_crashfile_sizelimit = """
81 select crash_file_sizelimit
82 from rhnOrgConfiguration
83 where org_id = :org_id
84 """
85
86 _query_set_crashfile_upload_flag = """
87 update rhnServerCrashFile
88 set is_uploaded = 'Y'
89 where id = (
90 select scf.id as id
91 from rhnServerCrashFile scf,
92 rhnServerCrash sc
93 where scf.crash_id = sc.id and
94 scf.crash_id = :crash_id and
95 sc.server_id = :server_id and
96 scf.filename = :filename and
97 scf.path = :path and
98 scf.filesize = :filesize
99 )
100 """
101
102 _query_get_crash_reporting_settings = """
103 select crash_reporting_enabled
104 from rhnOrgConfiguration
105 where org_id = :org_id
106 """
107
108 _query_get_crashfile_upload_settings = """
109 select crashfile_upload_enabled
110 from rhnOrgConfiguration
111 where org_id = :org_id
112 """
113
114
115 -class Abrt(rhnHandler):
116
118 rhnHandler.__init__(self)
119 self.functions.append('create_crash')
120 self.functions.append('update_crash_count')
121 self.functions.append('upload_crash_file')
122 self.functions.append('is_crashfile_upload_enabled')
123 self.functions.append('get_crashfile_uploadlimit')
124
125 self.watched_items = ['analyzer',
126 'architecture',
127 'cmdline',
128 'component',
129 'count',
130 'executable',
131 'kernel',
132 'reason',
133 'username',
134 'uuid']
135
145
149
151 log_debug(1, "_update_package_data: %s, %s" % (crash_id, pkg_data))
152
153 if pkg_data and 'package' in pkg_data:
154 (n, e, v, r) = parseRPMName(pkg_data['package'])
155 if not all((n, e, v, r)):
156 return 0
157
158 h = rhnSQL.prepare(_query_update_pkg_data1)
159 r = h.execute(
160 crash_id=crash_id,
161 pkg_name=n,
162 pkg_epoch=e,
163 pkg_version=v,
164 pkg_release=r)
165 rhnSQL.commit()
166
167 return r
168
169 for item in ['pkg_name', 'pkg_epoch', 'pkg_version', 'pkg_release', 'pkg_arch']:
170 if not (item in pkg_data and pkg_data[item]):
171 return 0
172
173 h = rhnSQL.prepare(_query_update_pkg_data2)
174 r = h.execute(
175 crash_id=crash_id,
176 pkg_name=pkg_data['pkg_name'],
177 pkg_epoch=pkg_data['pkg_epoch'],
178 pkg_version=pkg_data['pkg_version'],
179 pkg_release=pkg_data['pkg_release'],
180 pkg_arch=pkg_data['pkg_arch'])
181 rhnSQL.commit()
182
183 return r
184
189
201
211
221
226
228 self.auth_system(system_id)
229 log_debug(1, self.server_id, crash_data, pkg_data)
230
231 self._check_crash_reporting_setting()
232
233 if not ('crash' in crash_data and 'path' in crash_data) or \
234 not (crash_data['crash'] and crash_data['path']):
235 log_debug(1, self.server_id, "The crash information is invalid or incomplete: %s" % str(crash_data))
236 raise rhnFault(5000)
237
238 server_org_id = self.server.server['org_id']
239 server_crash_dir = get_crash_path(str(server_org_id), str(self.server_id), crash_data['crash'])
240 if not server_crash_dir:
241 log_debug(1, self.server_id, "Error composing crash directory path")
242 raise rhnFault(5002)
243
244 crash_id = self._get_crash_id(self.server_id, crash_data['crash'])
245 log_debug(1, "crash_id: %s" % crash_id)
246
247 if (crash_id is None):
248 if 'count' not in crash_data:
249 crash_data['count'] = 1
250
251 h = rhnSQL.prepare(_query_create_crash)
252 h.execute(
253 server_id=self.server_id,
254 crash=crash_data['crash'],
255 path=crash_data['path'],
256 crash_count=crash_data['count'],
257 storage_path=server_crash_dir)
258 rhnSQL.commit()
259 self._update_package_data(self._get_crash_id(self.server_id, crash_data['crash']), pkg_data)
260 return 1
261 else:
262 return 0
263
265 self.auth_system(system_id)
266 self._check_crash_reporting_setting()
267
268 required_keys = ['filename', 'path', 'filesize', 'filecontent', 'content-encoding']
269 for k in required_keys:
270 if k not in crash_file:
271 log_debug(1, self.server_id, "The crash file data is invalid or incomplete: %s" % crash_file)
272 raise rhnFault(5001, "Missing or invalid key: %s" % k)
273
274 log_debug(1, self.server_id, crash, crash_file['filename'])
275
276 server_org_id = self.server.server['org_id']
277 server_crash_dir = get_crash_path(str(server_org_id), str(self.server_id), crash)
278 if not server_crash_dir:
279 log_debug(1, self.server_id, "Error composing crash directory path")
280 raise rhnFault(5002)
281
282 server_filename = get_crashfile_path(str(server_org_id),
283 str(self.server_id),
284 crash,
285 crash_file['filename'])
286 if not server_filename:
287 log_debug(1, self.server_id, "Error composing crash file path")
288 raise rhnFault(5003)
289
290 if not crash_file['content-encoding'] == 'base64':
291 log_debug(1, self.server_id, "Invalid content encoding: %s" % crash_file['content-encoding'])
292 raise rhnFault(5004, "Invalid content encodig: %s" % crash_file['content-encoding'])
293
294 crash_id = self._get_crash_id(self.server_id, crash)
295 if not crash_id:
296 log_debug(1, self.server_id, "No record for crash: %s" % crash)
297 raise rhnFault(5005, "Invalid crash name: %s" % crash)
298
299
300 self._create_or_update_crash_file(self.server_id, crash_id, crash_file['filename'],
301 crash_file['path'], crash_file['filesize'])
302 rhnSQL.commit()
303
304
305 if not self._is_crashfile_uploading_enabled(server_org_id):
306 return 1
307 filecontent = base64.decodestring(crash_file['filecontent'])
308 claimed_filesize = crash_file['filesize']
309 filesize = len(filecontent)
310 sizelimit = self._get_crashfile_sizelimit()
311 if (claimed_filesize > sizelimit or filesize > sizelimit) and sizelimit != 0:
312 if filesize == 0:
313 filesize = claimed_filesize
314 log_debug(1, "The file [%s] size (%s bytes) is more than allowed (%s bytes), skipping."
315 % (crash_file['path'], filesize, sizelimit))
316 return 0
317 absolute_dir = os.path.join(CFG.MOUNT_POINT, server_crash_dir)
318 absolute_file = os.path.join(absolute_dir, crash_file['filename'])
319
320 if not os.path.exists(absolute_dir):
321 log_debug(1, self.server_id, "Creating crash directory: %s" % absolute_dir)
322 os.makedirs(absolute_dir)
323 mode = stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH
324 os.chmod(absolute_dir, mode)
325 os.chmod(os.path.dirname(os.path.normpath(absolute_dir)), mode)
326
327 log_debug(1, self.server_id, "Creating crash file: %s" % absolute_file)
328 f = open(absolute_file, 'w+')
329 f.write(filecontent)
330 f.close()
331
332 self._set_crashfile_upload_flag(self.server_id, crash_id, crash_file['filename'],
333 crash_file['path'], crash_file['filesize'])
334
335 if crash_file['filename'] in self.watched_items:
336
337 if crash_file['filename'] == 'username':
338 filecontent = filecontent.strip()
339 st = rhnSQL.Statement(_query_update_watched_items % crash_file['filename'])
340 h = rhnSQL.prepare(st)
341 h.execute(filecontent=filecontent, crash_id=crash_id)
342 rhnSQL.commit()
343
344 return 1
345
347 self.auth_system(system_id)
348
349 log_debug(1, self.server_id, "Updating crash count for %s to %s" % (crash, crash_count))
350
351 server_org_id = self.server.server['org_id']
352 server_crash_dir = get_crash_path(str(server_org_id), str(self.server_id), crash)
353 if not server_crash_dir:
354 log_debug(1, self.server_id, "Error composing crash directory path")
355 raise rhnFault(5002)
356
357 h = rhnSQL.prepare(_query_update_crash_count)
358 r = h.execute(
359 crash_count=crash_count,
360 server_id=self.server_id,
361 crash=crash)
362 rhnSQL.commit()
363
364 if r == 0:
365 log_debug(1, self.server_id, "No record for crash: %s" % crash)
366 raise rhnFault(5005, "Invalid crash name: %s" % crash)
367
368 absolute_dir = os.path.join(CFG.MOUNT_POINT, server_crash_dir)
369 absolute_file = os.path.join(absolute_dir, 'count')
370
371 log_debug(1, self.server_id, "Updating crash count file: %s" % absolute_file)
372 f = open(absolute_file, 'w+')
373 f.write(crash_count)
374 f.close()
375
376 return 1
377
381
385