Package: apt-cacher
Version: 1.7.3
Severity: normal
Tags: patch

apt-cacher-cleanup.pl is the Perl script used by apt-cacher to clean the
cache: it updates Packages and Sources index files and removes obsolete
.deb files; it is usually run daily or weekly by cron and has a command
line option to update files by patching (using diff files from the Debian
archive).

Nowadays all my clients using the apt-cacher proxy rely on the "InRelease"
file for the top level hash sums catalog of index files in the archive; the
old "Release" file, i.e. the one with detached gpg signature, is not
downloaded any more and then it does not get cached by the proxy.

    # ls /var/cache/apt-cacher/packages/ | grep Release
    debian_dists_testing_InRelease
    debian_dists_unstable_InRelease

The proxy works correctly, it keeps package index files and diff files in
the cache and serves them to its clients.  When, instead, it comes to
cleaning the cache and the above mentioned script is run in "patch mode"
("-p" command line option) it is not able to patch index files if the old
fashioned "Release" file is not present.  It completely ignores the
contents of "InRelease" files and relies only on the old format.

This causes a second problem: the cache ends up having not up to date index
files and then the cleaning script removes some .deb package files even when
they are still actual.  The next client that needs them has to get them
downloaded again.  Even if from the point of view of the client's "apt-get"
everything still works fine this behavior is sub optimal and makes a caching
proxy less useful.

The attached "apt-cacher-cleanup.log" contains the complete output of a
simulation run.  Here is an excerpt with the parts that are significant to
this bug:

    [...]
    Attempting to update debian_dists_testing_contrib_binary-amd64_Packages.bz2 
by patching
    GET /debian/dists/testing/Release
    debian_dists_testing_Release not available, aborting patch
    Patching failed or not possible
    [many similar error lines...]
    Building source package file/version table
    Removing file: debian/libnetpbm10_10.0-15+b1_amd64.deb and company...
    Removing file: debian/netpbm_10.0-15+b1_amd64.deb and company...
    Removing expired headers: debian/libnetpbm10_10.0-15+b1_amd64.deb and 
company...
    Removing expired headers: debian/netpbm_10.0-15+b1_amd64.deb and company...

As you can see the version of the package that is going to be removed is
not obsolete by any means:

    # apt-show-versions -a netpbm
    netpbm 2:10.0-15+b1 install ok installed
    netpbm 2:10.0-15+b1 testing  ftp.de.debian.org
    netpbm 2:10.0-15+b1 unstable ftp.de.debian.org
    netpbm/testing uptodate 2:10.0-15+b1

On the contrary, if I let the proxy get the "Release" file in its cache
(for example downloading it with wget) then all the error messages about
failed patching disappear and .deb files do not get deleted.

The solution that I propose (for which a patch is attached) is to simply
modify the cache cleaning script apt-cacher-cleanup.pl to use the
"InRelease" file to verify hash sums when patching.

Attachment: apt-cacher-cleanup.log.gz
Description: Binary data

--- /usr/share/apt-cacher/apt-cacher-cleanup.pl	2012-02-18 17:01:43.000000000 +0100
+++ /usr/local/bin/apt-cacher-cleanup-2.pl	2012-04-18 10:24:15.123830145 +0200
@@ -188,7 +188,7 @@
 	return;
     }
     my ($basename,$type) = ($name =~ /(^.+?)(\.(?:bz2|gz))?$/);
-    (my $release = $basename) =~ s/(?:main|contrib|non-free).*$/Release/;
+    (my $release = $basename) =~ s/(?:main|contrib|non-free).*$/InRelease/;
     (my $diffindex = $basename) .= '.diff_Index';
 
     for ($release, $diffindex) {

Reply via email to