[yum-cvs] yum-utils/plugins/fedorakmod README, 1.2, 1.3 fedorakmod.py, 1.4, 1.5

Jack Neely slack at linux.duke.edu
Tue Sep 19 15:13:36 UTC 2006


Update of /home/groups/yum/cvs/yum-utils/plugins/fedorakmod
In directory login1.linux.duke.edu:/tmp/cvs-serv25795

Modified Files:
	README fedorakmod.py 
Log Message:
Current fedorakmod pluging work.  Most of the agreed upon functionality
is there and the plugin should be easily extendable.  There seems to
be a Yum bug that's preventing installing a given kmod for all installed
kernels to work properly.  Attempting to track that down.


Index: README
===================================================================
RCS file: /home/groups/yum/cvs/yum-utils/plugins/fedorakmod/README,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- README	5 Jul 2006 17:54:45 -0000	1.2
+++ README	19 Sep 2006 15:13:34 -0000	1.3
@@ -5,11 +5,11 @@
 
 To Do
 =====
-   *) Install kernel modules for all avaliable kernels
+   *) Install kernel modules for all available kernels
    *) Remove kernel modules if matching kernel is removed.
 
 Folks, feel free to patch and add suggestions.  It will only help FE kernel
-module infrastructure develope faster.
+module infrastructure develop faster.
 
 Jack Neely <jjneely at ncsu.edu> -- 07/05/2006
 

Index: fedorakmod.py
===================================================================
RCS file: /home/groups/yum/cvs/yum-utils/plugins/fedorakmod/fedorakmod.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- fedorakmod.py	20 Jul 2006 16:39:54 -0000	1.4
+++ fedorakmod.py	19 Sep 2006 15:13:34 -0000	1.5
@@ -20,9 +20,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-from sets import Set
-
+import os
 import rpmUtils
+from sets import Set
 from yum import packages
 from yum.constants import TS_INSTALL
 from yum.plugins import TYPE_CORE, PluginYumExit
@@ -32,54 +32,53 @@
 
 kernelProvides = Set([ "kernel-%s" % a for a in rpmUtils.arch.arches.keys() ])
         
+def getRunningKernel():
+    # Taken from the installonlyn.py plugin writen by Jeremy Katz
+    # Copyright 2005  Red Hat, Inc. 
+    # Modified by Jack Neely to return a kernel provides tuple
+    """This takes the output of uname and figures out the (version, release)
+    tuple for the running kernel."""
+    ver = os.uname()[2]
+    for s in ("bigmem", "enterprise", "smp", "hugemem", "PAE",
+              "guest", "hypervisor", "xen0", "xenU", "xen"):
+        if ver.endswith(s):
+            ver = ver.replace(s, "")
+    if ver.find("-") != -1:
+        (v, r) = ver.split("-", 1)
+        # XXX: Gah, this assumes epoch
+        return ('kernel-%s' % os.uname()[4], 'EQ', ('0', v, r))
+    return None
 
-def package(c, tuple):
-    rpmdb = c.getRpmDB()
-
-    # XXX: When RPM leaves dup NEVRA's??
-    hdr = rpmdb.returnHeaderByTuple(tuple)[0]
-    po = packages.YumInstalledPackage(hdr)
-    return po
-
-    
-def whatProvides(c, list):
+def _whatProvides(c, list):
     """Return a list of POs of installed kernels."""
 
-    bag = {}
+    bag = []
     
     rpmdb = c.getRpmDB()
     for i in list:
         tuples = rpmdb.whatProvides(i, None, None)
-        for p in tuples:
-            bag[p] = package(c, p)
+        for pkgtuple in tuples:
+            # XXX: what do we do for duplicate packages?
+            #po = rpmdb.packagesByTuple(pkgtuple)[0]
+            po = rpmdb.searchPkgTuple(pkgtuple)[0]
+            bag.append(po)
 
     return bag
 
 
-def getInstalledKernels(c):
-    return whatProvides(c, kernelProvides)
-
-
-def getInstalledModules(c):
-    return whatProvides(c, ["kernel-modules"])
-
-
-def searchByName(packageDict, name):
-    """Returns a list of package tuples who's package name matches the
-       given name."""
+def _getKernelDeps(po, match):
+      
+    reqs = po.returnPrco(match)
+    return [ r for r in reqs if r[0] in kernelProvides ]
+    #return filter(lambda r: r[0] in kernelProvides, reqs)
 
-    list = []
-    for key in packageDict.keys():
-        if key[0] == name:
-            list.append(key)
 
-    return list
+def getInstalledKernels(c):
+    return _whatProvides(c, kernelProvides)
 
 
-def getKernelStuffs(po, match):
-      
-    reqs = po.returnPrco(match)
-    return filter(lambda r: r[0] in kernelProvides, reqs)
+def getInstalledModules(c):
+    return _whatProvides(c, ["kernel-modules"])
 
 
 def getKernelProvides(po):
@@ -87,27 +86,49 @@
        tuples (name, flags, ver) representing any kernel provides.
        Assumed that the PO is a kernel package."""
      
-    return getKernelStuffs(po, "provides")
+    return _getKernelDeps(po, "provides")
 
 
 def getKernelReqs(po):
     """Pass in a package header.  This function will return a list of
        tuples (name, flags, ver) representing any kernel requires."""
       
-    return getKernelStuffs(po, "requires")
+    return _getKernelDeps(po, "requires")
+
+
+def resolveVersions(packageList):
+    """The packageDict is a dict of pkgtuple -> PO
+       We return a dict of kernel version -> list of kmod POs
+          where the list contains only one PO for each kmod name"""
+
+    dict = {}
+    for po in packageList:
+        kernel = getKernelReqs(po)
+        if len(kernel) == 1:
+            kernel = kernel[0]
+        else:
+            print "Bad kmod package: May only require one kernel"
+            continue
 
+        # Figure out the real name of this kmod
+        name = []
+        for r in po.returnPrco("provides"):
+            if r[0].endswith('-kmod'):
+                name.append(r[0])
+        if len(name) != 1:
+            print "Non compliant kmod package: %s" % po
+            continue
+        po.kmodName = name[0]
 
-def mapNameToKernel(packageDict):
-    # name -> (name, flag, (e,v,r)) where name is 'kernel-<arch>'
-    modnames = {}
-    for key in packageDict.keys():
-        kernelReqs = getKernelReqs(packageDict[key])
-        if modnames.has_key(key[0]):
-            modnames[key[0]].extend(kernelReq)
+        if not dict.has_key(kernel):
+            dict[kernel] = [po]
         else:
-            modnames[key[0]] = kernelReqs
+            sameName = [ x for x in dict[kernel] if x.name == po.name ][0]
+            if packages.comparePoEVR(sameName, po) < 0:
+                dict[kernel].remove(sameName)
+                dict[kernel].append(po)
 
-    return modnames
+    return dict
 
 
 def installKernelModules(c, newModules, installedModules):
@@ -117,13 +138,15 @@
 
     tsInfo = c.getTsInfo()
 
-    for modpo in newModules.values():
+    for modpo in newModules:
         c.info(4, "Installing kernel module: %s" % modpo.name)
-    
+        # Should only ever be 1 element to this list
+        te = tsInfo.getMembers(modpo.pkgtup)[0] 
+        tsCheck(te)
+
         kernelReqs = getKernelReqs(modpo)
-        instPkgs = searchByName(installedModules, modpo.name)
-        for pkg in instPkgs:
-            po = installedModules[pkg]
+        instPkgs = filter(lambda p: p.name == modpo.name, installedModules)
+        for po in instPkgs:
             instKernelReqs = getKernelReqs(po)
 
             for r in kernelReqs:
@@ -137,35 +160,63 @@
                     break
 
 
-def pinKernels(c, newKernels, newModules, installedModules):
+def pinKernels(c, newKernels, modules):
     """If we are using kernel modules, do not upgrade/install a new 
        kernel until matching modules are available."""
     
-    if len(newKernels.keys()) == 0:
+    runningKernel = getRunningKernel()
+    if runningKernel == None:
+        c.error(2, "Could not parsing running kernel version.")
         return
 
-    tsInfo = c.getTsInfo()
+    table = resolveVersions(modules)
+    if not table.has_key(runningKernel):
+        # The current kernel has no modules installed
+        return
+        
+    names = [ p.kmodName for p in table[runningKernel] ]
+    for kpo in newKernels:
+        prov = getKernelProvides(kpo)[0]
+        if table.has_key(prov):
+            kmods = [ po.kmodName for po in table[prov] ]
+        else:
+            kmods = []
+        if Set(kmods) != Set(names):
+            c.info(2, "Removing kernel %s from install set" % str(prov))
+            # XXX: This wants a pkgtuple which will probably change RSN
+            c.getTsInfo().remove(kpo.pkgtup)
+
+
+# There is a Yum bug that prevents this from working propperly.
+# c.getRepos().getPackageSack().searchProvides("kernel-modules") does not
+# return packages with fully popluated Provides information
+def installAllKmods(c, avaModules, modules, kernels):
+    list = []
+    names = []
+    interesting = []
 
-    # name -> (name, flag, (e,v,r)) where name is 'kernel-<arch>'
-    installedMap = mapNameToKernel(installedModules)
-    newMap = mapNameToKernel(newModules)
-
-    for kernel in newKernels.keys():
-        # Each kernel should only provide one kernel-<arch>
-        prov = getKernelProvides(newKernels[kernel])[0]
-
-        for name in installedMap:
-            if prov in installedMap[name]:
-                # matching module already installed
-                continue
-            elif newMap.has_key(name) and prov in newMap[name]:
-                # matching module available
-                continue
-            else:
-                # No matching module for new kernel
-                c.info(2, "Removing kernel %s from install set" % str(kernel))
-                tsInfo.remove(kernel)
-                del newKernels[kernel]
+    rModules = resolveVersions(modules)
+    for group in rModules.values():
+        for po in group:
+            if po.kmodName not in names:
+                names.append(po.kmodName)
+
+    rAvaModules = resolveVersions(avaModules)
+    for group in rAvaModules.values():
+        for po in group:
+            if po.kmodName in names:
+                interesting.append(po)
+
+    table = resolveVersions(interesting + modules)
+    
+    for kernel in [ getKernelProvides(k)[0] for k in kernels ]:
+        if not table.has_key(kernel): continue
+        for po in table[kernel]:
+            if po not in modules:
+                c.getTsInfo().addTrueInstall(po)
+                list.append(po)
+
+    return list
 
 
 def tsCheck(te):
@@ -182,8 +233,9 @@
     
 def postresolve_hook(c):
 
-    newModules = {}
-    newKernels = {}
+    avaModules = c.getRepos().getPackageSack().searchProvides("kernel-modules")
+    newModules = []
+    newKernels = []
 
     installedKernels = getInstalledKernels(c)
     installedModules = getInstalledModules(c)
@@ -191,16 +243,27 @@
     for te in c.getTsInfo().getMembers():
         if te.ts_state not in ('i', 'u'):
             continue
-        if "kernel-modules" in te.po.getProvidesNames():
-            tsCheck(te)  # We do this here as I can't get the TE from the PO
-            newModules[te.po.returnPackageTuple()] = te.po
-        if kernelProvides.intersection(te.po.getProvidesNames()) != Set([]):
-            # We have a kernel package
-            newKernels[te.po.returnPackageTuple()] = te.po
+        if "kernel-modules" in te.po.provides_names:
+            newModules.append(te.po)
+            for po in avaModules:
+                if te.po.pkgtup == po.pkgtup:
+                    avaModules.remove(po)
+        if kernelProvides.intersection(te.po.provides_names) != Set([]):
+            newKernels.append(te.po)
+
+    # Install modules for all kernels
+    if c.confInt('main', 'installforallkernels', default=1) != 0:
+        #print "Running installAllKmods()"
+        #moreModules = installAllKmods(c, avaModules, 
+        #                              newModules + installedModules,
+        #                              newKernels + installedKernels)
+        #newModules = newModules + moreModules
+        pass
 
     # Pin kernels
-    if c.confInt('main', 'pinkernels', default=1) is not 0:
-        pinKernels(c, newKernels, newModules, installedModules)
+    if c.confInt('main', 'pinkernels', default=0) != 0:
+        #print "Running pin kernels..."
+        pinKernels(c, newKernels, newModules + installedModules)
 
     # Upgrade/Install kernel modules
     installKernelModules(c, newModules, installedModules)




More information about the Yum-cvs-commits mailing list