Implement server diagnostics
This outputs a handy summary of your server configuration and version strings etc, which is useful for bug reporting. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
parent
6b3f429c81
commit
3885acf87d
@ -13,6 +13,9 @@ others.
|
|||||||
New Features
|
New Features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
* add a --info command line switch that outputs useful information about
|
||||||
|
the server and the configuration for all enabled accounts.
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -82,6 +82,9 @@ class Account(CustomConfig.ConfigHelperMixin):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def getaccountmeta(self):
|
||||||
|
return os.path.join(self.metadatadir, 'Account-' + self.name)
|
||||||
|
|
||||||
def getsection(self):
|
def getsection(self):
|
||||||
return 'Account ' + self.getname()
|
return 'Account ' + self.getname()
|
||||||
|
|
||||||
@ -154,8 +157,16 @@ class Account(CustomConfig.ConfigHelperMixin):
|
|||||||
self.quicknum = 0
|
self.quicknum = 0
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def serverdiagnostics(self):
|
||||||
|
"""Output diagnostics for all involved repositories"""
|
||||||
|
remote_repo = Repository(self, 'remote')
|
||||||
|
local_repo = Repository(self, 'local')
|
||||||
|
#status_repo = Repository(self, 'status')
|
||||||
|
self.ui.serverdiagnostics(remote_repo, 'Remote')
|
||||||
|
self.ui.serverdiagnostics(local_repo, 'Local')
|
||||||
|
#self.ui.serverdiagnostics(statusrepos, 'Status')
|
||||||
|
|
||||||
class SyncableAccount(Account):
|
class SyncableAccount(Account):
|
||||||
"""A syncable email account connecting 2 repositories
|
"""A syncable email account connecting 2 repositories
|
||||||
|
|
||||||
@ -233,9 +244,6 @@ class SyncableAccount(Account):
|
|||||||
if looping and self.sleeper() >= 2:
|
if looping and self.sleeper() >= 2:
|
||||||
looping = 0
|
looping = 0
|
||||||
|
|
||||||
def getaccountmeta(self):
|
|
||||||
return os.path.join(self.metadatadir, 'Account-' + self.name)
|
|
||||||
|
|
||||||
def sync(self):
|
def sync(self):
|
||||||
"""Synchronize the account once, then return
|
"""Synchronize the account once, then return
|
||||||
|
|
||||||
|
@ -44,9 +44,12 @@ class OfflineImap:
|
|||||||
"""
|
"""
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Parse the commandline and invoke everything"""
|
"""Parse the commandline and invoke everything"""
|
||||||
# next line also sets self.config
|
# next line also sets self.config and self.ui
|
||||||
options = self.parse_cmd_options()
|
options, args = self.parse_cmd_options()
|
||||||
self.sync(options)
|
if options.diagnostics:
|
||||||
|
self.serverdiagnostics(options)
|
||||||
|
else:
|
||||||
|
self.sync(options)
|
||||||
|
|
||||||
def parse_cmd_options(self):
|
def parse_cmd_options(self):
|
||||||
parser = OptionParser(version=offlineimap.__version__,
|
parser = OptionParser(version=offlineimap.__version__,
|
||||||
@ -143,6 +146,13 @@ class OfflineImap:
|
|||||||
"not usable. Possible interface choices are: %s " %
|
"not usable. Possible interface choices are: %s " %
|
||||||
", ".join(UI_LIST.keys()))
|
", ".join(UI_LIST.keys()))
|
||||||
|
|
||||||
|
parser.add_option("--info",
|
||||||
|
action="store_true", dest="diagnostics",
|
||||||
|
default=False,
|
||||||
|
help="Output information on the configured email repositories"
|
||||||
|
". Useful for debugging and bug reporting. Use in conjunction wit"
|
||||||
|
"h the -a option to limit the output to a single account")
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
#read in configuration file
|
#read in configuration file
|
||||||
@ -265,7 +275,7 @@ class OfflineImap:
|
|||||||
config.getdefaultint('Repository ' + reposname,
|
config.getdefaultint('Repository ' + reposname,
|
||||||
'maxconnections', 2))
|
'maxconnections', 2))
|
||||||
self.config = config
|
self.config = config
|
||||||
return options
|
return (options, args)
|
||||||
|
|
||||||
def sync(self, options):
|
def sync(self, options):
|
||||||
"""Invoke the correct single/multithread syncing
|
"""Invoke the correct single/multithread syncing
|
||||||
@ -276,7 +286,7 @@ class OfflineImap:
|
|||||||
# die immediately
|
# die immediately
|
||||||
self.ui.terminate(errormsg="terminating...")
|
self.ui.terminate(errormsg="terminating...")
|
||||||
signal.signal(signal.SIGTERM, sigterm_handler)
|
signal.signal(signal.SIGTERM, sigterm_handler)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pidfd = open(self.config.getmetadatadir() + "/pid", "w")
|
pidfd = open(self.config.getmetadatadir() + "/pid", "w")
|
||||||
pidfd.write(str(os.getpid()) + "\n")
|
pidfd.write(str(os.getpid()) + "\n")
|
||||||
@ -305,11 +315,7 @@ class OfflineImap:
|
|||||||
self.ui.terminate(1, errormsg = errormsg)
|
self.ui.terminate(1, errormsg = errormsg)
|
||||||
if account not in syncaccounts:
|
if account not in syncaccounts:
|
||||||
syncaccounts.append(account)
|
syncaccounts.append(account)
|
||||||
|
|
||||||
server = None
|
|
||||||
remoterepos = None
|
|
||||||
localrepos = None
|
|
||||||
|
|
||||||
def sig_handler(sig, frame):
|
def sig_handler(sig, frame):
|
||||||
if sig == signal.SIGUSR1 or sig == signal.SIGHUP:
|
if sig == signal.SIGUSR1 or sig == signal.SIGHUP:
|
||||||
# tell each account to stop sleeping
|
# tell each account to stop sleeping
|
||||||
@ -370,3 +376,13 @@ class OfflineImap:
|
|||||||
accountname)
|
accountname)
|
||||||
threading.currentThread().name = "Account sync %s" % accountname
|
threading.currentThread().name = "Account sync %s" % accountname
|
||||||
account.syncrunner()
|
account.syncrunner()
|
||||||
|
|
||||||
|
def serverdiagnostics(self, options):
|
||||||
|
activeaccounts = self.config.get("general", "accounts")
|
||||||
|
if options.accounts:
|
||||||
|
activeaccounts = options.accounts
|
||||||
|
activeaccounts = activeaccounts.split(",")
|
||||||
|
allaccounts = accounts.AccountListGenerator(self.config)
|
||||||
|
for account in allaccounts:
|
||||||
|
if account.name not in activeaccounts: continue
|
||||||
|
account.serverdiagnostics()
|
||||||
|
@ -322,6 +322,53 @@ class UIBase:
|
|||||||
s._msg("Deleting flag %s from %d messages on %s" % \
|
s._msg("Deleting flag %s from %d messages on %s" % \
|
||||||
(", ".join(flags), len(uidlist), dest))
|
(", ".join(flags), len(uidlist), dest))
|
||||||
|
|
||||||
|
def serverdiagnostics(self, repository, type):
|
||||||
|
"""Connect to repository and output useful information for debugging"""
|
||||||
|
conn = None
|
||||||
|
self._msg("%s repository '%s': type '%s'" % (type, repository.name,
|
||||||
|
self.getnicename(repository)))
|
||||||
|
try:
|
||||||
|
if hasattr(repository, 'gethost'): # IMAP
|
||||||
|
self._msg("Host: %s Port: %s SSL: %s" % (repository.gethost(),
|
||||||
|
repository.getport(),
|
||||||
|
repository.getssl()))
|
||||||
|
try:
|
||||||
|
conn = repository.imapserver.acquireconnection()
|
||||||
|
except OfflineImapError, e:
|
||||||
|
self._msg("Failed to connect. Reason %s" % e)
|
||||||
|
else:
|
||||||
|
if 'ID' in conn.capabilities:
|
||||||
|
self._msg("Server supports ID extension.")
|
||||||
|
#TODO: Debug and make below working, it hangs Gmail
|
||||||
|
#res_type, response = conn.id((
|
||||||
|
# 'name', offlineimap.__productname__,
|
||||||
|
# 'version', offlineimap.__version__))
|
||||||
|
#self._msg("Server ID: %s %s" % (res_type, response[0]))
|
||||||
|
self._msg("Server welcome string: %s" % str(conn.welcome))
|
||||||
|
self._msg("Server capabilities: %s\n" % str(conn.capabilities))
|
||||||
|
repository.imapserver.releaseconnection(conn)
|
||||||
|
if type != 'Status':
|
||||||
|
folderfilter = repository.getconf('folderfilter', None)
|
||||||
|
if folderfilter:
|
||||||
|
self._msg("folderfilter= %s\n" % folderfilter)
|
||||||
|
folderincludes = repository.getconf('folderincludes', None)
|
||||||
|
if folderincludes:
|
||||||
|
self._msg("folderincludes= %s\n" % folderincludes)
|
||||||
|
nametrans = repository.getconf('nametrans', None)
|
||||||
|
if nametrans:
|
||||||
|
self._msg("nametrans= %s\n" % nametrans)
|
||||||
|
|
||||||
|
folders = repository.getfolders()
|
||||||
|
foldernames = [(f.name, f.getvisiblename()) for f in folders]
|
||||||
|
folders = []
|
||||||
|
for name, visiblename in foldernames:
|
||||||
|
if name == visiblename: folders.append(name)
|
||||||
|
else: folders.append("%s -> %s" % (name, visiblename))
|
||||||
|
self._msg("Folderlist: %s\n" % str(folders))
|
||||||
|
finally:
|
||||||
|
if conn: #release any existing IMAP connection
|
||||||
|
repository.imapserver.close()
|
||||||
|
|
||||||
################################################## Threads
|
################################################## Threads
|
||||||
|
|
||||||
def getThreadDebugLog(s, thread):
|
def getThreadDebugLog(s, thread):
|
||||||
|
Loading…
Reference in New Issue
Block a user