aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Pipping <sebastian@pipping.org>2010-02-18 06:27:01 +0100
committerSebastian Pipping <sebastian@pipping.org>2010-02-18 06:27:01 +0100
commit15607e2a960e046a9d1cf23bbc04f30c505c5600 (patch)
tree4f762884d6f33871bf9be61483812c6391842dbb
parentMove safe op out of try-except block, extend code doc (diff)
downloadlayman-15607e2a960e046a9d1cf23bbc04f30c505c5600.tar.gz
layman-15607e2a960e046a9d1cf23bbc04f30c505c5600.tar.bz2
layman-15607e2a960e046a9d1cf23bbc04f30c505c5600.zip
Hint about broken overlay catalog
-rw-r--r--CHANGES2
-rw-r--r--layman/action.py11
-rw-r--r--layman/db.py14
-rw-r--r--layman/dbbase.py42
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')