[yum-git] Branch 'yum-3_2_X' - 2 commits - yum/rpmtrans.py
James Antill
james at linux.duke.edu
Tue Sep 23 14:34:52 UTC 2008
yum/rpmtrans.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 8 deletions(-)
New commits:
commit 0aed92573666a4e09650e5a5c0f25357ac957d2a
Author: James Antill <james at and.org>
Date: Tue Sep 23 10:34:44 2008 -0400
Protect I/O calls within RPMTransaction itself, due to rpm insane mode.
Try and cleanup if they trigger, so we don't have half a transaction saved
in the log files.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index 98faa9a..0961b34 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -138,6 +138,11 @@ class SimpleCliCallBack(RPMBaseCallback):
if msgs:
print msgs,
+# This is ugly, but atm. rpm can go insane and run the "cleanup" phase
+# without the "install" phase if it gets an exception in it's callback. The
+# following means that we don't really need to know/care about that in the
+# display callback functions.
+# Note try/except's in RPMTransaction are for the same reason.
class _WrapNoExceptions:
def __init__(self, parent):
self.__parent = parent
@@ -292,8 +297,17 @@ class RPMTransaction:
# hope springs eternal that this isn't wrong
msg = '%s %s:%s-%s-%s.%s\n' % (t,e,n,v,r,a)
- self._ts_done.write(msg)
- self._ts_done.flush()
+ try:
+ self._ts_done.write(msg)
+ self._ts_done.flush()
+ except (IOError, OSError), e:
+ try:
+ # Having incomplete transactions is probably worse than having
+ # nothing.
+ del self._ts_done
+ os.unlink(self.ts_done_fn)
+ except:
+ pass
self._te_tuples.pop(0)
def ts_all(self):
@@ -333,12 +347,20 @@ class RPMTransaction:
self.display.errorlog('could not open ts_all file: %s' % e)
return
- for (t,e,n,v,r,a) in self._te_tuples:
- msg = "%s %s:%s-%s-%s.%s\n" % (t,e,n,v,r,a)
- fo.write(msg)
- fo.flush()
- fo.close()
-
+ try:
+ for (t,e,n,v,r,a) in self._te_tuples:
+ msg = "%s %s:%s-%s-%s.%s\n" % (t,e,n,v,r,a)
+ fo.write(msg)
+ fo.flush()
+ fo.close()
+ except (IOError, OSError), e:
+ try:
+ # Having incomplete transactions is probably worse than having
+ # nothing.
+ os.unlink(self.ts_all_fn)
+ except:
+ pass
+
def callback( self, what, bytes, total, h, user ):
if what == rpm.RPMCALLBACK_TRANS_START:
self._transStart( bytes, total, h )
commit cf896fc7ccc135aeb94d69739bb625fc44934377
Author: James Antill <james at and.org>
Date: Tue Sep 23 10:25:05 2008 -0400
Wrap all calls to the display callbacks within the rpm transaction.
The problem here is that rpm gets _very_ unhappy if exceptions happen in
any of the code it calls during the transaction, and can basically destroy
the system (stopping the install phase but doing the cleanup phase).
This doesn't 100% protect us, as we can still have errors in our code
but it'll protect against anything in the callbacks.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index 34fa178..98faa9a 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -138,12 +138,33 @@ class SimpleCliCallBack(RPMBaseCallback):
if msgs:
print msgs,
+class _WrapNoExceptions:
+ def __init__(self, parent):
+ self.__parent = parent
+
+ def __getattr__(self, name):
+ """ Wraps all access to the parent functions. This is so it'll eat all
+ exceptions because rpm doesn't like exceptions in the callback. """
+ func = getattr(self.__parent, name)
+
+ def newFunc(*args, **kwargs):
+ try:
+ func(*args, **kwargs)
+ except:
+ pass
+
+ newFunc.__name__ = func.__name__
+ newFunc.__doc__ = func.__doc__
+ newFunc.__dict__.update(func.__dict__)
+ return newFunc
+
class RPMTransaction:
def __init__(self, base, test=False, display=NoOutputCallBack):
if not callable(display):
self.display = display
else:
self.display = display() # display callback
+ self.display = _WrapNoExceptions(self.display)
self.base = base # base yum object b/c we need so much
self.test = test # are we a test?
self.trans_running = False
More information about the Yum-cvs-commits
mailing list