|
Packit |
8ea169 |
import os
|
|
Packit |
8ea169 |
import logging
|
|
Packit |
8ea169 |
import report
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
import problem
|
|
Packit |
8ea169 |
import problem.config
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
class DBusProxy(object):
|
|
Packit |
8ea169 |
__instance = None
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def __init__(self, dbus):
|
|
Packit |
8ea169 |
self._proxy = None
|
|
Packit |
8ea169 |
self._iface = None
|
|
Packit |
8ea169 |
self.dbus = dbus
|
|
Packit |
8ea169 |
self.connected = False
|
|
Packit |
8ea169 |
self.connect()
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def __new__(cls, *args, **kwargs):
|
|
Packit |
8ea169 |
if not cls.__instance:
|
|
Packit |
8ea169 |
cls.__instance = super(DBusProxy, cls).__new__(cls)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return cls.__instance
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def connect(self):
|
|
Packit |
8ea169 |
self.connected = False
|
|
Packit |
8ea169 |
if self._proxy:
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
# we might get org.freedesktop.DBus.Error.ServiceUnknown here
|
|
Packit |
8ea169 |
# if endpoint timed out
|
|
Packit |
8ea169 |
self._proxy.close()
|
|
Packit |
8ea169 |
except self.dbus.exceptions.DBusException:
|
|
Packit |
8ea169 |
pass
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
self._proxy = self.dbus.SystemBus().get_object(
|
|
Packit |
8ea169 |
'org.freedesktop.problems', '/org/freedesktop/problems')
|
|
Packit |
8ea169 |
except self.dbus.exceptions.DBusException as e:
|
|
Packit |
8ea169 |
logging.debug('Unable to get dbus proxy: {0}'.format(e))
|
|
Packit |
8ea169 |
return
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
self._iface = self.dbus.Interface(self._proxy,
|
|
Packit |
8ea169 |
'org.freedesktop.problems')
|
|
Packit |
8ea169 |
except self.dbus.exceptions.DBusException as e:
|
|
Packit |
8ea169 |
logging.debug('Unable to get dbus interface: {0}'.format(e))
|
|
Packit |
8ea169 |
return
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self.connected = True
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def _dbus_call(self, fun_name, *args):
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
logging.debug('Calling {0} with {1}'.format(fun_name, args))
|
|
Packit |
8ea169 |
return getattr(self._iface, fun_name)(*args)
|
|
Packit |
8ea169 |
except self.dbus.exceptions.DBusException as e:
|
|
Packit |
8ea169 |
dbname = e.get_dbus_name()
|
|
Packit |
8ea169 |
if dbname == "org.freedesktop.DBus.Error.ServiceUnknown":
|
|
Packit |
8ea169 |
self.connect()
|
|
Packit |
8ea169 |
return getattr(self._iface, fun_name)(*args)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if dbname == 'org.freedesktop.problems.AuthFailure':
|
|
Packit |
8ea169 |
raise problem.exception.AuthFailure(e)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if dbname == 'org.freedesktop.problems.InvalidProblemDir':
|
|
Packit |
8ea169 |
raise problem.exception.InvalidProblem(e)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
raise
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def get_item(self, dump_dir, name):
|
|
Packit |
8ea169 |
val = self._dbus_call('GetInfo', dump_dir, [name])
|
|
Packit |
8ea169 |
if name not in val:
|
|
Packit |
8ea169 |
return None
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return str(val[name])
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def set_item(self, dump_dir, name, value):
|
|
Packit |
8ea169 |
return self._dbus_call('SetElement', dump_dir, name, str(value))
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def del_item(self, dump_dir, name):
|
|
Packit |
8ea169 |
return self._dbus_call('DeleteElement', dump_dir, name)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def create(self, problem_dict):
|
|
Packit |
8ea169 |
return self._dbus_call('NewProblem', problem_dict)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def delete(self, dump_dir):
|
|
Packit |
8ea169 |
return self._dbus_call('DeleteProblem', [dump_dir])
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def chown(self, dump_dir):
|
|
Packit |
8ea169 |
return self._dbus_call('ChownProblemDir', dump_dir)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list(self):
|
|
Packit |
8ea169 |
return [str(prob) for prob in self._dbus_call('GetProblems')]
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list_all(self):
|
|
Packit |
8ea169 |
return [str(prob) for prob in self._dbus_call('GetAllProblems')]
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
class SocketProxy(object):
|
|
Packit |
8ea169 |
def create(self, problem_dict):
|
|
Packit |
8ea169 |
import socket
|
|
Packit |
8ea169 |
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
Packit |
8ea169 |
sock.settimeout(5)
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
sock.connect('/var/run/abrt/abrt.socket')
|
|
Packit |
8ea169 |
sock.sendall("PUT / HTTP/1.1\r\n\r\n")
|
|
Packit |
8ea169 |
for key, value in problem_dict.items():
|
|
Packit |
8ea169 |
sock.sendall('{0}={1}\0'.format(key.upper(), value))
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
sock.shutdown(socket.SHUT_WR)
|
|
Packit |
8ea169 |
resp = ''
|
|
Packit |
8ea169 |
while True:
|
|
Packit |
8ea169 |
buf = sock.recv(256)
|
|
Packit |
8ea169 |
if not buf:
|
|
Packit |
8ea169 |
break
|
|
Packit |
8ea169 |
resp += buf
|
|
Packit |
8ea169 |
return resp
|
|
Packit |
8ea169 |
except socket.timeout as exc:
|
|
Packit |
8ea169 |
logging.error('communication with daemon failed: {0}'.format(exc))
|
|
Packit |
8ea169 |
return None
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def get_item(self, *args):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def set_item(self, *args):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def del_item(self, *args):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def delete(self, *args):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list(self, *args):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list_all(self, *args):
|
|
Packit |
8ea169 |
return self.list(*args)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def get_problem_watcher(self):
|
|
Packit |
8ea169 |
raise NotImplementedError
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
class FsProxy(object):
|
|
Packit |
8ea169 |
def __init__(self, directory=problem.config.DEFAULT_DUMP_LOCATION):
|
|
Packit |
8ea169 |
self.directory = directory
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def create(self, problem_dict):
|
|
Packit |
8ea169 |
probd = report.problem_data()
|
|
Packit |
8ea169 |
for key, value in problem_dict.items():
|
|
Packit |
8ea169 |
probd.add(key, value)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ddir = probd.create_dump_dir(self.directory)
|
|
Packit |
8ea169 |
ret = ddir.name
|
|
Packit |
8ea169 |
ddir.close()
|
|
Packit |
8ea169 |
problem.notify_new_path(ret)
|
|
Packit |
8ea169 |
return ret
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def _open_ddir(self, dump_dir, readonly=False):
|
|
Packit |
8ea169 |
flags = 0
|
|
Packit |
8ea169 |
if readonly:
|
|
Packit |
8ea169 |
flags |= report.DD_OPEN_READONLY
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ddir = report.dd_opendir(dump_dir, flags)
|
|
Packit |
8ea169 |
if not ddir:
|
|
Packit |
8ea169 |
raise problem.exception.InvalidProblem(
|
|
Packit |
8ea169 |
'Can\'t open directory: {0}'.format(dump_dir))
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return ddir
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def get_item(self, dump_dir, name):
|
|
Packit |
8ea169 |
ddir = self._open_ddir(dump_dir, readonly=True)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
flags = (report.DD_FAIL_QUIETLY_EACCES |
|
|
Packit |
8ea169 |
report.DD_FAIL_QUIETLY_ENOENT |
|
|
Packit |
8ea169 |
report.DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
val = ddir.load_text(name, flags).encode('utf-8', errors='ignore')
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ddir.close()
|
|
Packit |
8ea169 |
return val
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def set_item(self, dump_dir, name, value):
|
|
Packit |
8ea169 |
ddir = self._open_ddir(dump_dir)
|
|
Packit |
8ea169 |
ddir.save_text(name, str(value))
|
|
Packit |
8ea169 |
ddir.close()
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def del_item(self, dump_dir, name):
|
|
Packit |
8ea169 |
ddir = self._open_ddir(dump_dir)
|
|
Packit |
8ea169 |
ddir.delete_item(name)
|
|
Packit |
8ea169 |
ddir.close()
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def delete(self, dump_dir):
|
|
Packit |
8ea169 |
ddir = report.dd_opendir(dump_dir)
|
|
Packit |
8ea169 |
if not ddir:
|
|
Packit |
8ea169 |
return not os.path.isdir(dump_dir)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ddir.delete()
|
|
Packit |
8ea169 |
return True
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list(self, _all=False):
|
|
Packit |
8ea169 |
for dir_entry in os.listdir(self.directory):
|
|
Packit |
8ea169 |
dump_dir = os.path.join(self.directory, dir_entry)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if not os.path.isdir(dump_dir) or not os.access(dump_dir, os.R_OK):
|
|
Packit |
8ea169 |
continue
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
uid = os.getuid()
|
|
Packit |
8ea169 |
gid = os.getuid()
|
|
Packit |
8ea169 |
dir_stat = os.stat(dump_dir)
|
|
Packit |
8ea169 |
if not _all and (dir_stat.st_uid != uid and
|
|
Packit |
8ea169 |
dir_stat.st_gid != gid):
|
|
Packit |
8ea169 |
continue
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ddir = report.dd_opendir(dump_dir, report.DD_OPEN_READONLY)
|
|
Packit |
8ea169 |
if ddir:
|
|
Packit |
8ea169 |
ddir.close()
|
|
Packit |
8ea169 |
yield dump_dir
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def list_all(self, *args, **kwargs):
|
|
Packit |
8ea169 |
kwargs.update(dict(_all=True))
|
|
Packit |
8ea169 |
return self.list(*args, **kwargs)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
def get_proxy():
|
|
Packit |
8ea169 |
try:
|
|
Packit |
8ea169 |
import dbus
|
|
Packit |
8ea169 |
wrapper = DBusProxy(dbus)
|
|
Packit |
8ea169 |
if wrapper.connected:
|
|
Packit |
8ea169 |
return wrapper
|
|
Packit |
8ea169 |
except ImportError:
|
|
Packit |
8ea169 |
logging.debug('DBus not found')
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return FsProxy()
|