From 15607e2a960e046a9d1cf23bbc04f30c505c5600 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Thu, 18 Feb 2010 06:27:01 +0100 Subject: Hint about broken overlay catalog --- CHANGES | 2 ++ layman/action.py | 11 ++++++++--- layman/db.py | 14 +++++++++++--- layman/dbbase.py | 42 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index e2f94a6..8a76df1 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,8 @@ Version TODO - Fix syncing of tar overlays (bug #304547) + - Hint about broken overlay catalog (bug #304781) + Version 1.3.1 - Released 2010/02/05 =================================== diff --git a/layman/action.py b/layman/action.py index b8a9c27..a393167 100644 --- a/layman/action.py +++ b/layman/action.py @@ -26,7 +26,7 @@ __version__ = "$Id: action.py 312 2007-04-09 19:45:49Z wrobel $" import os, sys -from layman.dbbase import UnknownOverlayException +from layman.dbbase import UnknownOverlayException, BrokenOverlayCatalog from layman.db import DB, RemoteDB from layman.utils import path, delete_empty_directory from layman.debug import OUT @@ -66,7 +66,7 @@ class Fetch: ''' def __init__(self, config): - self.db = RemoteDB(config) + self.db = RemoteDB(config, ignore_init_read_errors=True) def run(self): '''Fetch the overlay listing.''' @@ -544,7 +544,12 @@ def main(config): OUT.debug('Checking for action', 7) if i[0] in config.keys(): - result += i[1](config).run() + try: + result += i[1](config).run() + except Exception, error: + OUT.error(str(error)) + result = -1 # So it cannot remain 0, i.e. success + break # Reset umask os.umask(old_umask) diff --git a/layman/db.py b/layman/db.py index 2a95f47..cdaeb62 100644 --- a/layman/db.py +++ b/layman/db.py @@ -62,6 +62,10 @@ class DB(DbBase): OUT.debug('DB handler initiated', 6) + # overrider + def _broken_catalog_hint(self): + return '' + def add(self, overlay, quiet = False): ''' Add an overlay to the local list of overlays. @@ -210,7 +214,7 @@ class DB(DbBase): class RemoteDB(DbBase): '''Handles fetching the remote overlay list.''' - def __init__(self, config): + def __init__(self, config, ignore_init_read_errors=False): self.config = config @@ -237,7 +241,11 @@ class RemoteDB(DbBase): quiet = int(config['quietness']) < 3 - DbBase.__init__(self, paths, config, ignore, quiet) + DbBase.__init__(self, paths, config, ignore, quiet, ignore_init_read_errors) + + # overrider + def _broken_catalog_hint(self): + return 'Try running "sudo layman -f" to re-fetch that file' def cache(self): ''' @@ -292,7 +300,7 @@ class RemoteDB(DbBase): # Before we overwrite the old cache, check that the downloaded # file is intact and can be parsed try: - self.read(olist) + self.read(olist, origin=url) except Exception, error: raise IOError('Failed to parse the overlays list fetched fr' 'om ' + url + '\nThis means that the download' diff --git a/layman/dbbase.py b/layman/dbbase.py index d8aa401..88916ae 100644 --- a/layman/dbbase.py +++ b/layman/dbbase.py @@ -29,6 +29,7 @@ __version__ = "$Id: overlay.py 273 2006-12-30 15:54:50Z wrobel $" #------------------------------------------------------------------------------- import sys, os, os.path +import xml import xml.etree.ElementTree as ET # Python 2.5 from layman.debug import OUT @@ -46,6 +47,23 @@ class UnknownOverlayException(Exception): message = 'Overlay "%s" does not exist.' % repo_name super(UnknownOverlayException, self).__init__(message) +#=============================================================================== +# +# Class BrokenOverlayCatalog +# +#------------------------------------------------------------------------------- + +class BrokenOverlayCatalog(ValueError): + def __init__(self, origin, expat_error, hint=None): + if hint == None: + hint = '' + else: + hint = '\nHint: %s' % hint + + super(BrokenOverlayCatalog, self).__init__( + 'XML parsing failed for "%(origin)s" (line %(line)d, column %(column)d)%(hint)s' % \ + {'line':expat_error.lineno, 'column':expat_error.offset + 1, 'origin':origin, 'hint':hint}) + #=============================================================================== # @@ -56,7 +74,7 @@ class UnknownOverlayException(Exception): class DbBase: ''' Handle a list of overlays.''' - def __init__(self, paths, config, ignore = 0, quiet = False): + def __init__(self, paths, config, ignore = 0, quiet = False, ignore_init_read_errors=False): self.config = config self.quiet = quiet @@ -68,8 +86,13 @@ class DbBase: OUT.debug('Initializing overlay list handler', 8) for path in self.paths: - if os.path.exists(path): + if not os.path.exists(path): + continue + + try: self.read_file(path) + except Exception, error: + if not ignore_init_read_errors: raise error def __eq__(self, other): for key in set(self.overlays.keys() + other.overlays.keys()): @@ -90,9 +113,14 @@ class DbBase: raise IOError('Failed to read the overlay list at ("' + path + '")!\nError was:\n' + str(error)) - self.read(document) + self.read(document, origin=path) - def read(self, text): + def _broken_catalog_hint(self): + this_function_name = sys._getframe().f_code.co_name + raise NotImplementedError('Method "%s.%s" not implemented' % \ + (self.__class__.__name__, this_function_name)) + + def read(self, text, origin): ''' Read an xml list of overlays (adding to and potentially overwriting existing entries) @@ -105,7 +133,11 @@ class DbBase: >>> list(a.overlays['wrobel-stable'].source_uris()) [u'rsync://gunnarwrobel.de/wrobel-stable'] ''' - document = ET.fromstring(text) + try: + document = ET.fromstring(text) + except xml.parsers.expat.ExpatError, error: + raise BrokenOverlayCatalog(origin, error, self._broken_catalog_hint()) + overlays = document.findall('overlay') + \ document.findall('repo') -- cgit v1.2.3-1-g7c22