summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-09-06 02:34:40 +0900
committerkali <kali@leap.se>2012-09-06 02:34:40 +0900
commitbd26d30f34104898dd6c5314dee688e27c82529b (patch)
tree226ed4f238369f8937c28e3d0f11258cbfb7b506
parent6ef92e257ce1e605194cb26ff6cb804c7d2c3418 (diff)
parent8148bc9c8c113c41fcb18b397669b1f13447c653 (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.py35
-rw-r--r--src/leap/baseapp/constants.py5
-rw-r--r--src/leap/baseapp/dialogs.py36
-rw-r--r--src/leap/baseapp/eip.py183
-rw-r--r--src/leap/baseapp/leap_app.py8
-rw-r--r--src/leap/baseapp/log.py11
-rw-r--r--src/leap/baseapp/mainwindow.py25
-rw-r--r--src/leap/baseapp/systray.py2
-rw-r--r--src/leap/eip/checks.py7
-rw-r--r--src/leap/eip/config.py2
-rw-r--r--src/leap/eip/eipconnection.py46
-rw-r--r--src/leap/eip/exceptions.py115
-rw-r--r--src/leap/eip/openvpnconnection.py22
-rw-r--r--src/leap/util/leap_argparse.py4
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