Date: Tue, 28 Nov 2000 17:34:52 +0100 From: Stijn Hoop <stijn@win.tue.nl> To: Garrett Wollman <wollman@khavrinen.lcs.mit.edu> Cc: ports@freebsd.org Subject: Re: Upgrade hack idea Message-ID: <20001128173452.A94211@pcwin002.win.tue.nl> In-Reply-To: <200011272051.PAA96852@khavrinen.lcs.mit.edu>; from wollman@khavrinen.lcs.mit.edu on Mon, Nov 27, 2000 at 03:51:56PM -0500 References: <200011272051.PAA96852@khavrinen.lcs.mit.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
--oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, On Mon, Nov 27, 2000 at 03:51:56PM -0500, Garrett Wollman wrote: > I just did an upgrade from libpng.so.3 to libpng.so.4 on one of my > machines. I did not want to recompile the client applications, and I > did want to keep some record of the installation of this library and > its dependencies so I remember to delete it when I do recompile those > clients. > > I went through the following steps, which seem to be fairly > automatable, and would make a nice script hack (on the level of > `save_shared_libraries png-1.0.5 png-compat-1.0.5'). [snip procedure] I took your idea and automated it. Attached is my updateport script that takes these exact steps. Before running it, you need to create ${PREFIX}/lib/compat (for the port, this usually means /usr/X11R6 and /usr/local) and add it to /etc/rc.conf in the ${ldconfig_path} variable. The one thing this script doesn't do: it doesn't handle updating dependencies at the same time. So if port #1 depends on an update of port #2, and you run portupdate port #1, you'll *install* the new version of port #2, not update it. You'd have to run updateport port #2 first. I suppose this idea really needs to be in bsd.port.mk, but the script is older than your idea, I just updated it and thought that this could be handy for others. It could also be updated to use Maxim's new information in /var/db/pkg as to the origin of a package, but I don't have the right bsd.port.mk now so I couldn't test that. For now it guesses the old version of a port from the information in /var/db/pkg. Note that I only tested it with your shared library idea *ONCE* on print/gnomeprint, upgraded from under gnumeric. This worked like a charm but YMMV of course. Warning, alpha quality code, here be dragons, etc. Regards, --Stijn --oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=updateport #!/bin/sh # ---------------------------------------------------------------------------- # "THE BEER-WARE LICENSE" (Revision 42): # <stijn@win.tue.nl> wrote this file. As long as you retain this notice you # can do whatever you want with this stuff. If we meet some day, and you think # this stuff is worth it, you can buy me a beer in return. Stijn Hoop # ---------------------------------------------------------------------------- # Global settings PORTSDIR=/usr/ports PKGDBDIR=/var/db/pkg COMPATLIBDIR=lib/compat # Check arguments if [ -z "$1" ]; then echo "Usage: $0 <port-to-upgrade>" echo echo "For example:" echo " $0 misc/screen" exit 1 fi if [ ! -d "${PORTSDIR}/$1" ]; then echo "===> Error: ${PORTSDIR}/$1 not found. Stop." exit 1 fi # Figure out the upgrade path echo "===> Determining installed port version for $1" cd $PORTSDIR/$1 || exit 1 PORTNAME=`make -V PKGNAMEPREFIX``make -V PORTNAME``make -V PKGNAMESUFFIX` OLDVERSION=`ls -d ${PKGDBDIR}/${PORTNAME}-[0-9]* 2>/dev/null | \ sed "s/^.*-\(.*\)$/\1/"` if [ -z $OLDVERSION ]; then echo "===> No old version of $PORTNAME installed." exit 1 fi OLDNAME=${PORTNAME}-${OLDVERSION} NEWVERSION=`make -V PORTVERSION``make -V _SUF1``make -V _SUF2` NEWNAME=`make -V PKGNAME` if [ $NEWNAME = $OLDNAME ]; then echo "===> ${PORTNAME} is up to date (at version $OLDVERSION)." exit 2 fi # For shared library compatability PREFIX=`make -V PREFIX` COMPATNAME=${PORTNAME}-compat-${OLDVERSION} # Figure out if the port installs shared libraries if [ ! -z `make -V INSTALLS_SHLIB` ]; then SHLIB_SAVE= # Determine upgraded libraries NEWLIBS=`grep '\.so\.' pkg-plist | sort` for i in $NEWLIBS; do NEWLIBNAME=`echo $i | sed "s/\.[0-9][0-9]*$//"` NEWLIBVERSION=`echo $i | sed "s/^.*\.\([0-9][0-9]*\)$/\1/"` OLDLIBNAME=`grep "$NEWLIBNAME\." \ ${PKGDBDIR}/${OLDNAME}/+CONTENTS` OLDLIBVERSION=`echo ${OLDLIBNAME} | \ sed "s/^.*\.\([0-9][0-9]*\)$/\1/"` if [ ! -z $OLDLIBVERSION ]; then if [ $OLDLIBVERSION != $NEWLIBVERSION ]; then # An incompatible shared library version SHLIB_SAVE="${SHLIB_SAVE} ${OLDLIBNAME}" fi fi done # Now determine libraries that aren't in the new port anymore, and # save them too OLDLIBS=`grep '\.so\.' ${PKGDBDIR}/${OLDNAME}/+CONTENTS | sort` for i in $OLDLIBS; do OLDLIBNAME=`echo $i | sed "s/\.[0-9][0-9]*$//"` if ! grep $OLDLIBNAME pkg-plist >/dev/null; then SHLIB_SAVE="${SHLIB_SAVE} $i" fi done else SHLIB_SAVE= fi # Ask for confirmation for now, this script is still not well tested. echo "===> Upgrading ${OLDNAME} to ${NEWNAME}" if [ ! -z "$SHLIB_SAVE" ]; then echo " WARNING: this will upgrade shared libraries, which other" echo " programs may depend on! Doing this automatically is not" echo " always guaranteed to yield usable results." fi read -p "===> Are you sure you want to do this? [y/n] " ANS if [ "x$ANS" != "xyes" -a "x$ANS" != "xy" ]; then echo "===> Upgrade cancelled." exit 1; fi # Save the old package metadata for later use cp -rp ${PKGDBDIR}/${OLDNAME} ${PKGDBDIR}/${COMPATNAME} if [ ! -z "$SHLIB_SAVE" ]; then # Build a new +CONTENTS for the compat package, containing # just the shared libraries. CONTENTS=`mktemp -t updateport` if [ $? -ne 0 ]; then echo "$0: Can't create temporary file." exit 1 fi echo "@name ${COMPATNAME}" >> $CONTENTS echo "@cwd ${PREFIX}" >> $CONTENTS for i in $SHLIB_SAVE; do cp -p ${PREFIX}/$i ${PREFIX}/${COMPATLIBDIR} echo $i | sed "s#lib/#${COMPATLIBDIR}/#" >> $CONTENTS echo "@comment MD5:"`md5 -q ${PREFIX}/$i` >> $CONTENTS done echo "@unexec ldconfig -R" >> $CONTENTS mv -f $CONTENTS ${PKGDBDIR}/${COMPATNAME}/+CONTENTS chmod a+r ${PKGDBDIR}/${COMPATNAME}/+CONTENTS ldconfig -m ${PREFIX}/${COMPATLIBDIR} fi # Upgrade the port (building it if necessary) make || exit 1 pkg_delete -f ${OLDNAME} || exit 1 make install || exit 1 # Update dependencies echo "===> Updating dependencies from ${OLDNAME} to ${NEWNAME}" if [ -e ${PKGDBDIR}/${COMPATNAME}/+REQUIRED_BY ]; then if [ -z "$SHLIB_SAVE" ]; then # Let's just hope we are binary compatible... REPLACE=${NEWNAME} else # Change the dependencies to use compat package REPLACE=${COMPATNAME} fi for i in `cat ${PKGDBDIR}/${COMPATNAME}/+REQUIRED_BY`; do if [ -e ${PKGDBDIR}/$i/+CONTENTS ]; then perl -pi -e "s/${OLDNAME}/${REPLACE}/g" \ ${PKGDBDIR}/$i/+CONTENTS fi done if [ -z "$SHLIB_SAVE" ]; then cp ${PKGDBDIR}/${COMPATNAME}/+REQUIRED_BY \ ${PKGDBDIR}/${REPLACE}/+REQUIRED_BY fi fi # Remove the compat 'package' if we're not installing a new shared library if [ -z "$SHLIB_SAVE" ]; then rm -rf ${PKGDBDIR}/${COMPATNAME} else echo "===> The old shared libraries (if any) were saved in a" echo " compatability 'package' named ${COMPATNAME} for" echo " your convenience." fi --oyUTqETQ0mS9luUI-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001128173452.A94211>