[yum-cvs] yum/yum __init__.py, 1.240, 1.241 rpmsack.py, 1.24, 1.25 yumRepo.py, 1.18, 1.19

Menno Smits mjs at linux.duke.edu
Sun Sep 3 21:11:07 UTC 2006


Update of /home/groups/yum/cvs/yum/yum
In directory login1.linux.duke.edu:/tmp/cvs-serv2539/yum

Modified Files:
	__init__.py rpmsack.py yumRepo.py 
Log Message:
Fixes so that CTRL-C finally works properly:
    - rpmdb transactions are only kept open when strictly necessary so that
      SIGINT handler is left alone by rpm during downloads etc
    - added a simple interrupt_callback for package downloads. A single CTRL-C
      will push the download to the next mirror. Two quick CTRL-C's will
      terminate Yum. This needs cleaning up to not upset Yum API clients.


Index: __init__.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/__init__.py,v
retrieving revision 1.240
retrieving revision 1.241
diff -u -r1.240 -r1.241
--- __init__.py	3 Sep 2006 10:21:56 -0000	1.240
+++ __init__.py	3 Sep 2006 21:11:05 -0000	1.241
@@ -231,43 +231,34 @@
            This can't happen in __init__ b/c we don't know our installroot
            yet"""
         
-        if hasattr(self, 'read_ts'):
+        if hasattr(self, 'tsInfo'):
             return
             
         if not self.conf.installroot:
             raise Errors.YumBaseError, 'Setting up TransactionSets before config class is up'
         
-        installroot = self.conf.installroot
-        self.read_ts = rpmUtils.transaction.initReadOnlyTransaction(root=installroot)
         self.tsInfo = self._transactionDataFactory()
-        self.rpmdb = rpmsack.RPMDBPackageSack()
         self.initActionTs()
         
     def doRpmDBSetup(self):
         """sets up a holder object for important information from the rpmdb"""
-        
+
         if not self.localdbimported:
             self.verbose_logger.debug('Reading Local RPMDB')
-            self.rpmdb.ts = self.read_ts
-            self.rpmdb.buildIndexes()
+            self.rpmdb = rpmsack.RPMDBPackageSack(root=self.conf.installroot)
             self.localdbimported = 1
 
     def closeRpmDB(self):
         """closes down the instances of the rpmdb we have wangling around"""
         if hasattr(self, 'rpmdb'):
-            del self.rpmdb
+            self.rpmdb = None
             self.localdbimported = 0
         if hasattr(self, 'ts'):
-            del self.ts.ts
-            del self.ts
-        if hasattr(self, 'read_ts'):
-            del self.read_ts.ts
-            del self.read_ts
+            self.ts = None
         if hasattr(self, 'up'):
-            del self.up
+            self.up = None
         if hasattr(self, 'comps'):
             self.comps.compiled = False
-            
 
     def doRepoSetup(self, thisrepo=None):
         """grabs the repomd.xml for each enabled repository and sets up 
@@ -602,7 +593,7 @@
             else:
                 return 0
 
-        ylp = YumLocalPackage(self.read_ts, fo)
+        ylp = YumLocalPackage(self.rpmdb.readOnlyTS(), fo)
         if ylp.pkgtup != po.pkgtup:
             if raiseError:
                 raise URLGrabError(-1, 'Package does not match intended download')
@@ -792,7 +783,9 @@
             hasgpgkey = not not repo.gpgkey 
         
         if check:
-            sigresult = rpmUtils.miscutils.checkSig(self.read_ts, po.localPkg())
+            ts = self.rpmdb.readOnlyTS()
+            sigresult = rpmUtils.miscutils.checkSig(ts, po.localPkg())
+            ts.close()
             localfn = os.path.basename(po.localPkg())
             
             if sigresult == 0:
@@ -2017,6 +2010,8 @@
         keyurls = repo.gpgkey
         key_installed = False
 
+        ts = rpmUtils.transaction.TransactionWrapper(self.conf.installroot)
+
         for keyurl in keyurls:
             self.logger.info('Retrieving GPG key from %s' % keyurl)
 
@@ -2039,7 +2034,7 @@
                       'GPG key parsing failed: ' + str(e)
 
             # Check if key is already installed
-            if misc.keyInstalled(self.read_ts, keyid, timestamp) >= 0:
+            if misc.keyInstalled(ts, keyid, timestamp) >= 0:
                 self.logger.info('GPG key at %s (0x%s) is already installed' % (
                     keyurl, hexkeyid))
                 continue
@@ -2056,7 +2051,7 @@
                 raise Errors.YumBaseError, "Not installing key"
             
             # Import the key
-            result = self.ts.pgpImportPubkey(misc.procgpgkey(rawkey))
+            result = ts.pgpImportPubkey(misc.procgpgkey(rawkey))
             if result != 0:
                 raise Errors.YumBaseError, \
                       'Key import failed (code %d)' % result
@@ -2076,3 +2071,4 @@
         if result != 0:
             self.logger.info("Import of key(s) didn't help, wrong key(s)?")
             raise Errors.YumBaseError, errmsg
+

Index: rpmsack.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/rpmsack.py,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- rpmsack.py	3 Sep 2006 02:50:05 -0000	1.24
+++ rpmsack.py	3 Sep 2006 21:11:05 -0000	1.25
@@ -22,17 +22,17 @@
 import types
 import warnings
 
-from Errors import PackageSackError
 from rpmUtils import miscutils
+from rpmUtils.transaction import initReadOnlyTransaction
 import misc
 from packages import YumInstalledPackage
 from packageSack import ListPackageSack, PackageSackBase
 
 class RPMDBPackageSack(PackageSackBase):
 
-    def __init__(self, ts=None):
+    def __init__(self, root='/'):
         self.excludes = {}
-        self.ts = ts
+        self.root = root
         self.pkglist = []
         self.dep_table = { 'requires'  : (rpm.RPMTAG_REQUIRENAME,
                                           rpm.RPMTAG_REQUIREVERSION,
@@ -47,13 +47,16 @@
                                           rpm.RPMTAG_OBSOLETEVERSION,
                                           rpm.RPMTAG_OBSOLETEFLAGS)
                            }
-        if self.ts:
-            self.buildIndexes()
+        self.buildIndexes()
+
+    def readOnlyTS(self):
+        return initReadOnlyTransaction(root=self.root)
 
     def buildIndexes(self):
+        ts = self.readOnlyTS()
         self.header_indexes = {}
         
-        mi = self.ts.dbMatch()
+        mi = ts.dbMatch()
         for hdr in mi:
             pkgtuple = self._hdr2pkgTuple(hdr)
             if not self.header_indexes.has_key(pkgtuple):
@@ -64,8 +67,6 @@
         
         self.pkglist = self.header_indexes.keys()
         
-        del mi
-
     def _checkIndexes(self, failure='error'):
         return
 
@@ -73,11 +74,12 @@
         self.excludes[obj.pkgId] = 1
 
     def searchAll(self, name, query_type='like'):
+        ts = self.readOnlyTS()
         result = {}
 
         # check provides
         table = self.dep_table['provides']
-        mi = self.ts.dbMatch()
+        mi = ts.dbMatch()
         mi.pattern(table[0], rpm.RPMMIRE_GLOB, name)
         for hdr in mi:
             pkg = self.makePackageObject(hdr, mi.instance())
@@ -85,6 +87,7 @@
                 result[pkg.pkgid] = pkg
 
         del mi
+        ts.close()
         
         fileresults = self.searchFiles(name)
         for pkg in fileresults:
@@ -95,22 +98,25 @@
 
     def searchFiles(self, name):
         """search the filelists in the rpms for anything matching name"""
-        
+        ts = self.readOnlyTS()
         result = {}
         
-        mi = self.ts.dbMatch('basenames', name)
+        mi = ts.dbMatch('basenames', name)
         for hdr in mi:
             pkg = self.makePackageObject(hdr, mi.instance())
             if not result.has_key(pkg.pkgid):
                 result[pkg.pkgid] = pkg
         del mi
+        ts.close()
         
         return result.values()
         
     def searchPrco(self, name, prcotype):
+        
+        ts = self.readOnlyTS()
         result = {}
         table = self.dep_table[prcotype]
-        mi = self.ts.dbMatch(table[0], name)
+        mi = ts.dbMatch(table[0], name)
         for hdr in mi:
             po = self.makePackageObject(hdr, mi.instance())
             prcotup = (name, None, (None, None, None))
@@ -129,6 +135,7 @@
                         result[pkg.pkgid] = pkg
         
         del mi
+        ts.close()
         
         return result.values()
 
@@ -158,7 +165,6 @@
         if len(self.searchNevra(name=name, arch=arch, epoch=epoch, ver=ver, rel=rel)) > 0:
             return 1
         return 0
-    
 
     def returnNewestByNameArch(self, naTup=None):
 
@@ -169,13 +175,16 @@
         (name, arch) = naTup
         allpkg = []
 
-        mi = self.ts.dbMatch(rpm.RPMTAG_NAME, naTup[0])
+        ts = self.readOnlyTS()
+        mi = ts.dbMatch(rpm.RPMTAG_NAME, naTup[0])
         arch = naTup[1]
         for hdr in mi:
             if hdr[rpm.RPMTAG_ARCH] == arch:
                 allpkg.append(self._hdr2pkgTuple(hdr))
         
         del mi
+        ts.close()
+
         if not allpkg:
             # FIXME: raise  ...
             print 'No Package Matching %s' % name
@@ -185,7 +194,9 @@
         if not name:
             return
 
-        allpkg = self.mi2list(self.ts.dbMatch(rpm.RPMTAG_NAME, name))
+        ts = self.readOnlyTS()
+        allpkg = self.mi2list(ts.dbMatch(rpm.RPMTAG_NAME, name))
+        ts.close()
         if not allpkg:
             # FIXME: raise  ...
             print 'No Package Matching %s' % name
@@ -264,8 +275,8 @@
             returnList.append(self.makePackageObject(hdr, mi.instance()))
         return returnList
 
-    def hdrByindex(self, index):
-        mi = self.ts.dbMatch(0, index)
+    def hdrByindex(self, ts, index):
+        mi = ts.dbMatch(0, index)
         hdr = mi.next()
         return hdr
     
@@ -273,10 +284,11 @@
     
         """return YumInstalledPackage objects in a list for each index in the list"""
         all = []
+        ts = self.readOnlyTS()
         for idx in indexlist:
-            hdr  = self.hdrByindex(idx)
+            hdr  = self.hdrByindex(ts, idx)
             all.append(self.makePackageObject(hdr, idx))
-        
+        ts.close()
         return all
 
     def _hdr2pkgTuple(self, hdr):
@@ -304,11 +316,13 @@
         warnings.warn('getHdrList() will go away in a future version of Yum.\n',
                 DeprecationWarning, stacklevel=2)
     
+        ts = self.readOnlyTS()
         hdrlist = []
         for pkg in self.header_indexes.keys():
             for idx in self.header_indexes[pkg]:
-                hdr = self.hdrByindex(idx)
+                hdr = self.hdrByindex(ts, idx)
                 hdrlist.append(hdr)
+        ts.close()
         return hdrlist
 
     def getNameArchPkgList(self):
@@ -370,11 +384,8 @@
         return []
         
     def addDB(self, ts):
-        warnings.warn('addDB()() will go away in a future version of Yum.\n',
-                DeprecationWarning, stacklevel=2)
-    
-        self.ts = ts
-        self.buildIndexes()
+        # Can't support this now
+        raise NotImplementedError
 
     def whatProvides(self, name, flags, version):
         """searches the rpmdb for what provides the arguments

Index: yumRepo.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/yumRepo.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- yumRepo.py	2 Sep 2006 07:47:27 -0000	1.18
+++ yumRepo.py	3 Sep 2006 21:11:05 -0000	1.19
@@ -165,6 +165,7 @@
         self.storage = storagefactory.GetStorage()
         self.sack = self.storage.GetPackageSack()
 
+        self.last_interrupt_time = None
 
     def __getProxyDict(self):
         self.doProxyDict()
@@ -319,6 +320,7 @@
                                    progress_obj=self.callback,
                                    proxies = self.proxy_dict,
                                    failure_callback=self.failure_obj,
+                                   interrupt_callback=self.interrupt_callback,
                                    timeout=self.timeout,
                                    http_headers=headers,
                                    reget='simple')
@@ -327,6 +329,26 @@
         self.grab = mgclass(self.grabfunc, self.urls,
                             failure_callback=self.mirror_failure_obj)
 
+    def interrupt_callback(self, cb):
+        '''Handle CTRL-C's during downloads
+
+        If a CTRL-C occurs a URLGrabError will be raised to push the download
+        onto the next mirror.  
+        
+        If two CTRL-C's occur in quick succession then yum will exit.
+
+        @param cb: urlgrabber callback obj
+        '''
+        now = time.time()
+        if self.last_interrupt_time:
+            if now - self.last_interrupt_time < 0.2:
+                # Two quick CTRL-C's, quit
+                raise KeyboardInterrupt
+
+        # Go to next mirror
+        self.last_interrupt_time = now
+        raise URLGrabError(15, 'user interrupt')
+
     def dirSetup(self):
         """make the necessary dirs, if possible, raise on failure"""
 
@@ -428,6 +450,7 @@
                             reget = reget,
                             proxies = self.proxy_dict,
                             failure_callback = self.failure_obj,
+                            interrupt_callback=self.interrupt_callback,
                             timeout=self.timeout,
                             checkfunc=checkfunc,
                             http_headers=headers,




More information about the Yum-cvs-commits mailing list