[Thincrust-devel] [PATCH appliance-tools 3/3] image-minimizer: add droprpm/keeprpm

apevec at gmail.com apevec at gmail.com
Tue Jul 27 00:22:54 UTC 2010


From: Alan Pevec <apevec at redhat.com>

Currently supported keywords by image-minimizer are:
drop <file path pattern>
keep <file path pattern>

specifying which part of the filesystem to remove during image creation.

Example usage:
%post --nochroot --interpreter image-minimizer
drop /usr/lib/libboost*
keep /usr/lib/libboost_program_options.so*
keep /usr/lib/libboost_filesystem.so*
keep /usr/lib/libboost_thread-mt.so*
keep /usr/lib/libboost_system.so*
drop /usr/kerberos
keep /usr/kerberos/bin/kinit
keep /usr/kerberos/bin/klist
%end

Following keywords are added by this patch:
droprpm <rpm name pattern>
keeprpm <rpm name pattern>

<rpm name pattern> is glob-style pattern using fnmatch:
name*   match all packages which name starts with "name"
!name*  match all packages which name does not start with "name"

Example usage:
%post --nochroot --interpreter image-minimizer
droprpm perl-*
keeprpm perl-libs
%end

Installation root (--installroot option) must be specified when
droprpm/keeprpm commands are used, to avoid accidental system damage.
---
 tools/image-minimizer |   55 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/tools/image-minimizer b/tools/image-minimizer
index 18f19f9..321cfd8 100755
--- a/tools/image-minimizer
+++ b/tools/image-minimizer
@@ -1,8 +1,8 @@
 #!/usr/bin/python
 #
-# imageminimizer: removes files on the filesystem
+# image-minimizer: removes files and packages on the filesystem
 #
-# Copyright 2007, Red Hat  Inc.
+# Copyright 2007-2010 Red Hat  Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ import optparse
 import os
 import shutil
 import sys
+import rpm
 
 class ImageMinimizer:
     filename = ''
@@ -30,12 +31,16 @@ class ImageMinimizer:
     keeps = set()
     drops = set()
     visited = set()
+    keeps_rpm = set()
+    drops_rpm = set()
+    ts = None
 
     def __init__(self, filename, root, dryrun, verbose):
         self.filename = filename
         self.prefix = root
         self.dryrun = dryrun
         self.verbose = verbose
+        self.ts = None
 
     # Recursively adds all files and directories.
     # This is done becuase globbing does not allow
@@ -50,18 +55,34 @@ class ImageMinimizer:
 
     def add_pattern(self, files, pattern):
         globs = glob.glob(pattern)
+        if self.verbose and len(globs) == 0:
+            print "%s file not found" % pattern
         for g in globs:
             if os.path.isdir(g):
                 self.add_directory(files, g)
             else:
                 files.add(g)
 
+    def add_pattern_rpm(self, rpms, pattern):
+        if self.ts is None:
+            if self.prefix is None:
+                raise Exception ('Must specify installation root for droprpm/keeprpm')
+            self.ts = rpm.TransactionSet(self.prefix)
+        mi = self.ts.dbMatch()
+        mi.pattern('name', rpm.RPMMIRE_GLOB, pattern)
+        not_found = True
+        for hdr in mi:
+            not_found = False
+            rpms.add(hdr['name'])
+        if self.verbose and not_found:
+            print "%s package not found" % pattern
+
     # Parses each line in the ifle
     def parse_line(self, line):
         tup = line.partition(' ')
         command = tup[0].lower()
-        pattern = tup[2].strip()
-        if not self.prefix == None:
+        pattern = pattern_orig = tup[2].strip()
+        if self.prefix is not None:
             pattern = pattern.lstrip('/')
             pattern = os.path.join(self.prefix, pattern)
 
@@ -71,6 +92,10 @@ class ImageMinimizer:
                 self.add_pattern(self.keeps, pattern)
             elif command == 'drop':
                 self.add_pattern(self.drops, pattern)
+            elif command == 'keeprpm':
+                self.add_pattern_rpm(self.keeps_rpm, pattern_orig)
+            elif command == 'droprpm':
+                self.add_pattern_rpm(self.drops_rpm, pattern_orig)
             else:
                 raise Exception ('Unknown Command: ' + command)
 
@@ -97,11 +122,31 @@ class ImageMinimizer:
                         print 'rm -rf ' + dir
                     os.rmdir(dir)
 
+    def remove_rpm(self, rpms):
+
+        def runCallback(reason, amount, total, key, client_data):
+            if self.verbose and reason == rpm.RPMCALLBACK_UNINST_STOP:
+                print key, "erased"
+
+        if len(rpms) == 0:
+            return
+
+        for pkg in rpms:
+            if self.dryrun:
+                print "erasing ", pkg
+            else:
+                self.ts.addErase(pkg)
+        if not self.dryrun:
+            # skip ts.check(), equivalent to --nodeps
+            self.ts.run(runCallback, "erase")
+
     def filter(self):
         for line in (open(self.filename).readlines()):
             self.parse_line(line.strip())
         final = self.drops.difference(self.keeps)
         self.remove(final)
+        final_rpm = self.drops_rpm.difference(self.keeps_rpm)
+        self.remove_rpm(final_rpm)
 
 
 def parse_options():
@@ -111,7 +156,7 @@ def parse_options():
     parser.set_defaults(root=os.environ.get('INSTALL_ROOT'), dry_run=False)
 
     parser.add_option("-i", "--installroot", type="string", dest="root",
-        help="Root path to prepend to all patterns. Defaults to INSTALL_ROOT")
+        help="Root path to prepend to all file patterns and installation root for RPM operations.  Defaults to INSTALL_ROOT")
 
     parser.add_option("--dryrun", action="store_true", dest="dryrun",
         help="If set, no filesystem changes are made.")
-- 
1.7.1.1




More information about the Thincrust-devel mailing list