Tim Lauridsen wrote:
seth vidal wrote:
writing a program that downloads pkgs and runs the transaction w/o
duplicating a bunch of code from cli.doTransaction(). this clearly needs
to be fixed.

The standard operating set:

1. download pkgs
2. sig check pkgs
3. test transaction
4. rpm_check_debug transaction
5. ts.check()
6. ts.order()
7. self.runTransaction(cb)

yes, this needs to be much simpler.

-sv


_______________________________________________
Yum-devel mailing list
Yum-devel@linux.duke.edu
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel
Yes, it sucks, and there is even more step for the time you have populates self.tsInfo with the actions you want to perform.

1. Solve dependencies.
2. Ask the user for confimation.
3. Download packages.
4. Check signatures.
5 Ask user for gpg key import confimation if needed.
6. Do a test transaction
7. Do the real transaction

But how do we make it better ?.
Add a generic 'processTransaction' to YumBaseCli with some kind of callback, so it can be extended ??
See the attached pseudo kode.

Tim


------------------------------------------------------------------------

_______________________________________________
Yum-devel mailing list
Yum-devel@linux.duke.edu
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel
I have made a prof of concept to how it could work.

Tim
diff --git a/yum/__init__.py b/yum/__init__.py
index 33a0e76..ec0ee1b 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -51,6 +51,7 @@ warnings.simplefilter("ignore", Errors.YumFutureDeprecationWarning)
 
 from packages import parsePackages, YumAvailablePackage, YumLocalPackage, YumInstalledPackage
 from constants import *
+from yum.rpmtrans import RPMTransaction,SimpleCliCallBack
 
 __version__ = '3.2.2'
 
@@ -2166,3 +2167,137 @@ class YumBase(depsolve.Depsolve):
                             numleft -= 1
                         
         map(lambda x: self.tsInfo.addErase(x), toremove)
+
+    def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
+        '''
+        Process the current Transaction
+        - Download Packages
+        - Check GPG Signatures.
+        - Run Test RPM Transaction
+        - Run RPM Transaction
+        
+        callback.event method is called at start/end of each process.
+        
+        @param callback: callback object (must have an event method)
+        @param rpmTestDisplay: Name of display class to use in RPM Test Transaction 
+        @param rpmDisplay: Name of display class to use in RPM Transaction 
+        '''
+        
+        action = "Download Packages"
+        if callback: callback.event(action=action, state="Start")
+        pkgs = self._downloadPackages()
+        if callback: callback.event(action=action, state="End")
+        action = "Checking Signatures"
+        if callback: callback.event(action=action, state="Start")
+        self._checkSignatures(pkgs)
+        if callback: callback.event(action=action, state="End")
+        action = "Test Transaction"
+        if callback: callback.event(action=action, state="Start")
+        self._doTestTransaction(display=rpmTestDisplay)
+        if callback: callback.event(action=action, state="End")
+        action = "Run Transaction"
+        if callback: callback.event(action=action, state="Start")
+        self._doTransaction(display=rpmDisplay)
+        if callback: callback.event(action=action, state="End")
+    
+    def _downloadPackages(self):
+        ''' Download the need packages in the Transaction '''
+        # This can be overloaded by a subclass.    
+        dlpkgs = map(lambda x: x.po, filter(lambda txmbr:
+                                            txmbr.ts_state in ("i", "u"),
+                                            self.tsInfo.getMembers()))
+           
+        try:
+            probs = self.downloadPkgs(dlpkgs)
+
+        except IndexError:
+            raise yum.Errors.YumBaseError, ["Unable to find a suitable mirror."]
+        if len(probs.keys()) > 0:
+            errstr = ["Errors were encountered while downloading packages."]
+            for key in probs.keys():
+                errors = yum.misc.unique(probs[key])
+                for error in errors:
+                    errstr.append("%s: %s" %(key, error))
+
+            raise yum.Errors.YumBaseError, errstr
+        return dlpkgs
+
+    def _checkSignatures(self,pkgs):
+        ''' The the signatures of the downloaded packages '''
+        # This can be overloaded by a subclass.    
+        for po in pkgs:
+            result, errmsg = self.sigCheckPkg(po)
+            if result == 0:
+                # Verified ok, or verify not req'd
+                continue            
+            elif result == 1:
+               self.getKeyForPackage(po, self._askForGPGKeyImport)
+            else:
+                raise yum.Errors.YumBaseError, errmsg
+
+        return 0
+        
+    def _askForGPGKeyImport(self, po, userid, hexkeyid):
+        ''' 
+        Ask for GPGKeyImport 
+        This need to be overloaded in a subclass to make GPG Key import work
+        '''
+        return False
+
+    def _doTestTransaction(self,display=None):
+        ''' Do the RPM test transaction '''
+        # This can be overloaded by a subclass.    
+        if self.conf.rpm_check_debug:
+            self.verbose_logger.log(logginglevels.INFO_2, 
+                 'Running rpm_check_debug')
+            msgs = self._run_rpm_check_debug()
+            if msgs:
+                retmsgs = ['ERROR with rpm_check_debug vs depsolve:']
+                retmsgs.extend(msgs) 
+                retmsgs.append('Please report this error in bugzilla')
+                raise yum.Errors.YumBaseError,retmsgs
+        
+        tsConf = {}
+        for feature in ['diskspacecheck']: # more to come, I'm sure
+            tsConf[feature] = getattr( self.conf, feature )
+        #
+        testcb = RPMTransaction(self, test=True)
+        # overwrite the default display class
+        if display:
+            testcb.display = display
+        # clean out the ts b/c we have to give it new paths to the rpms 
+        del self.ts
+  
+        self.initActionTs()
+        # save our dsCallback out
+        dscb = self.dsCallback
+        self.dsCallback = None # dumb, dumb dumb dumb!
+        self.populateTs( keepold=0 ) # sigh
+        tserrors = self.ts.test( testcb, conf=tsConf )
+        del testcb
+  
+        if len( tserrors ) > 0:
+            errstring =  'Test Transaction Errors: '
+            for descr in tserrors:
+                 errstring += '  %s\n' % descr 
+            raise yum.Errors.YumBaseError, errstring 
+
+        del self.ts
+        # put back our depcheck callback
+        self.dsCallback = dscb
+
+
+    def _doTransaction(self,display=None):
+        ''' do the RPM Transaction '''
+        # This can be overloaded by a subclass.    
+        self.initActionTs() # make a new, blank ts to populate
+        self.populateTs( keepold=0 ) # populate the ts
+        self.ts.check() # required for ordering
+        self.ts.order() # order
+        cb = RPMTransaction(self,display=SimpleCliCallBack)
+        # overwrite the default display class
+        if display:
+            cb.display = display
+        self.runTransaction( cb=cb )
+
+        
from utils import YumUtilBase
import output

class ProcessTransactionCallback:
    ''' 
    callback class for YumBase.processTransaction
    the event method is called for every step in the process
    it can be overloaded by subclass the want do some other action
    '''

    def __init__(self):
        pass
        
    def event(self,action = None, state = None):
        print '%s %s' % (state,action)

name = 'test'
ver  = '0.1'
usage = 'test [options] [args]'

yb = YumUtilBase(name,ver,usage)
yb.doUtilConfigSetup()
txmbr = yb.install(name='BasiliskII')
if txmbr:
    print "Installing : %s" % str(txmbr[0].po)
    rc,msgs =  yb.buildTransaction() 
    if rc !=2:
        print "Dep Errors"
        print "\n".join(msgs)
    else:
        try:
            yb.processTransaction(callback=ProcessTransactionCallback(),
                                  rpmDisplay=output.YumCliRPMCallBack())
        except yum.Errors.YumBaseError, msgs:
            print "Error in Transaction Processing"
            print "\n".join(msgs)
        
else:
    print "nothing to do"
_______________________________________________
Yum-devel mailing list
Yum-devel@linux.duke.edu
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to