2016-02-18 02:53:35 +03:00
# Copyright (C) 2015-2016 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2022-08-26 21:01:05 +03:00
import dbus
2016-02-18 02:53:35 +03:00
import threading
# noinspection PyUnresolvedReferences
2016-03-09 01:04:44 +03:00
from gi . repository import GLib
2016-02-18 02:53:35 +03:00
from . job import Job
from . import cfg
2022-08-31 19:18:55 +03:00
from . utils import log_error , mt_async_call , extract_stack_trace
2016-02-18 02:53:35 +03:00
class RequestEntry ( object ) :
def __init__ ( self , tmo , method , arguments , cb , cb_error ,
2016-06-28 20:07:21 +03:00
return_tuple = True , job_state = None ) :
2016-02-18 02:53:35 +03:00
self . method = method
self . arguments = arguments
self . cb = cb
self . cb_error = cb_error
self . timer_id = - 1
self . lock = threading . RLock ( )
self . done = False
self . _result = None
2016-06-28 19:45:05 +03:00
self . _job = None
2016-02-18 02:53:35 +03:00
self . _rc = 0
self . _rc_error = None
self . _return_tuple = return_tuple
2016-06-28 20:07:21 +03:00
self . _job_state = job_state
2016-02-18 02:53:35 +03:00
2016-12-15 00:30:01 +03:00
if tmo < 0 :
2016-02-18 02:53:35 +03:00
# Client is willing to block forever
pass
elif tmo == 0 :
self . _return_job ( )
else :
2016-12-15 00:30:01 +03:00
# Note: using 990 instead of 1000 for second to ms conversion to
# account for overhead. Goal is to return just before the
# timeout amount has expired. Better to be a little early than
# late.
self . timer_id = GLib . timeout_add (
tmo * 990 , RequestEntry . _request_timeout , self )
2016-02-18 02:53:35 +03:00
@staticmethod
def _request_timeout ( r ) :
"""
Method which gets called when the timer runs out !
: param r : RequestEntry which timed out
2016-12-15 00:30:01 +03:00
: return : Result of timer_expired
2016-02-18 02:53:35 +03:00
"""
2016-12-15 00:30:01 +03:00
return r . timer_expired ( )
2016-02-18 02:53:35 +03:00
def _return_job ( self ) :
2016-12-13 01:13:27 +03:00
# Return job is only called when we create a request object or when
# we pop a timer. In both cases we are running in the correct context
# and do not need to schedule the call back in main context.
2016-06-28 20:07:21 +03:00
self . _job = Job ( self , self . _job_state )
2016-02-18 02:53:35 +03:00
cfg . om . register_object ( self . _job , True )
if self . _return_tuple :
2016-12-13 01:13:27 +03:00
self . cb ( ( ' / ' , self . _job . dbus_object_path ( ) ) )
2016-02-18 02:53:35 +03:00
else :
2016-12-13 01:13:27 +03:00
self . cb ( self . _job . dbus_object_path ( ) )
2016-02-18 02:53:35 +03:00
def run_cmd ( self ) :
try :
result = self . method ( * self . arguments )
self . register_result ( result )
2022-08-26 19:10:24 +03:00
except SystemExit as se :
self . register_error ( - 1 , str ( se ) , se )
raise se
2022-08-26 21:01:05 +03:00
except dbus . exceptions . DBusException as dbe :
# This is an expected error path when something goes awry that
# we handled
self . register_error ( - 1 , str ( dbe ) , dbe )
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
except Exception as e :
2016-02-18 02:53:35 +03:00
# Use the request entry to return the result as the client may
# have gotten a job by the time we hit an error
2022-08-26 21:01:05 +03:00
# Lets set the exception text as the error message and log the
# exception in the journal for figuring out what went wrong.
2022-08-18 01:24:08 +03:00
cfg . debug . dump ( )
2022-08-10 01:55:27 +03:00
cfg . flightrecorder . dump ( )
2022-08-31 19:18:55 +03:00
tb = extract_stack_trace ( e )
2022-08-26 21:01:05 +03:00
log_error ( " While processing %s : we encountered \n %s " % ( str ( self . method ) , tb ) )
log_error ( " Error returned to client: %s " % str ( e ) )
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
self . register_error ( - 1 , str ( e ) , e )
2016-02-18 02:53:35 +03:00
def is_done ( self ) :
with self . lock :
rc = self . done
return rc
def get_errors ( self ) :
with self . lock :
return ( self . _rc , self . _rc_error )
def result ( self ) :
with self . lock :
if self . done :
return self . _result
return ' / '
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
def _reg_ending ( self , result , error_rc = 0 , error_msg = None ,
error_exception = None ) :
2016-02-18 02:53:35 +03:00
with self . lock :
self . done = True
if self . timer_id != - 1 :
# Try to prevent the timer from firing
2016-03-09 01:04:44 +03:00
GLib . source_remove ( self . timer_id )
2016-02-18 02:53:35 +03:00
self . _result = result
self . _rc = error_rc
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
self . _rc_error = error_msg
2016-02-18 02:53:35 +03:00
if not self . _job :
# We finished and there is no job, so return result or error
# now!
# Note: If we don't have a valid cb or cbe, this indicates a
# request that doesn't need a response as we already returned
# one before the request was processed.
if error_rc == 0 :
if self . cb :
if self . _return_tuple :
2017-09-22 17:59:50 +03:00
mt_async_call ( self . cb , ( result , ' / ' ) )
2016-02-18 02:53:35 +03:00
else :
2017-09-22 17:59:50 +03:00
mt_async_call ( self . cb , result )
2016-02-18 02:53:35 +03:00
else :
if self . cb_error :
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
if not error_exception :
if not error_msg :
error_exception = Exception (
" An error occurred, but no reason was "
" given, see service logs! " )
else :
error_exception = Exception ( error_msg )
2017-09-22 17:59:50 +03:00
mt_async_call ( self . cb_error , error_exception )
2016-02-18 02:53:35 +03:00
else :
2023-02-16 19:24:06 +03:00
# We have a job, and it's complete, indicate that it's done.
2016-02-18 02:53:35 +03:00
self . _job . Complete = True
self . _job = None
lvmdbus: Fix exception during exception handling
Python 3.5 in F24 was throwing the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/main.py", line 73, in process_request
req.run_cmd()
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 73, in run_cmd
self.register_error(-1, st)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 123, in register_error
self._reg_ending(None, error_rc, error)
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 115, in _reg_ending
self.cb_error(self._rc_error)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 669, in <lambda>
keywords[error_callback] = lambda exception: _method_reply_error(connection, message, exception)
File "/usr/lib64/python3.5/site-packages/dbus/service.py", line 293, in _method_reply_error
exception))
File "/usr/lib64/python3.5/traceback.py", line 136, in format_exception_only
return list(TracebackException(etype, value, None).format_exception_only())
File "/usr/lib64/python3.5/traceback.py", line 442, in __init__
if (exc_value and exc_value.__cause__ is not None
AttributeError: 'str' object has no attribute '__cause__'
This was caused because we were calling the dbus error callback with a
string instead of an actual exception. On python 3.4 this was apparently
OK, but not with 3.5. Corrected to pass the exception to error callback.
Change tested on both python 3.4 and 3.5.
Reported-by: Vratislav Podzimek <vpodzime@redhat.com>
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2016-03-09 00:57:15 +03:00
def register_error ( self , error_rc , error_message , error_exception ) :
2016-09-17 08:10:46 +03:00
self . _reg_ending ( ' / ' , error_rc , error_message , error_exception )
2016-02-18 02:53:35 +03:00
def register_result ( self , result ) :
self . _reg_ending ( result )
def timer_expired ( self ) :
with self . lock :
# Set the timer back to -1 as we will get a warning if we try
# to remove a timer that doesn't exist
self . timer_id = - 1
if not self . done :
# Create dbus job object and return path to caller
self . _return_job ( )
else :
# The job is done, we have nothing to do
pass
return False