tech-pkg archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Script pkg_tsort
Hello,
Here is a simple Bourne shell script that takes what is currently
installed on a node, takes the build dependencies and the running
dependencies and produce a series of records in topological order
with the following fields:
pkg_path installed_version vuln_status\
src_version vuln_src_status\
os os_release os_proc_arch
By default, the packages with PRESERVE set (i.e. +PRESERVE file in the
pkg database) are not listed and their _running_ dependencies are
"frozen" i.e. not put in the final listing.
The main use for me is a help when upgrading in order to be able to
launch updating having an idea about what has to be done and what is
about to succeed or not.
The topological sorting is done with NetBSD rcorder(1) that gives as a
bonus dependencies that are not present (typically build dependencies
that one has suppressed).
The vulnerability is tested both for the current packages and for the
source version (i.e. the version in /usr/pkgsrc) so that if one wants to
automate the updating, one knows that one has to set
ALLOW_VULNERABLE_PACKAGES for the updated version that has
vulnerabilities.
I have tried initially to set the version of the packages in /usr/pkgsrc
simply by sed'ing the Makefile. But since there are, in some
packages, a bunch of variables replacements, I had to fall back to
calling "make show-vars": this is what takes the huge majority of
time...
It is a simple script and its purpose is to give informations, upon
which one can make decisions. It does not update anything (Unix
philosophy: pipe programs. It is simple, after that, to select the
packages based on the values in the different fields (it is not magic:
some things are so tangled that a package will refuse to build with an
old frozen version required by a PRESERVE(d) package etc.; but at least
one can sort the things before).
I didn't find the equivalent in existing so it might be of some use for
others.
It does what I intended it to do, but it has been done rapidly and it
could be improved (if the "improvment" is not to try to add "actions"
to it; this would NOT be an improvment).
Cheers,
--
Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
http://www.kergis.com/
http://www.sbfa.fr/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89 250D 52B1 AE95 6006 F40C
#!/bin/sh -e
#$Id: tsort,v 1.1 2019/04/15 14:59:23 tlaronde Exp $
# Gives in topological order informations about all or some installed
# packages for further processing of the records.
#
# C) 2019 Thierry Laronde <tlaronde%polynum.com@localhost>
# BSD 2 clause license.
#
# Requires: NetBSD rcorder(1) and pkg_admin(1).
: ${TMPDIR:=/tmp}
: ${PKGSRCDIR:=/usr/pkgsrc}
usage="$0 [-h] [-c] [pkg...]
Print in topological order the tree of installed packages as
registered in PKG_DBDIR (value retrieved via pkg_admin(1)) with
the build and running dependencies, giving the details of installed
version, status for vulnerabilities, source (PKGSRCDIR retrieved in
environment) version, status of source for vulnerabilities,
installed OS version, release and processor architecture.
Options:
-h print this Help
-c Complete packages. By default, preserved packages are NOT
listed.
"
#========== SUBR
#========== CHECKS
do_complete=NO
pkg_list=
while test $# -gt 0; do
case "$1" in
-h) echo "$usage"; exit 0;;
-c) do_complete=YES;;
*) pkg_list="$pkg_list $1";;
esac
shift
done
# Required.
#
test $(command -v pkg_admin)\
|| { echo "pkg_admin(1) is required!"; exit 2; }
PKG_DBDIR=$(pkg_admin config-var PKG_DBDIR)
tmpdir="$TMPDIR/$$"
#========== PROCESSING: stores
#
mkdir "$tmpdir"
list="$tmpdir/list"
# Take all at first.
#
find "$PKG_DBDIR" -type d -maxdepth 1\
| sed -e "\\!$PKG_DBDIR\$!d" -e "s!$PKG_DBDIR/!!" >"$list"
# Select using regexp if pkg are specified on cmd line.
#
if test "$pkg_list"; then
rm -f "$tmpdir/junk"
for pkg in $pkg_list; do
grep "$pkg" "$list" >>"$tmpdir/junk"
done
mv "$tmpdir/junk" "$list"
fi
mkdir "$tmpdir/pkg"
# If we exclude preserved packages, we need to exclude from update
# their _running_ dependencies.
#
if test $do_complete = NO; then
echo "Looking for PRESERVE(d) dependencies..." >&2
pkg_info | while read pkg junk; do
test -f "$PKG_DBDIR/$pkg/+PRESERVE" || continue
sed -n 's/^@pkgdep \(.*\)-[0-9.]*$/\1/p' "$PKG_DBDIR/$pkg/+CONTENTS" >>"$tmpdir/junk"
done
sort "$tmpdir/junk" | uniq >"$tmpdir/frozen"
echo "Excluding PRESERVE(d) dependencies: " >&2
cat "$tmpdir/frozen" >&2
fi
echo "I will call make to retrieve current variables, so be patient..." >&2
while read pkg junk; do
test do_complete = YES || test ! -f "$PKG_DBDIR/$pkg/+PRESERVE"\
|| continue
name=${pkg%-*}
version=${pkg##*-}
if pkg_admin audit-pkg $pkg >/dev/null 2>&1; then
status=OK
else
status=VULNERABLE
fi
if test -f "$tmpdir/frozen"; then
! fgrep "$name" "$tmpdir/frozen" || continue
fi
pkgpath=$(sed -n 's/^PKGPATH=//p' "$PKG_DBDIR/$pkg/+BUILD_INFO")
uname_s=$(sed -n 's/^OPSYS=//p' "$PKG_DBDIR/$pkg/+BUILD_INFO")
uname_r=$(sed -n 's/^OS_VERSION=//p' "$PKG_DBDIR/$pkg/+BUILD_INFO")
uname_p=$(sed -n 's/^MACHINE_ARCH=//p' "$PKG_DBDIR/$pkg/+BUILD_INFO")
if test -f "$PKGSRCDIR/$pkgpath/Makefile"; then
srcversion=$(cd "$PKGSRCDIR/$pkgpath"; make show-vars VARNAMES=PKGVERSION)
if pkg_admin audit-pkg $name-$srcversion >/dev/null 2>&1; then
srcstatus=OK
else
scrstatus=VULNERABLE
fi
else
srcversion=UNAVAILABLE
srcstatus=UNKNOWN
fi
sed -n 's/^@[a-z]*dep \(.*\)-[0-9.]*[nb0-9]*$/# REQUIRE: \1/p' "$PKG_DBDIR/$pkg/+CONTENTS" >"$tmpdir/junk"
# Fix for xorgproto bunch.
#
if grep "# REQUIRE: .*proto" "$tmpdir/junk" >/dev/null 2>&1; then
ed -s "$tmpdir/junk" <<EOT
g/^# REQUIRE: .*proto/d
a
# REQUIRE: xorgproto
.
w
q
EOT
fi
sort "$tmpdir/junk" | uniq > "$tmpdir/pkg/$name"
echo "# PROVIDE: $name" >>"$tmpdir/pkg/$name"
echo "##PKGINFO: $pkgpath $version $status $srcversion $srcstatus $uname_s $uname_r $uname_p" >>"$tmpdir/pkg/$name"
done <"$list"
# The list is given as is.
# One can use "pkg_info -R pkg" to see what depends upon pkg.
#
cd "$tmpdir/pkg/"
echo "##pkgpath cur_version cur_status src_version src_status cur_OS cur_OS_release cur_OS_procarch"
rcorder * | while read name; do
sed -n 's/^##PKGINFO: //p' "$tmpdir/pkg/$name"
done
rm -fr "$tmpdir"
exit 0
Home |
Main Index |
Thread Index |
Old Index