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

"Daniel P. Berrange" <[email protected]>
Newsgroups gmane.linux.rpm.yum
Message-ID <[email protected]>
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  -=|

_______________________________________________
Yum mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum
yum-utils-1.1.4-delete-obsolete.patch (text/plain, 3.2 KB)
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:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.