apt


On a debian linux box the directory /var/cache/apt/archives gradually fills up with every .deb file you have ever installed or have ever downloaded with the option of installing. If a file corresponds to your currently installed version or is currently the most advanced version of that package you have available then you want to keep it, otherwise it’s redundant and may as well be deleted.

For example, let’s say I have 12 versions of bash sitting in that directory; the first 8 are previous versions, the 9th is the installed version, and the last 3 are versions I have downloaded but not gotten to the point of actually installing. In that case I want to keep the 9th and 12th files and delete the other 10.

Here is a perl script that will do exactly that. You could have a nightly script that did

apt-get update
apt-get upgrade --download-only -qq

then ran the following clean up script, then emailed you the list of packages having upgrades available.

#!/usr/bin/perl

use strict;
use warnings;

use Dpkg::Version qw(version_compare);

my %installed = ();

eval {
    my $pid = open(STATUS, '/usr/bin/dpkg-query -l | /bin/grep ^i |')
        or die 'Failed to get package status feed';
    while (defined($_ = )) {
        chomp;
        if (/^\w\w\s+(\S+)\s+(\S+)\s/) {
            $installed{$1} = $2;
        }
        else {
            die 'Unrecognised package status line';
        }
    }
    close(STATUS);
};
if ($@) {
    die "Failed to build list of installed versions\n". $@;
}

my %candidate = ( %installed );

eval {
    my $archive_dir = '/var/cache/apt/archives';
    opendir(AVAIL, $archive_dir)
        or die 'Failed to read archive dir';
    while (defined(my $deb = readdir(AVAIL))) {
        chomp $deb;
        if ($deb =~ /^([^_]+)_([^_]+)_/) {
            my ($p, $v) = ($1, $2);
            $v =~ s/%3a/:/g;
            if (exists $candidate{$p}) {
                my $cmp = version_compare($candidate{$p}, $v);
                if ($cmp  0) {
                    # Found a non-maximal version
                    unlink $deb
                        unless $installed{$p} && $installed{$p} eq $v;
                }
            }
            else {
                $candidate{$p} = $v;
            }
        }
        else {
            warn "Ignoring unrecognised file ($deb)";
        }
    }
    closedir(AVAIL);
};
if ($@) {
    die "Failed to build list of available versions\n". $@;
}

__END__
Advertisements

When you’re using a non-standard repository it’s fairly common to find apt-get complaining about non-verifiable keys.
For example, when using mirror.ourdelta.org I was getting

W: GPG error: http://mirror.ourdelta.org etch Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3EA4DFD8A29A9ED6
W: GPG error: http://archive.debian.org etch Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 9AA38DCD55BE302B NO_PUBKEY B5D0C804ADB11277
W: GPG error: http://archive.debian.org etch/updates Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 9AA38DCD55BE302B
W: GPG error: http://archive.debian.org etch/volatile Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY DFD993306D849617

If you are sure you trust the source, a solution is to use gpg to request the key, then export that into apt.

key=3EA4DFD8A29A9ED6
gpg --keyserver hkp://pgpkeys.mit.edu --recv-keys $key; \
gpg --armor --export $key | apt-key add -

[omit the \ and its linebreak]
then up-arrow to edit for the next key, etc
(I use a variable because it has to be run multiple times, so it speeds up the edits.)

If you are going to continue using the same shell, finish with

unset key

When trying to install packages from a debian archive that’s had a significant update, you sometimes get the error: “WARNING: The following packages cannot be authenticated!”
It is easily remedied via:

apt-get update
apt-get install debian-archive-keyring
apt-get update