[yum-cvs] yum-utils/plugins/fedorakmod README, 1.1, 1.2 fedorakmod.conf, 1.1, 1.2 fedorakmod.py, 1.2, 1.3

Jack Neely slack at linux.duke.edu
Wed Jul 5 17:54:47 UTC 2006


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

Modified Files:
	README fedorakmod.conf fedorakmod.py 
Log Message:
Refactor so that additional functionality can easily be added in.
Implement pinning of kernels based on availability of kernel modules.


Index: README
===================================================================
RCS file: /home/groups/yum/cvs/yum-utils/plugins/fedorakmod/README,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- README	13 Feb 2006 20:21:05 -0000	1.1
+++ README	5 Jul 2006 17:54:45 -0000	1.2
@@ -5,11 +5,11 @@
 
 To Do
 =====
-   *) Install kernel module for all avaliable kernels
-   *) Pin kernel until modules for new kernel are available
+   *) Install kernel modules for all avaliable 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.
 
-Jack Neely <jjneely at gmail.com> -- 2/13/2006
+Jack Neely <jjneely at ncsu.edu> -- 07/05/2006
 

Index: fedorakmod.conf
===================================================================
RCS file: /home/groups/yum/cvs/yum-utils/plugins/fedorakmod/fedorakmod.conf,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- fedorakmod.conf	13 Feb 2006 20:21:05 -0000	1.1
+++ fedorakmod.conf	5 Jul 2006 17:54:45 -0000	1.2
@@ -1,2 +1,3 @@
 [main]
 enabled = 1
+pinkernels = 1

Index: fedorakmod.py
===================================================================
RCS file: /home/groups/yum/cvs/yum-utils/plugins/fedorakmod/fedorakmod.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- fedorakmod.py	3 Jul 2006 21:28:40 -0000	1.2
+++ fedorakmod.py	5 Jul 2006 17:54:45 -0000	1.3
@@ -21,6 +21,7 @@
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 import rpm
+from sets import Set
 
 from rpmUtils.miscutils import *
 from yum import packages
@@ -30,7 +31,7 @@
 requires_api_version = '2.4'
 plugin_type = (TYPE_CORE,)
 
-kernelProvides = ["kernel-%s" % a for a in rpmUtils.arch.arches.keys()]
+kernelProvides = Set([ "kernel-%s" % a for a in rpmUtils.arch.arches.keys() ])
         
 
 def flagToString(flags):
@@ -75,40 +76,141 @@
     return po
 
 
+def package(c, tuple):
+    rpmdb = c.getRpmDB()
+
+    # XXX: When RPM leaves dup NEVRA's??
+    hdr = rpmdb.returnHeaderByTuple(tuple)[0]
+    po = packages.YumInstalledPackage(hdr)
+    populatePrco(po, hdr)
+
+    return po
+
+    
+def whatProvides(c, list):
+    """Return a list of POs of installed kernels."""
+
+    bag = {}
+    
+    rpmdb = c.getRpmDB()
+    for i in list:
+        tuples = rpmdb.whatProvides(i, None, None)
+        for p in tuples:
+            bag[p] = package(c, p)
+
+    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."""
+
+    list = []
+    for key in packageDict.keys():
+        if key[0] == name:
+            list.append(key)
+
+    return list
+
+
+def getKernelStuffs(po, match):
+      
+    reqs = po.returnPrco(match)
+    return filter(lambda r: r[0] in kernelProvides, reqs)
+
+
+def getKernelProvides(po):
+    """Pass in a package header.  This function will return a list of
+       tuples (name, flags, ver) representing any kernel provides.
+       Assumed that the PO is a kernel package."""
+     
+    return getKernelStuffs(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."""
       
-    reqs = po.returnPrco("requires")
-    return filter(lambda r: r[0] in kernelProvides, reqs)
+    return getKernelStuffs(po, "requires")
 
 
-def handleKernelModule(c, modpo):
-    """Figure out what special magic needs to be done to install/upgrade
-       this kernel module."""
+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)
+        else:
+            modnames[key[0]] = kernelReqs
 
-    # XXX: Lets try to fix this up so we don't need RPM header objects
+    return modnames
+
+
+def installKernelModules(c, newModules, installedModules):
+    """Figure out what special magic needs to be done to install/upgrade
+       this kernel module.  This doesn't actually initiate an install
+       as the module is already in the package sack to be applied."""
 
-    rpmdb = c.getRpmDB()
     tsInfo = c.getTsInfo()
+
+    for modpo in newModules.values():
+        c.info(4, "Installing kernel module: %s" % modpo.name)
+    
+        kernelReqs = getKernelReqs(modpo)
+        instPkgs = searchByName(installedModules, modpo.name)
+        for pkg in instPkgs:
+            po = installedModules[pkg]
+            instKernelReqs = getKernelReqs(po)
+
+            for r in kernelReqs:
+                if r in instKernelReqs:
+                    # we know that an incoming kernel module requires the
+                    # same kernel as an already installed moulde of the
+                    # same name.  "Upgrade" this module instead of install.
+                    tsInfo.addErase(po)
+                    c.info(2, 'Removing kernel module %s upgraded to %s' %
+                           (po, modpo))
+                    break
+
+
+def pinKernels(c, newKernels, newModules, installedModules):
+    """If we are using kernel modules, do not upgrade/install a new 
+       kernel until matching modules are available."""
     
-    kernelReqs = getKernelReqs(modpo)
-    instPkgs = rpmdb.returnTupleByKeyword(name=modpo.name)
-    for pkg in instPkgs:
-        hdr = rpmdb.returnHeaderByTuple(pkg)[0] # Assume no dup NAEVRs
-        po = packages.YumInstalledPackage(hdr)
-        populatePrco(po, hdr)
-        instKernelReqs = getKernelReqs(po)
-
-        for r in kernelReqs:
-            if r in instKernelReqs:
-                # we know that an incoming kernel module requires the
-                # same kernel as an already installed moulde of the
-                # same name.  "Upgrade" this module instead of install.
-                tsInfo.addErase(po)
-                c.info(2, 'Removing kernel module %s upgraded to %s' %
-                       (po, modpo))
-                break
+    if len(newKernels.keys()) == 0:
+        return
+
+    tsInfo = c.getTsInfo()
+
+    # 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]
 
 
 def tsCheck(te):
@@ -118,19 +220,34 @@
         te.ts_state = 'i'
         te.output_state = TS_INSTALL
 
-    
+
 def init_hook(c):
     c.info(3, "Loading Fedora Extras kernel module support.")
 
     
 def postresolve_hook(c):
 
+    newModules = {}
+    newKernels = {}
+
+    installedKernels = getInstalledKernels(c)
+    installedModules = getInstalledModules(c)
+
     for te in c.getTsInfo().getMembers():
         if te.ts_state not in ('i', 'u'):
             continue
         if "kernel-modules" in te.po.getProvidesNames():
-            c.info(4, "Handling kernel module: %s" % te.name)
-            tsCheck(te)
-            handleKernelModule(c, te.po)
+            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
+
+    # Pin kernels
+    if c.confInt('main', 'pinkernels', default=1) is not 0:
+        pinKernels(c, newKernels, newModules, installedModules)
+
+    # Upgrade/Install kernel modules
+    installKernelModules(c, newModules, installedModules)
            
 # vim:ts=4:expandtab 




More information about the Yum-cvs-commits mailing list