diff options
author | kali <kali@leap.se> | 2012-09-06 02:34:40 +0900 |
---|---|---|
committer | kali <kali@leap.se> | 2012-09-06 02:34:40 +0900 |
commit | bd26d30f34104898dd6c5314dee688e27c82529b (patch) | |
tree | 226ed4f238369f8937c28e3d0f11258cbfb7b506 | |
parent | 6ef92e257ce1e605194cb26ff6cb804c7d2c3418 (diff) | |
parent | 8148bc9c8c113c41fcb18b397669b1f13447c653 (diff) |
Merge branch 'feature/error-handling' into develop
Closes #504: design generic error handling solution.
* app-wide logging config.
* --logfile command line argument.
* created basic exception hierarchy
* conductor pushes exceptions to error queue
* in Qt, error dialogs are created from exception attributes
-rw-r--r-- | src/leap/app.py | 35 | ||||
-rw-r--r-- | src/leap/baseapp/constants.py | 5 | ||||
-rw-r--r-- | src/leap/baseapp/dialogs.py | 36 | ||||
-rw-r--r-- | src/leap/baseapp/eip.py | 183 | ||||
-rw-r--r-- | src/leap/baseapp/leap_app.py | 8 | ||||
-rw-r--r-- | src/leap/baseapp/log.py | 11 | ||||
-rw-r--r-- | src/leap/baseapp/mainwindow.py | 25 | ||||
-rw-r--r-- | src/leap/baseapp/systray.py | 2 | ||||
-rw-r--r-- | src/leap/eip/checks.py | 7 | ||||
-rw-r--r-- | src/leap/eip/config.py | 2 | ||||
-rw-r--r-- | src/leap/eip/eipconnection.py | 46 | ||||
-rw-r--r-- | src/leap/eip/exceptions.py | 115 | ||||
-rw-r--r-- | src/leap/eip/openvpnconnection.py | 22 | ||||
-rw-r--r-- | src/leap/util/leap_argparse.py | 4 |
14 files changed, 323 insertions, 178 deletions
diff --git a/src/leap/app.py b/src/leap/app.py index db48701b..5849848c 100644 --- a/src/leap/app.py +++ b/src/leap/app.py @@ -6,9 +6,6 @@ from PyQt4.QtGui import (QApplication, QSystemTrayIcon, QMessageBox) from leap.baseapp.mainwindow import LeapWindow -logging.basicConfig() -logger = logging.getLogger(name=__name__) - def main(): """ @@ -20,17 +17,39 @@ def main(): parser, opts = leap_argparse.init_leapc_args() debug = getattr(opts, 'debug', False) - #XXX get debug level and set logger accordingly + # XXX get severity from command line args if debug: - logger.setLevel('DEBUG') - logger.debug('args: %s' % opts) + level = logging.DEBUG + else: + level = logging.WARNING + + logger = logging.getLogger(name='leap') + logger.setLevel(level) + console = logging.StreamHandler() + console.setLevel(level) + formatter = logging.Formatter( + '%(asctime)s ' + '- %(name)s - %(levelname)s - %(message)s') + console.setFormatter(formatter) + logger.addHandler(console) + + logfile = getattr(opts, 'log_file', False) + if logfile: + logger.debug('setting logfile to %s ', logfile) + fileh = logging.FileHandler(logfile) + fileh.setLevel(logging.DEBUG) + fileh.setFormatter(formatter) + logger.addHandler(fileh) + + logger.debug('args: %s' % opts) + logger.info('Starting app') app = QApplication(sys.argv) if not QSystemTrayIcon.isSystemTrayAvailable(): QMessageBox.critical(None, "Systray", - "I couldn't detect any \ -system tray on this system.") + "I couldn't detect" + "any system tray on this system.") sys.exit(1) if not debug: QApplication.setQuitOnLastWindowClosed(False) diff --git a/src/leap/baseapp/constants.py b/src/leap/baseapp/constants.py index 763df23b..e312be21 100644 --- a/src/leap/baseapp/constants.py +++ b/src/leap/baseapp/constants.py @@ -1 +1,6 @@ +# This timer used for polling vpn manager state. + +# XXX what is an optimum polling interval? +# too little will be overkill, too much will +# miss transition states. TIMER_MILLISECONDS = 250.0 diff --git a/src/leap/baseapp/dialogs.py b/src/leap/baseapp/dialogs.py index 4b1b5b62..d4acb09d 100644 --- a/src/leap/baseapp/dialogs.py +++ b/src/leap/baseapp/dialogs.py @@ -1,33 +1,47 @@ +import logging + from PyQt4.QtGui import (QDialog, QFrame, QPushButton, QLabel, QMessageBox) +logger = logging.getLogger(name=__name__) + class ErrorDialog(QDialog): - def __init__(self, parent=None): + def __init__(self, parent=None, errtype=None, msg=None, label=None): super(ErrorDialog, self).__init__(parent) - frameStyle = QFrame.Sunken | QFrame.Panel self.warningLabel = QLabel() self.warningLabel.setFrameStyle(frameStyle) self.warningButton = QPushButton("QMessageBox.&warning()") + if msg is not None: + self.msg = msg + if label is not None: + self.label = label + if errtype == "critical": + self.criticalMessage(self.msg, self.label) + def warningMessage(self, msg, label): msgBox = QMessageBox(QMessageBox.Warning, "QMessageBox.warning()", msg, QMessageBox.NoButton, self) msgBox.addButton("&Ok", QMessageBox.AcceptRole) - msgBox.addButton("&Cancel", QMessageBox.RejectRole) if msgBox.exec_() == QMessageBox.AcceptRole: - self.warningLabel.setText("Save Again") - else: - self.warningLabel.setText("Continue") + pass + # do whatever we want to do after + # closing the dialog. we can pass that + # in the constructor def criticalMessage(self, msg, label): msgBox = QMessageBox(QMessageBox.Critical, "QMessageBox.critical()", msg, QMessageBox.NoButton, self) msgBox.addButton("&Ok", QMessageBox.AcceptRole) - msgBox.addButton("&Cancel", QMessageBox.RejectRole) - if msgBox.exec_() == QMessageBox.AcceptRole: - self.warningLabel.setText("Save Again") - else: - self.warningLabel.setText("Continue") + msgBox.exec_() + + # It's critical, so we exit. + # We should better emit a signal and connect it + # with the proper shutdownAndQuit method, but + # this suffices for now. + logger.info('Quitting') + import sys + sys.exit() diff --git a/src/leap/baseapp/eip.py b/src/leap/baseapp/eip.py index 029ce0ba..afdb7adc 100644 --- a/src/leap/baseapp/eip.py +++ b/src/leap/baseapp/eip.py @@ -1,3 +1,4 @@ +import logging import time from PyQt4 import QtCore @@ -7,8 +8,10 @@ from leap.baseapp import constants from leap.eip import exceptions as eip_exceptions from leap.eip.eipconnection import EIPConnection +logger = logging.getLogger(name=__name__) -class EIPConductorApp(object): + +class EIPConductorAppMixin(object): """ initializes an instance of EIPConnection, gathers errors, and passes status-change signals @@ -48,64 +51,90 @@ class EIPConductorApp(object): lambda: self.start_or_stopVPN()) def error_check(self): + """ + consumes the conductor error queue. + pops errors, and acts accordingly (launching user dialogs). + """ + logger.debug('error check') + + ##################################### + # XXX refactor in progress (by #504) + + errq = self.conductor.error_queue + while errq.qsize() != 0: + logger.debug('%s errors left in conductor queue', errq.qsize()) + error = errq.get() + + # redundant log, debugging the loop. + logger.error('%s: %s', error.__class__.__name__, error.message) + + if issubclass(error.__class__, eip_exceptions.EIPClientError): + self.handle_eip_error(error) + + else: + # This is not quite working. FIXME + import traceback + traceback.print_exc() + raise error + + if error.failfirst is True: + break + + ############################################# + # old errors to check + # write test for them and them remove + # their corpses from here. + + #if self.conductor.missing_vpn_keyfile is True: + #dialog = ErrorDialog() + #dialog.criticalMessage( + #'Could not find the vpn keys file', + #'error') + + #if self.conductor.bad_keyfile_perms is True: + #dialog = ErrorDialog() + #dialog.criticalMessage( + #'The vpn keys file has bad permissions', + #'error') + + # deprecated. configchecker takes care of that. + #if self.conductor.missing_definition is True: + #dialog = ErrorDialog() + #dialog.criticalMessage( + #'The default ' + #'definition.json file cannot be found', + #'error') + + def handle_eip_error(self, error): + """ + check severity and launches + dialogs informing user about the errors. + in the future we plan to derive errors to + our log viewer. + """ - # XXX refactor (by #504) - - if self.conductor.missing_definition is True: - dialog = ErrorDialog() - dialog.criticalMessage( - 'The default ' - 'definition.json file cannot be found', - 'error') - - if self.conductor.missing_provider is True: - dialog = ErrorDialog() - dialog.criticalMessage( - 'Missing provider. Add a remote_ip entry ' - 'under section [provider] in eip.cfg', - 'error') - - if self.conductor.missing_vpn_keyfile is True: - dialog = ErrorDialog() - dialog.criticalMessage( - 'Could not find the vpn keys file', - 'error') - - # ... btw, review pending. - # os.kill of subprocess fails if we have - # some of this errors. - - if self.conductor.bad_provider is True: - dialog = ErrorDialog() - dialog.criticalMessage( - 'Bad provider entry. Check that remote_ip entry ' - 'has an IP under section [provider] in eip.cfg', - 'error') - - if self.conductor.bad_keyfile_perms is True: - dialog = ErrorDialog() - dialog.criticalMessage( - 'The vpn keys file has bad permissions', - 'error') - - if self.conductor.missing_auth_agent is True: - dialog = ErrorDialog() - dialog.warningMessage( - 'We could not find any authentication ' - 'agent in your system.<br/>' - 'Make sure you have ' - '<b>polkit-gnome-authentication-agent-1</b> ' - 'running and try again.', - 'error') - - if self.conductor.missing_pkexec is True: + if getattr(error, 'usermessage', None): + message = error.usermessage + else: + message = error.message + + # XXX + # check headless = False before + # launching dialog. + # (so Qt tests can assert stuff) + + if error.critical: + logger.critical(error.message) + #critical error (non recoverable), + #we give user some info and quit. + #(critical error dialog will exit app) + ErrorDialog(errtype="critical", + msg=message, + label="critical error") + + else: dialog = ErrorDialog() - dialog.warningMessage( - 'We could not find <b>pkexec</b> in your ' - 'system.<br/> Do you want to try ' - '<b>setuid workaround</b>? ' - '(<i>DOES NOTHING YET</i>)', - 'error') + dialog.warningMessage(message, 'error') @QtCore.pyqtSlot() def statusUpdate(self): @@ -126,8 +155,9 @@ class EIPConductorApp(object): if self.conductor.with_errors: #XXX how to wait on pkexec??? #something better that this workaround, plz!! - time.sleep(2) - print('errors. disconnect.') + time.sleep(5) + logger.debug('timeout') + logger.error('errors. disconnect') self.start_or_stopVPN() # is stop state = self.conductor.poll_connection_state() @@ -161,29 +191,30 @@ class EIPConductorApp(object): """ stub for running child process with vpn """ + if self.conductor.has_errors(): + logger.debug('not starting vpn; conductor has errors') + if self.eip_service_started is False: try: self.conductor.connect() - # XXX move this to error queue - except eip_exceptions.EIPNoCommandError: - dialog = ErrorDialog() - dialog.warningMessage( - 'No suitable openvpn command found. ' - '<br/>(Might be a permissions problem)', - 'error') - if self.debugmode: - self.startStopButton.setText('&Disconnect') - self.eip_service_started = True - # XXX what is optimum polling interval? - # too little is overkill, too much - # will miss transition states.. + except eip_exceptions.EIPNoCommandError as exc: + self.handle_eip_error(exc) + + except Exception as err: + # raise generic exception (Bad Thing Happened?) + logger.exception(err) + else: + # no errors, so go on. + if self.debugmode: + self.startStopButton.setText('&Disconnect') + self.eip_service_started = True - # XXX decouple! (timer is init by icons class). - # should bring it here? - # to its own class? + # XXX decouple! (timer is init by icons class). + # we could bring Timer Init to this Mixin + # or to its own Mixin. + self.timer.start(constants.TIMER_MILLISECONDS) - self.timer.start(constants.TIMER_MILLISECONDS) return if self.eip_service_started is True: diff --git a/src/leap/baseapp/leap_app.py b/src/leap/baseapp/leap_app.py index def95da1..f91b2329 100644 --- a/src/leap/baseapp/leap_app.py +++ b/src/leap/baseapp/leap_app.py @@ -1,9 +1,13 @@ +import logging + from PyQt4 import QtGui from leap.gui import mainwindow_rc +logger = logging.getLogger(name=__name__) + -class MainWindow(object): +class MainWindowMixin(object): """ create the main window for leap app @@ -79,5 +83,7 @@ technolust</i>") # TODO:make sure to shutdown all child process / threads # in conductor # XXX send signal instead? + logger.info('Shutting down') self.conductor.cleanup() + logger.info('Exiting') QtGui.qApp.quit() diff --git a/src/leap/baseapp/log.py b/src/leap/baseapp/log.py index 0c98eb94..8a7f81c3 100644 --- a/src/leap/baseapp/log.py +++ b/src/leap/baseapp/log.py @@ -1,8 +1,12 @@ +import logging + from PyQt4 import QtGui from PyQt4 import QtCore +vpnlogger = logging.getLogger('leap.openvpn') + -class LogPane(object): +class LogPaneMixin(object): """ a simple log pane that writes new lines as they come @@ -18,7 +22,6 @@ class LogPane(object): self.logbrowser = QtGui.QTextBrowser() startStopButton = QtGui.QPushButton("&Connect") - #startStopButton.clicked.connect(self.start_or_stopVPN) self.startStopButton = startStopButton logging_layout.addWidget(self.logbrowser) @@ -56,5 +59,7 @@ class LogPane(object): """ simple slot: writes new line to logger Pane. """ + msg = line[:-1] if self.debugmode: - self.logbrowser.append(line[:-1]) + self.logbrowser.append(msg) + vpnlogger.info(msg) diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index ac7fe9c4..10b23d9a 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -1,23 +1,22 @@ # vim: set fileencoding=utf-8 : #!/usr/bin/env python import logging -logging.basicConfig() -logger = logging.getLogger(name=__name__) -logger.setLevel(logging.DEBUG) from PyQt4 import QtCore from PyQt4 import QtGui -from leap.baseapp.eip import EIPConductorApp -from leap.baseapp.log import LogPane -from leap.baseapp.systray import StatusAwareTrayIcon -from leap.baseapp.leap_app import MainWindow +from leap.baseapp.eip import EIPConductorAppMixin +from leap.baseapp.log import LogPaneMixin +from leap.baseapp.systray import StatusAwareTrayIconMixin +from leap.baseapp.leap_app import MainWindowMixin + +logger = logging.getLogger(name=__name__) class LeapWindow(QtGui.QMainWindow, - MainWindow, EIPConductorApp, - StatusAwareTrayIcon, - LogPane): + MainWindowMixin, EIPConductorAppMixin, + StatusAwareTrayIconMixin, + LogPaneMixin): """ main window for the leap app. Initializes all of its base classes @@ -35,9 +34,9 @@ class LeapWindow(QtGui.QMainWindow, super(LeapWindow, self).__init__() if self.debugmode: self.createLogBrowser() - EIPConductorApp.__init__(self, opts=opts) - StatusAwareTrayIcon.__init__(self) - MainWindow.__init__(self) + EIPConductorAppMixin.__init__(self, opts=opts) + StatusAwareTrayIconMixin.__init__(self) + MainWindowMixin.__init__(self) # bind signals # XXX move to parent classes init?? diff --git a/src/leap/baseapp/systray.py b/src/leap/baseapp/systray.py index f3832473..c696ee74 100644 --- a/src/leap/baseapp/systray.py +++ b/src/leap/baseapp/systray.py @@ -4,7 +4,7 @@ from PyQt4 import QtGui from leap.gui import mainwindow_rc -class StatusAwareTrayIcon(object): +class StatusAwareTrayIconMixin(object): """ a mix of several functions needed to create a systray and make it diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py index 1b7c2e1b..4a2a9599 100644 --- a/src/leap/eip/checks.py +++ b/src/leap/eip/checks.py @@ -1,12 +1,7 @@ -#import json import logging import ssl import os -logging.basicConfig() -logger = logging.getLogger(name=__name__) -logger.setLevel(logging.DEBUG) - import requests from leap.base import constants as baseconstants @@ -17,6 +12,8 @@ from leap.eip import exceptions as eipexceptions from leap.eip import specs as eipspecs from leap.util.fileutil import mkdir_p +logger = logging.getLogger(name=__name__) + """ EIPConfigChecker ---------- diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 810a5a8d..f4b979ce 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -10,9 +10,7 @@ from leap.baseapp.permcheck import (is_pkexec_in_system, from leap.eip import exceptions as eip_exceptions from leap.eip import specs as eipspecs -logging.basicConfig() logger = logging.getLogger(name=__name__) -logger.setLevel('DEBUG') class EIPConfig(baseconfig.JSONLeapConfig): diff --git a/src/leap/eip/eipconnection.py b/src/leap/eip/eipconnection.py index 386b71be..5c54a986 100644 --- a/src/leap/eip/eipconnection.py +++ b/src/leap/eip/eipconnection.py @@ -3,15 +3,14 @@ EIP Connection Class """ from __future__ import (absolute_import,) import logging - -logging.basicConfig() -logger = logging.getLogger(name=__name__) -logger.setLevel(logging.DEBUG) +import Queue from leap.eip.checks import EIPConfigChecker from leap.eip import exceptions as eip_exceptions from leap.eip.openvpnconnection import OpenVPNConnection +logger = logging.getLogger(name=__name__) + class EIPConnection(OpenVPNConnection): """ @@ -25,8 +24,7 @@ class EIPConnection(OpenVPNConnection): self.settingsfile = kwargs.get('settingsfile', None) self.logfile = kwargs.get('logfile', None) - # not used atm. but should. - self.error_queue = [] + self.error_queue = Queue.Queue() status_signals = kwargs.pop('status_signals', None) self.status = EIPConnectionStatus(callbacks=status_signals) @@ -34,11 +32,19 @@ class EIPConnection(OpenVPNConnection): super(EIPConnection, self).__init__(*args, **kwargs) + def has_errors(self): + return True if self.error_queue.qsize != 0 else True + def run_checks(self, skip_download=False): """ run all eip checks previous to attempting a connection """ - self.config_checker.run_all(skip_download=skip_download) + logger.debug('running conductor checks') + try: + self.config_checker.run_all(skip_download=skip_download) + self.run_openvpn_checks() + except Exception as exc: + self.error_queue.put(exc) def connect(self): """ @@ -46,7 +52,6 @@ class EIPConnection(OpenVPNConnection): """ self.forget_errors() self._try_connection() - # XXX should capture errors? def disconnect(self): """ @@ -67,11 +72,11 @@ class EIPConnection(OpenVPNConnection): """ return self.status.current - def desired_connection_state(self): - """ - returns the desired_connection state - """ - return self.desired_con_state + #def desired_connection_state(self): + #""" + #returns the desired_connection state + #""" + #return self.desired_con_state def poll_connection_state(self): """ @@ -109,26 +114,27 @@ class EIPConnection(OpenVPNConnection): private method for disconnecting """ if self.subp is not None: + logger.debug('disconnecting...') self.subp.terminate() self.subp = None - # XXX signal state changes! :) - def _is_alive(self): - """ - don't know yet - """ - pass + #def _is_alive(self): + #""" + #don't know yet + #""" + #pass def _connect(self): """ entry point for connection cascade methods. """ - #conn_result = ConState.DISCONNECTED try: conn_result = self._try_connection() except eip_exceptions.UnrecoverableError as except_msg: logger.error("FATAL: %s" % unicode(except_msg)) conn_result = self.status.UNRECOVERABLE + + # XXX enqueue exceptions themselves instead? except Exception as except_msg: self.error_queue.append(except_msg) logger.error("Failed Connection: %s" % diff --git a/src/leap/eip/exceptions.py b/src/leap/eip/exceptions.py index 19a0e707..3c8f6afb 100644 --- a/src/leap/eip/exceptions.py +++ b/src/leap/eip/exceptions.py @@ -1,71 +1,126 @@ -class EIPNoCommandError(Exception): - pass +""" +Generic error hierarchy +Leap/EIP exceptions used for exception handling, +logging, and notifying user of errors +during leap operation. +Exception hierarchy +------------------- +All EIP Errors must inherit from EIPClientError (note: move that to +a more generic LEAPClientBaseError). -class ConnectionError(Exception): - """ - generic connection error - """ - pass +Exception attributes and their meaning/uses +------------------------------------------- + +* critical: if True, will abort execution prematurely, + after attempting any cleaning + action. + +* failfirst: breaks any error_check loop that is examining + the error queue. + +* message: the message that will be used in the __repr__ of the exception. + +* usermessage: the message that will be passed to user in ErrorDialogs + in Qt-land. + +TODO: + +* EIPClientError: + Should inherit from LeapException + and move basic attrs there + +* gettext / i18n for user messages. + +""" class EIPClientError(Exception): """ base EIPClient exception """ - def __str__(self): - if len(self.args) >= 1: - return repr(self.args[0]) - else: - return ConnectionError + critical = False -class UnrecoverableError(EIPClientError): +class CriticalError(EIPClientError): """ we cannot do anything about it, sorry """ - # XXX we should catch this and raise - # to qtland, so we emit signal - # to translate whatever kind of error - # to user-friendly msg in dialog. - pass + critical = True + failfirst = True -class MissingSocketError(Exception): +class Warning(EIPClientError): + """ + just that, warnings + """ pass -class ConnectionRefusedError(Exception): - pass +class EIPNoPolkitAuthAgentAvailable(CriticalError): + message = "No polkit authentication agent could be found" + usermessage = ("We could not find any authentication " + "agent in your system.<br/>" + "Make sure you have " + "<b>polkit-gnome-authentication-agent-1</b> " + "running and try again.") -class EIPNoPkexecAvailable(Exception): - pass +class EIPNoPkexecAvailable(Warning): + message = "No pkexec binary found" + usermessage = ("We could not find <b>pkexec</b> in your " + "system.<br/> Do you want to try " + "<b>setuid workaround</b>? " + "(<i>DOES NOTHING YET</i>)") + failfirst = True + + +class EIPNoCommandError(EIPClientError): + message = "no suitable openvpn command found" + usermessage = ("No suitable openvpn command found. " + "<br/>(Might be a permissions problem)") + +# +# errors still needing some love +# -class EIPNoPolkitAuthAgentAvailable(Exception): +class EIPInitNoKeyFileError(CriticalError): + message = "No vpn keys found in the expected path" + usermessage = "We could not find your eip certs in the expected path" + + +class EIPInitBadKeyFilePermError(Warning): + # I don't know if we should be telling user or not, + # we try to fix permissions and should only re-raise + # if permission check failed. pass -class EIPInitNoProviderError(Exception): +class EIPInitNoProviderError(EIPClientError): pass -class EIPInitBadProviderError(Exception): +class EIPInitBadProviderError(EIPClientError): pass -class EIPInitNoKeyFileError(Exception): +class EIPConfigurationError(EIPClientError): pass +# +# Errors that probably we don't need anymore +# chase down for them and check. +# -class EIPInitBadKeyFilePermError(Exception): + +class MissingSocketError(Exception): pass -class EIPMissingDefaultProvider(Exception): +class ConnectionRefusedError(Exception): pass -class EIPConfigurationError(Exception): +class EIPMissingDefaultProvider(Exception): pass diff --git a/src/leap/eip/openvpnconnection.py b/src/leap/eip/openvpnconnection.py index 32fa55b1..4a6a495a 100644 --- a/src/leap/eip/openvpnconnection.py +++ b/src/leap/eip/openvpnconnection.py @@ -7,9 +7,7 @@ import socket import time from functools import partial -logging.basicConfig() logger = logging.getLogger(name=__name__) -logger.setLevel(logging.DEBUG) from leap.base.connection import Connection from leap.util.coroutines import spawn_and_watch_process @@ -24,7 +22,6 @@ class OpenVPNConnection(Connection): All related to invocation of the openvpn binary """ - # Connection Methods def __init__(self, config_file=None, watcher_cb=None, @@ -45,8 +42,8 @@ to be triggered for each one of them. :type watcher_cb: function :type signal_map: dict """ + logger.debug('init openvpn connection') self.debug = debug - #print('conductor:%s' % debug) self.config_file = config_file self.watcher_cb = watcher_cb @@ -59,15 +56,18 @@ to be triggered for each one of them. self.port = None self.proto = None + ################################## # XXX move all error messages # into a more encapsulated object. self.missing_pkexec = False self.missing_auth_agent = False + self.bad_keyfile_perms = False self.missing_vpn_keyfile = False self.missing_provider = False self.missing_definition = False self.bad_provider = False + ################################# #XXX workaround for signaling #the ui that we don't know how to @@ -79,9 +79,6 @@ to be triggered for each one of them. # XXX get autostart from config self.autostart = True - #self._get_or_create_config() - self._set_ovpn_command() - self._check_vpn_keys() # # management init methods @@ -97,6 +94,11 @@ to be triggered for each one of them. self.port = port self.password = password + def run_openvpn_checks(self): + logger.debug('running openvpn checks') + self._set_ovpn_command() + self._check_vpn_keys() + def _set_ovpn_command(self): # XXX check also for command-line --command flag try: @@ -104,10 +106,13 @@ to be triggered for each one of them. debug=self.debug) except eip_exceptions.EIPNoPolkitAuthAgentAvailable: command = args = None + # XXX deprecate self.missing_auth_agent = True + raise except eip_exceptions.EIPNoPkexecAvailable: command = args = None self.missing_pkexec = True + raise # XXX if not command, signal error. self.command = command @@ -192,7 +197,8 @@ to be triggered for each one of them. # def forget_errors(self): - print('forgetting errors') + #print('forgetting errors') + logger.debug('forgetting errors') self.with_errors = False def connect_to_management(self): diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py index 9c355134..f329cf3e 100644 --- a/src/leap/util/leap_argparse.py +++ b/src/leap/util/leap_argparse.py @@ -11,6 +11,10 @@ Launches main LEAP Client""", epilog=epilog) action="store", dest="config_file", type=argparse.FileType('r'), help='optional config file') + parser.add_argument('--logfile', metavar="LOG FILE", nargs='?', + action="store", dest="log_file", + #type=argparse.FileType('w'), + help='optional log file') return parser |