Subject: Re: pkg_chk update fallout
To: Hauke Fath <hf@spg.tu-darmstadt.de>
From: Rhialto <rhialto@falu.nl>
List: pkgsrc-users
Date: 10/25/2006 18:03:38
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed 25 Oct 2006 at 16:47:30 +0200, Hauke Fath wrote:
> I am in the middle of upgranding a pkgsrc-2006Q1 installation to 
> pkgsrc-2006Q3, working with pkg_chk 1.81 and binary packages from a 
> local bulk build.

What I usually do, is something like this:

- Make a list of what's installed now. Sometimes I forget this step.
  I have attached a script which creates a list sorted by dependency.
- in a pkg_comp chroot, run pkg_chk -r. This deletes outdated stuff that
  needs to be re-built, and more stuff that depends on it.
- depending on how thorough I want to be in the rebuilds, I move the
  existing, older binary packages out of the way. If I don't do that,
  some of them will be reinstalled if they are not outdated themselves.
  Script attached.
- Then I run pkg_chk -ak, and fix any problems, until everything is
  rebuilt.
- Outside the chroot again, I run pkg_chk -r and pkg_chk -ab.
  Apparently the -b option may be confused if there are different
  versions of the same binary package around. (script attached to fix
  this) It also may not look in the pkgchk.conf file (but just install
  all binary packages in sight), but that doesn't seem to be mentioned
  in the manpage anymore, so maybe it changed.

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert      -- You author it, and I'll reader it.
\X/ rhialto/at/xs4all.nl        -- Cetero censeo "authored" delendum esse.

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=check_installed_binary_packages

#!/bin/sh
#
# Usage: $0 fromdir todir
#
# Moves all binary packages in fromdir that are not installed anymore
# to todir.

fromdir=$1
todir=$2

if [ ! -w $todir ]
then
    echo "Can't write in $todir"
    exit
fi

for f in $(ls $fromdir)
do
    pkg=${f%.tgz}
    if pkg_info -e "$pkg"
    then
	echo $pkg is still installed
    else
	echo $pkg moved to Attic...
	mv "$fromdir/$f" "$todir"
    fi
done

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=move_older_versions_to_attic

#!/bin/sh

fromdir=$1
todir=$2
# fromdir should be an absolute path now, since pkg_admin lsbest prints
# absolute pathnames...

if [ ! -w $todir ]
then
    echo "Can't write in $todir"
    exit
fi

for f in $(ls $fromdir)
do
    # strip version number and .tgz
    pkg=$(echo $f | sed -e 's/-[0-9.]*\(nb[1-9][0-9]*\)\{0,1\}\.tgz$//')
    # If pattern did not match, leave the file alone
    if [ "$pkg" != "$f" ]
    then
	best=$(pkg_admin lsbest $fromdir/$pkg'-[0-9]*')
	if [ "$fromdir/$f" = "$best" ]
	then
	    echo $f is still the best
	else
	    echo $f moved to Attic, $best is best...
	    mv "$fromdir/$f" "$todir"
	fi
    fi
done

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename=sort_installed_binary_packages
Content-Transfer-Encoding: 8bit

#!/usr/pkg/bin/perl

use strict;

my $printdirs = 1;
my $print_toplevel = 0;
my $debug = 0;

my $pkgdbdir = $ENV{PKG_DBDIR} || "/var/db/pkg";

my %name_to_dir;

sub get_all_packages
{
    return map { s|^$pkgdbdir/||; $_ } grep { -d } glob($pkgdbdir."/*");
}

sub open_file
{
    my ($pkg, $file, $parent) = @_;

    my $fullname = "$pkgdbdir/$pkg/$file";
    if (-e $fullname) {
	# ok, nothing special to do
    } else {
	# It turns out that sometimes a dependency is not quite right.
	# In my case, about a dozen packages had installed newer versions
	# than were recorded in dependencies. Sloppy, but it happens.
	# Start guessing...
	my $oldpkg = $pkg;
	print STDERR "Warning: $pkg not found (needed for $parent), ";
	$pkg =~ s/-([0-9.]*)+(nb[0-9]+)?$//;
	print STDERR "best $pkg ";
	$pkg = `pkg_admin -s '' lsbest '$pkgdbdir/$pkg-[0-9]*'`;
	chomp $pkg;
	$pkg =~ s|^$pkgdbdir/||;
	chomp $pkg;
	print STDERR "is $pkg\n";
	$fullname = "$pkgdbdir/$pkg/$file";
    }
    open VERSION, "<", $fullname or die "Cannot open $fullname to read (needed for $parent)";
    return $pkg;
}

sub get_info_for
{
    my $pkg = shift;
    my $parent = shift;

    if (!exists $name_to_dir{$pkg}) {
	# Determine from which directory the package stems
	# Could also be done with pkg_info -Q PKGPATH $pkg, but
	# there is still the issue where not exactly the recorded
	# dependency is installed.
	my $origpkg = $pkg;
	$pkg = open_file($pkg, "+BUILD_VERSION", $parent);
	my $line = <VERSION>;
	close VERSION;

	# get dir/pkg from dir/pkg/Makefile # blah
	chomp $line;
	$line =~ s|^(.*?/.*?)/.*|$1|;

	$name_to_dir{$origpkg} = $line;
	$name_to_dir{$pkg} = $line;
	print STDERR "$pkg  <- $line\n" if $debug;

	# Now get what other packages we need
	open DEPS, "pkg_info -q -N $pkg |";
	my @deps = <DEPS>;
	close DEPS;

	# Go at least once through, with $pkg depending on itself,
	# so that tsort will know about it.
	foreach ($pkg, @deps) {
	    chomp;
	    next if $_ eq "";
	    get_info_for($_, $pkg);

	    my $ppkg = $pkg;
	    my $p_ = $_;
	    if ($printdirs) {
		$p_ = $name_to_dir{$p_};
		$ppkg = $name_to_dir{$ppkg};
	    }
	    print TSORT "$p_ $ppkg\n";
	}
    }
}

my @todo = @ARGV;
@todo = get_all_packages() unless int(@todo);

open TSORT, "| tsort";

foreach my $pkg (@todo) {
    get_info_for($pkg, "*TOP*");
}

close TSORT;

if ($print_toplevel) {
    print "# Top-level packages:\n";
    foreach (@todo) {
	print $name_to_dir{$_}, "\t # ", $_, "\n" 
		if   -d "${pkgdbdir}/$_" && 
		! -e "${pkgdbdir}/$_/+REQUIRED_BY";
    }
}

--uAKRQypu60I7Lcqm--