[yum-commits] Branch 'yum-3_2_X' - 6 commits - cli.py yum/depsolve.py yum/rpmtrans.py
Panu Matilainen
pmatilai at osuosl.org
Fri Feb 25 09:40:16 UTC 2011
cli.py | 1
yum/depsolve.py | 9 ++
yum/rpmtrans.py | 173 +++++++++++++++++++++++++-------------------------------
3 files changed, 89 insertions(+), 94 deletions(-)
New commits:
commit bfb557ad7224c8ead41121d9ef60850d0cf2db02
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Fri Feb 25 11:38:25 2011 +0200
Enable the new callback mode for yum itself
API users should be converted one-by-one to the new mode...
diff --git a/cli.py b/cli.py
index 0441c02..a4c7c79 100644
--- a/cli.py
+++ b/cli.py
@@ -73,6 +73,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
self.logger = logging.getLogger("yum.cli")
self.verbose_logger = logging.getLogger("yum.verbose.cli")
self.yum_cli_commands = {}
+ self.use_txmbr_in_callback = True
self.registerCommand(yumcommands.InstallCommand())
self.registerCommand(yumcommands.UpdateCommand())
self.registerCommand(yumcommands.InfoCommand())
commit a11bb92b0ac168535a64c57a20f4730c25ea46d0
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Fri Feb 25 11:37:44 2011 +0200
Add a new opt-in callback mode where only txmbr is used as the key
We really only want the txmbr in the key, everything else can be
reached through it. This avoids copying any data around as txmbrs
reside in memory anyway, so the key is just a cheap reference
to what we already have. With the new key -> txmbr helper in the
callback, this is truly trivial to handle there. The new mode
makes life in the callback somewhat easier and saves gobs of memory.
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 3aaba0e..8f18ccc 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -69,6 +69,8 @@ class Depsolve(object):
self._ts = None
self._tsInfo = None
self.dsCallback = None
+ # Callback-style switch, default to legacy (hdr, file) mode
+ self.use_txmbr_in_callback = False
self.logger = logging.getLogger("yum.Depsolve")
self.verbose_logger = logging.getLogger("yum.verbose.Depsolve")
@@ -220,8 +222,13 @@ class Depsolve(object):
txmbr.ts_state = 'i'
txmbr.output_state = TS_INSTALL
+ # New-style callback with just txmbr instead of full headers?
+ if self.use_txmbr_in_callback:
+ cbkey = txmbr
+ else:
+ cbkey = (hdr, rpmfile)
- self.ts.addInstall(hdr, (hdr, rpmfile), txmbr.ts_state)
+ self.ts.addInstall(hdr, cbkey, txmbr.ts_state)
self.verbose_logger.log(logginglevels.DEBUG_1,
_('Adding Package %s in mode %s'), txmbr.po, txmbr.ts_state)
if self.dsCallback:
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index f969b03..08bf99d 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -25,6 +25,7 @@ import types
import sys
from yum.constants import *
from yum import _
+from yum.transactioninfo import TransactionMember
import misc
import tempfile
@@ -258,7 +259,9 @@ class RPMTransaction:
# the exact txmbr but we always have a name, so return (name, txmbr)
# tuples so callers have less twists to deal with.
def _getTxmbr(self, cbkey):
- if isinstance(cbkey, tuple):
+ if isinstance(cbkey, TransactionMember):
+ return (cbkey.name, cbkey)
+ elif isinstance(cbkey, tuple):
pkgtup = self._dopkgtup(cbkey[0])
txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
# if this is not one, somebody screwed up
commit 905728eac850b7e2109deb9c8aafd05701ee04c3
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Fri Feb 25 11:36:57 2011 +0200
Unify callback key guessworks into helper function
Add an internal helper method to deal with the changing key type,
and locate the associated txmbr object when possible. We can't find
it on erasures, but we always have a name so return (name, txmbr) tuples
to simplify life for callers.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index ecb1129..f969b03 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -254,6 +254,21 @@ class RPMTransaction:
return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
+ # Find out txmbr based on the callback key. On erasures we dont know
+ # the exact txmbr but we always have a name, so return (name, txmbr)
+ # tuples so callers have less twists to deal with.
+ def _getTxmbr(self, cbkey):
+ if isinstance(cbkey, tuple):
+ pkgtup = self._dopkgtup(cbkey[0])
+ txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
+ # if this is not one, somebody screwed up
+ assert len(txmbrs) == 1
+ return (txmbrs[0].name, txmbrs[0])
+ elif isinstance(cbkey, basestring):
+ return (cbkey, None)
+ else:
+ return (None, None)
+
def ts_done(self, package, action):
"""writes out the portions of the transaction which have completed"""
@@ -415,9 +430,9 @@ class RPMTransaction:
def _instOpenFile(self, bytes, total, h):
self.lastmsg = None
- hdr = None
- if h is not None:
- hdr, rpmloc = h[0], h[1]
+ name, txmbr = self._getTxmbr(h)
+ if txmbr is not None:
+ rpmloc = txmbr.po.localPkg()
try:
self.fd = file(rpmloc)
except IOError, e:
@@ -426,48 +441,41 @@ class RPMTransaction:
if self.trans_running:
self.total_installed += 1
self.complete_actions += 1
- self.installed_pkg_names.add([hdr['name']])
+ self.installed_pkg_names.add(name)
return self.fd.fileno()
else:
self.display.errorlog("Error: No Header to INST_OPEN_FILE")
def _instCloseFile(self, bytes, total, h):
- hdr = None
- if h is not None:
- hdr, rpmloc = h[0], h[1]
+ name, txmbr = self._getTxmbr(h)
+ if txmbr is not None:
self.fd.close()
self.fd = None
if self.test: return
if self.trans_running:
- pkgtup = self._dopkgtup(hdr)
- txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
- for txmbr in txmbrs:
- self.display.filelog(txmbr.po, txmbr.output_state)
- self._scriptout(txmbr.po)
- # NOTE: We only do this for install, not erase atm.
- # because we don't get pkgtup data for erase (this
- # includes "Updated" pkgs).
- pid = self.base.history.pkg2pid(txmbr.po)
- state = self.base.history.txmbr2state(txmbr)
- self.base.history.trans_data_pid_end(pid, state)
- self.ts_done(txmbr.po, txmbr.output_state)
+ self.display.filelog(txmbr.po, txmbr.output_state)
+ self._scriptout(txmbr.po)
+ # NOTE: We only do this for install, not erase atm.
+ # because we don't get pkgtup data for erase (this
+ # includes "Updated" pkgs).
+ pid = self.base.history.pkg2pid(txmbr.po)
+ state = self.base.history.txmbr2state(txmbr)
+ self.base.history.trans_data_pid_end(pid, state)
+ self.ts_done(txmbr.po, txmbr.output_state)
def _instProgress(self, bytes, total, h):
- if h is not None:
- # If h is a string, we're repackaging.
+ name, txmbr = self._getTxmbr(h)
+ if name is not None:
+ # If we only have a name, we're repackaging.
# Why the RPMCALLBACK_REPACKAGE_PROGRESS flag isn't set, I have no idea
- if type(h) == type(""):
- self.display.event(h, 'repackaging', bytes, total,
+ if txmbr is None:
+ self.display.event(name, 'repackaging', bytes, total,
self.complete_actions, self.total_actions)
-
else:
- hdr, rpmloc = h[0], h[1]
- pkgtup = self._dopkgtup(hdr)
- txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
- for txmbr in txmbrs:
- action = txmbr.output_state
- self.display.event(txmbr.po, action, bytes, total,
- self.complete_actions, self.total_actions)
+ action = txmbr.output_state
+ self.display.event(txmbr.po, action, bytes, total,
+ self.complete_actions, self.total_actions)
+
def _unInstStart(self, bytes, total, h):
pass
@@ -475,20 +483,21 @@ class RPMTransaction:
pass
def _unInstStop(self, bytes, total, h):
+ name, txmbr = self._getTxmbr(h)
self.total_removed += 1
self.complete_actions += 1
- if h not in self.installed_pkg_names:
- self.display.filelog(h, TS_ERASE)
+ if name not in self.installed_pkg_names:
+ self.display.filelog(name, TS_ERASE)
action = TS_ERASE
else:
action = TS_UPDATED
- self.display.event(h, action, 100, 100, self.complete_actions,
+ self.display.event(name, action, 100, 100, self.complete_actions,
self.total_actions)
- self._scriptout(h)
+ self._scriptout(name)
if self.test: return # and we're done
- self.ts_done(h, action)
+ self.ts_done(name, action)
def _rePackageStart(self, bytes, total, h):
@@ -501,20 +510,16 @@ class RPMTransaction:
pass
def _cpioError(self, bytes, total, h):
- hdr, rpmloc = h[0], h[1]
- pkgtup = self._dopkgtup(hdr)
- txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
- for txmbr in txmbrs:
+ name, txmbr = self._getTxmbr(h)
+ if txmbr is not None:
msg = "Error in cpio payload of rpm package %s" % txmbr.po
txmbr.output_state = TS_FAILED
self.display.errorlog(msg)
# FIXME - what else should we do here? raise a failure and abort?
def _unpackError(self, bytes, total, h):
- hdr, rpmloc = h[0], h[1]
- pkgtup = self._dopkgtup(hdr)
- txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
- for txmbr in txmbrs:
+ name, txmbr = self._getTxmbr(h)
+ if txmbr is not None:
txmbr.output_state = TS_FAILED
msg = "Error unpacking rpm package %s" % txmbr.po
self.display.errorlog(msg)
@@ -522,35 +527,24 @@ class RPMTransaction:
# right behavior should be
def _scriptError(self, bytes, total, h):
- if not isinstance(h, types.TupleType):
- # fun with install/erase transactions, see rhbz#484729
- h = (h, None)
- hdr, rpmloc = h[0], h[1]
- remove_hdr = False # if we're in a clean up/remove then hdr will not be an rpm.hdr
- if not isinstance(hdr, rpm.hdr):
- txmbrs = [hdr]
- remove_hdr = True
+ # "bytes" carries the failed scriptlet tag,
+ # "total" carries fatal/non-fatal status
+ scriptlet_name = rpm.tagnames.get(bytes, "<unknown>")
+
+ name, txmbr = self._getTxmbr(h)
+ if txmbr is None:
+ package_name = name
else:
- pkgtup = self._dopkgtup(hdr)
- txmbrs = self.base.tsInfo.getMembers(pkgtup=pkgtup)
+ package_name = txmbr.po
- for pkg in txmbrs:
- # "bytes" carries the failed scriptlet tag,
- # "total" carries fatal/non-fatal status
- scriptlet_name = rpm.tagnames.get(bytes, "<unknown>")
- if remove_hdr:
- package_name = pkg
- else:
- package_name = pkg.po
-
- if total:
- msg = ("Error in %s scriptlet in rpm package %s" %
- (scriptlet_name, package_name))
- if not remove_hdr:
- pkg.output_state = TS_FAILED
- else:
- msg = ("Non-fatal %s scriptlet failure in rpm package %s" %
- (scriptlet_name, package_name))
- self.display.errorlog(msg)
- # FIXME - what else should we do here? raise a failure and abort?
+ if total:
+ msg = ("Error in %s scriptlet in rpm package %s" %
+ (scriptlet_name, package_name))
+ if txmbr is not None:
+ txmbr.output_state = TS_FAILED
+ else:
+ msg = ("Non-fatal %s scriptlet failure in rpm package %s" %
+ (scriptlet_name, package_name))
+ self.display.errorlog(msg)
+ # FIXME - what else should we do here? raise a failure and abort?
commit b7b5fda8079f4357fadd71c4fa58f31e5049bdbd
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Fri Feb 25 11:09:46 2011 +0200
Eliminate linear search for package names in callback
We only care if the name has been seen so a set works for the
purpose just as well and is faster.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index 30c9dd3..ecb1129 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -178,7 +178,7 @@ class RPMTransaction:
self.total_actions = 0
self.total_installed = 0
self.complete_actions = 0
- self.installed_pkg_names = []
+ self.installed_pkg_names = set()
self.total_removed = 0
self.logger = logging.getLogger('yum.filelogging.RPMInstallCallback')
self.filelog = False
@@ -426,7 +426,7 @@ class RPMTransaction:
if self.trans_running:
self.total_installed += 1
self.complete_actions += 1
- self.installed_pkg_names.append(hdr['name'])
+ self.installed_pkg_names.add([hdr['name']])
return self.fd.fileno()
else:
self.display.errorlog("Error: No Header to INST_OPEN_FILE")
commit 1dd3de9f7cd871444d0a0f2a29b6c41da2dccecf
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Thu Feb 24 09:16:33 2011 +0200
Remove unnecessary "magic number" test
RPMCALLBACK_TRANS_START is only issued once. That "bytes" happens
to be a magic value of 6 is just an artifact of truly ancient rpm
versions from last century issuing RPMCALLBACK_TRANS_START more than once.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index 06b484a..30c9dd3 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -402,11 +402,10 @@ class RPMTransaction:
def _transStart(self, bytes, total, h):
- if bytes == 6:
- self.total_actions = total
- if self.test: return
- self.trans_running = True
- self.ts_all() # write out what transaction will do
+ self.total_actions = total
+ if self.test: return
+ self.trans_running = True
+ self.ts_all() # write out what transaction will do
def _transProgress(self, bytes, total, h):
pass
commit d9cc803c7b7f2f6ad4ec5b33acbf17435af86051
Author: Panu Matilainen <pmatilai at laiskiainen.org>
Date: Thu Feb 24 08:57:32 2011 +0200
Simplify callback file open/close
There's never more than one active file descriptor at a time so
no need to collect them to a dict, remove now unneeded _makeHandle().
Also use a python file object and return its .fileno() instead of
the lowlevel os-routines.
diff --git a/yum/rpmtrans.py b/yum/rpmtrans.py
index d479829..06b484a 100644
--- a/yum/rpmtrans.py
+++ b/yum/rpmtrans.py
@@ -174,7 +174,7 @@ class RPMTransaction:
self.base = base # base yum object b/c we need so much
self.test = test # are we a test?
self.trans_running = False
- self.filehandles = {}
+ self.fd = None
self.total_actions = 0
self.total_installed = 0
self.complete_actions = 0
@@ -254,12 +254,6 @@ class RPMTransaction:
return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
- def _makeHandle(self, hdr):
- handle = '%s:%s.%s-%s-%s' % (hdr['epoch'], hdr['name'], hdr['version'],
- hdr['release'], hdr['arch'])
-
- return handle
-
def ts_done(self, package, action):
"""writes out the portions of the transaction which have completed"""
@@ -425,18 +419,16 @@ class RPMTransaction:
hdr = None
if h is not None:
hdr, rpmloc = h[0], h[1]
- handle = self._makeHandle(hdr)
try:
- fd = os.open(rpmloc, os.O_RDONLY)
- except OSError, e:
+ self.fd = file(rpmloc)
+ except IOError, e:
self.display.errorlog("Error: Cannot open file %s: %s" % (rpmloc, e))
else:
- self.filehandles[handle]=fd
if self.trans_running:
self.total_installed += 1
self.complete_actions += 1
self.installed_pkg_names.append(hdr['name'])
- return fd
+ return self.fd.fileno()
else:
self.display.errorlog("Error: No Header to INST_OPEN_FILE")
@@ -444,9 +436,8 @@ class RPMTransaction:
hdr = None
if h is not None:
hdr, rpmloc = h[0], h[1]
- handle = self._makeHandle(hdr)
- os.close(self.filehandles[handle])
- fd = 0
+ self.fd.close()
+ self.fd = None
if self.test: return
if self.trans_running:
pkgtup = self._dopkgtup(hdr)
More information about the Yum-commits
mailing list