Modern Update System
David Woodhouse
dwmw2 at infradead.org
Tue Nov 29 15:30:51 UTC 2005
On Mon, 2005-11-28 at 19:13 -0500, Benjy Grogan wrote:
> Is there any work being done for a modern update system that would
> only download what is needed instead of an entirely new rpm?
One trick I've had moderate success with is to extract the RPM payload
(on the remote end) into a cpio file. Then create a cpio file locally
using the contents of the old package, and rsync the new cpio using the
old cpio as seed. Once that's done, recompress (using 'minigzip -9' so
that it precisely matches what RPM does) and then use that as seed for
rsyncing the RPM itself, just to get the header.
#!/bin/sh
export RSYNC_RSH=`which ssh`
REMOTETMPDIR=/tmp/getrpm-`hostname`-$$
LOCALTMPDIR=/tmp/getrpm-$$
REMOTEHOST=$1
if ! minigzip < /dev/null > /dev/null; then
echo "minigzip not found. We need it to match rpm's compression"
echo "Get the rpm source, build its minigzip using its zlib."
echo "Stick it on your PATH somewhere"
exit 1
fi
if [ -z $REMOTEHOST ]; then
echo "Usage: $0 <remotehost> <rpm> [<rpm> ...]"
exit 1
fi
if ! mkdir $LOCALTMPDIR; then
echo "Cannot create temp directory $LOCALTMPDIR"
exit 1
fi
if ! pushd $LOCALTMPDIR > /dev/null ; then
echo "Change to local temporary directory failed";
exit 1
fi
mkdir rpms
if ! ssh $REMOTEHOST mkdir $REMOTETMPDIR; then
echo "Failed to create temp directory $REMOTETMPDIR on $REMOTEHOST"
rmdir $LOCALTMPDIR
exit 1
fi
shift
for PACKAGE in $* ; do
if ! ssh $REMOTEHOST rpm -qp --queryformat="%{NAME}" $PACKAGE > packagename; then
echo "Package listing for $REMOTEHOST:$PACKAGE failed"
continue;
fi
PACKAGENAME=`cat packagename`
if [ -z $PACKAGENAME ]; then
echo "Error: No package name although command succeeded"
continue;
fi
if rpm -ql $PACKAGENAME > files 2>/dev/null; then
echo "Package $PACKAGENAME is currently installed. Using existing files as seed"
cpio -Hnewc -o < files > $PACKAGENAME.cpio 2>/dev/null
if ! ssh $REMOTEHOST rpm2cpio $PACKAGE \> $REMOTETMPDIR/$PACKAGENAME.cpio; then
echo "Error: rpm2cpio of $REMOTEHOST:$PACKAGE failed"
continue;
fi
if ! rsync -vz --progress $REMOTEHOST:$REMOTETMPDIR/$PACKAGENAME.cpio $PACKAGENAME.cpio; then
echo "rsync of $PACKAGENAME.cpio failed"
rm $PACKAGENAME.cpio
continue
fi
ssh $REMOTEHOST rm $REMOTETMPDIR/$PACKAGENAME.cpio
echo -n "Compressing $PACKAGENAME.cpio..."
minigzip -9 $PACKAGENAME.cpio
echo "done."
mv $PACKAGENAME.cpio.gz `basename $PACKAGE`
if ! rsync -vz --progress $REMOTEHOST:$PACKAGE `basename $PACKAGE` ; then
echo "rsync failed"
rm `basename $PACKAGE`
continue
fi
mv `basename $PACKAGE` rpms
else
echo "Package $PACKAGENAME not installed. Copying whole package"
scp $REMOTEHOST:$PACKAGE rpms
fi
done
rm -f packagename *.cpio files
ssh $REMOTEHOST "rm -f $REMOTETMPDIR/*.cpio ; rmdir $REMOTETMPDIR"
popd
mv $LOCALTMPDIR/rpms/*.rpm .
rmdir $LOCALTMPDIR/rpm
--
dwmw2
More information about the fedora-devel-list
mailing list