[Yum] [PATCH 3 of 4] purge local packages no longer in repo

Daniel P. Berrange berrange at redhat.com
Wed May 30 18:06:39 UTC 2007


When tracking a bleeding edge repository like Fedora rawhide, existing
packages in a repo will be updated on a regular basis, removing the older
versions. This leaves large numbers of obsolete packages in the locally
synced directory which are never cleaned up. This patch adds a --delete
argument which instructs reposync to unlink any packages in the local
directory which are no longer present in the remote repository.

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r 9f422acb69fa reposync.py
--- a/reposync.py	Wed May 30 12:58:02 2007 -0400
+++ b/reposync.py	Wed May 30 13:34:40 2007 -0400
@@ -22,8 +22,6 @@
 #     make it work with mirrorlists (silly, really)
 #     man page/more useful docs
 #     deal nicely with a package changing but not changing names (ie: replacement)
-#     maybe have it iterate the dir, if it exists, and delete files not listed
-#     in a repo
 
 # criteria
 # if a package is not the same and smaller then reget it
@@ -35,6 +33,7 @@ import os
 import os
 import sys
 import shutil
+import stat
 
 from optparse import OptionParser
 from urlparse import urljoin
@@ -64,6 +63,24 @@ class RepoSync(yum.YumBase):
         yum.YumBase.__init__(self)
         self.logger = logging.getLogger('yum.verbose.reposync')
         self.opts = opts
+
+def localpkgs(dir):
+    names = os.listdir(dir)
+
+    cache = {}
+    for name in names:
+        fn = os.path.join(dir, name)
+        try:
+            st = os.lstat(fn)
+        except os.error:
+            continue
+        if stat.S_ISDIR(st.st_mode):
+            subcache= localpkgs(fn)
+            for pkg in subcache.keys():
+                cache[pkg] = subcache[pkg]
+        elif stat.S_ISREG(st.st_mode) and name.endswith(".rpm"):
+            cache[name] = { 'path': fn, 'size': st.st_size, 'device': st.st_dev }
+    return cache
 
 def parseArgs():
     usage = """
@@ -84,6 +101,8 @@ def parseArgs():
         help="directory in which to store metadata")
     parser.add_option("-t", "--tempcache", default=False, action="store_true", 
         help="Use a temp dir for storing/accessing yum-cache")
+    parser.add_option("-d", "--delete", default=False, action="store_true",
+        help="delete local packages no longer present in repository")
     parser.add_option("-p", "--download_path", dest='destdir', 
         default=os.getcwd(), help="Path to download packages to: defaults to current dir")
     parser.add_option("-g", "--gpgcheck", default=False, action="store_true",
@@ -155,19 +174,32 @@ def main():
     my.doRepoSetup()
     my.doSackSetup(rpmUtils.arch.getArchList(opts.arch))
     
-    download_list = []
-    
-
     for repo in my.repos.listEnabled():
-        local_repo_path = opts.destdir + '/' + repo.id
-            
         reposack = ListPackageSack(my.pkgSack.returnPackages(repoid=repo.id))
-            
+
         if opts.newest:
             download_list = reposack.returnNewestByNameArch()
         else:
             download_list = list(reposack)
-        
+
+        local_repo_path = opts.destdir + '/' + repo.id
+        if opts.delete and os.path.exists(local_repo_path):
+            current_pkgs = localpkgs(local_repo_path)
+
+            download_set = {}
+            for pkg in download_list:
+                remote = pkg.returnSimple('relativepath')
+                rpmname = os.path.basename(remote)
+                download_set[rpmname] = 1
+
+            for pkg in current_pkgs:
+                if download_set.has_key(pkg):
+                    continue
+
+                if not opts.quiet:
+                    my.logger.info("Removing obsolete %s", pkg)
+                os.unlink(current_pkgs[pkg]['path'])
+
         download_list.sort(sortPkgObj)
         n = 0
         for pkg in download_list:


More information about the Yum mailing list