[lorax] Add removekmod template command

Brian C. Lane bcl at redhat.com
Thu Mar 5 01:28:40 UTC 2015


removekmod GLOB [GLOB...] --allbut KEEPGLOB [KEEPGLOB...]

This can be used to remove kernel modules from under
/lib/modules/*/kernel/ while keeping specific items. This should be
easier than constructing find arguments to select the right things to
save.
---
 share/runtime-cleanup.tmpl | 34 ++++++++---------------
 src/pylorax/ltmpl.py       | 67 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/share/runtime-cleanup.tmpl b/share/runtime-cleanup.tmpl
index 5fed1a5..4c0627f 100644
--- a/share/runtime-cleanup.tmpl
+++ b/share/runtime-cleanup.tmpl
@@ -75,32 +75,20 @@ remove /var/lib/rpm/* /var/lib/yum
 remove /usr/share/icons/*/icon-theme.cache
 
 ## clean up kernel modules
-<%
-removekmods = """
-sound drivers/media drivers/hwmon drivers/video
-net/atm net/bluetooth net/sched net/sctp
-net/rds net/l2tp net/decnet net/netfilter net/ipv4 net/ipv6
-drivers/watchdog drivers/target drivers/rtc drivers/input/joystick
-drivers/bluetooth drivers/hid drivers/edac drivers/staging
-drivers/usb/serial drivers/usb/host drivers/usb/misc
-fs/ocfs2 fs/ceph fs/nfsd fs/ubifs fs/nilfs2
-arch/x86/kvm
-"""
-%>
-%for kmodpath in removekmods.split():
-    remove lib/modules/*/kernel/${kmodpath}
-%endfor
-remove lib/modules/*/{build,source,*.map}
+removekmod sound drivers/media drivers/hwmon drivers/video \
+           net/atm net/bluetooth net/sched net/sctp \
+           net/rds net/l2tp net/decnet net/netfilter net/ipv4 net/ipv6 \
+           drivers/watchdog drivers/target drivers/rtc drivers/input/joystick \
+           drivers/bluetooth drivers/hid drivers/edac drivers/staging \
+           drivers/usb/serial drivers/usb/host drivers/usb/misc \
+           fs/ocfs2 fs/ceph fs/nfsd fs/ubifs fs/nilfs2 \
+           arch/x86/kvm
 ## Need to keep virtio_console.ko and ipmi stuff in drivers/char
 ## Also keep virtio-rng so that the installer can get sufficient randomness for
 ## LUKS setup.
-runcmd chroot ${root} find /lib/modules \
-                        -regex ".*/kernel/drivers/char/.*" \
-                        \! -name virtio_console.ko\* \
-                        \! -name hw_random \
-                        \! -name virtio-rng.ko\* \
-                        \! -name ipmi\* \
-                        -delete
+removekmod drivers/char --allbut virtio_console hw_random \
+                                  virtio-rng ipmi
+remove lib/modules/*/{build,source,*.map}
 ## NOTE: depmod gets re-run after cleanup finishes
 
 ## remove unused themes, theme engines, icons, etc.
diff --git a/src/pylorax/ltmpl.py b/src/pylorax/ltmpl.py
index f3f2b56..a8ad2cb 100644
--- a/src/pylorax/ltmpl.py
+++ b/src/pylorax/ltmpl.py
@@ -597,12 +597,75 @@ class LoraxTemplateRunner(object):
             remove_files = matches
         # remove the files
         if remove_files:
-            logger.debug("%s: removed %i/%i files, %ikb/%ikb", cmd,
+            logger.debug("removefrom %s: removed %i/%i files, %ikb/%ikb", cmd,
                              len(remove_files), len(filelist),
                              self._getsize(*remove_files)/1024, self._getsize(*filelist)/1024)
             self.remove(*remove_files)
         else:
-            logger.debug("%s: no files to remove!", cmd)
+            logger.debug("removefrom %s: no files to remove!", cmd)
+
+    def removekmod(self, *globs):
+        '''
+        removekmod GLOB [GLOB...] [--allbut] KEEPGLOB [KEEPGLOB...]
+          Remove all files and directories matching the given file globs from the kernel
+          modules directory.
+
+          If '--allbut' is used, all the files from the modules will be removed *except*
+          the ones which match the file globs. There must be at least one initial GLOB
+          to search and one KEEPGLOB to keep. The KEEPGLOB is expanded to be *KEEPGLOB*
+          so that it will match anywhere in the path.
+
+          This only removes files from under /lib/modules/*/kernel/
+
+          Examples:
+            removekmod sound drivers/media drivers/hwmon drivers/video
+            removekmod drivers/char --allbut virtio_console hw_random
+        '''
+        cmd = " ".join(globs)
+        if "--allbut" in globs:
+            idx = globs.index("--allbut")
+            if idx == 0:
+                raise ValueError("removekmod needs at least one GLOB before --allbut")
+
+            # Apply keepglobs anywhere they appear in the path
+            keepglobs = globs[idx+1:]
+            if len(keepglobs) == 0:
+                raise ValueError("removekmod needs at least one GLOB after --allbut")
+
+            globs = globs[:idx]
+
+            # --allbut needs the full list of files to match keepglobs against, gather up every
+            # file under each glob pattern's results.
+            filelist = set()
+            for g in globs:
+                for top_dir in rglob(self._out("/lib/modules/*/kernel/"+g)):
+                    for root, _dirs, files in os.walk(top_dir):
+                        filelist.update(root+"/"+f for f in files)
+
+            # Remove anything matching keepglobs from the list
+            matches = set()
+            for g in keepglobs:
+                globs_re = re.compile(fnmatch.translate("*"+g+"*"))
+                m = filter(globs_re.match, filelist)
+                if m:
+                    matches.update(m)
+                else:
+                    logger.debug("removekmod %s: no files matched!", g)
+            remove_files = filelist.difference(matches)
+        else:
+            # Gather glob matches, the full list isn't needed since it will recursively remove
+            # directory matches.
+            keepglobs = []
+            filelist = set()
+            for g in globs:
+                filelist.update(rglob(self._out("/lib/modules/*/kernel/"+g)))
+            remove_files = filelist
+
+        if remove_files:
+            logger.debug("removekmod: %s", remove_files)
+            map(remove, remove_files)
+        else:
+            logger.debug("removekmod %s: no files to remove!", cmd)
 
     def createaddrsize(self, addr, src, dest):
         '''
-- 
2.1.0



More information about the anaconda-patches mailing list