Last week was hectic for me and I finally got around to not just making the
changes, but testing them too. I didn't know 'upgrade()' existed and now that
I've messed with it, I really like it. Instead of just being compatible with
the new package_changed_files(), any changes that are made are now committed at
the very end. So... you can modify files, one after another, and if you make a
mistake, just answer no at the end. I also updated expandpath() mainly because
of $PKGROOT always being///, or was it ////? Boy I hated that. You still end up
with //some.file because that's just what happens when the top dir is a slash;
which could be changed (eg., $PKGROOT$afile, ${PKGROOT}literal.file), but,
that's being too picky....I would like to get this committed soon. If anyone
wants to test, please give it a try. Just make sure your busybox has 'readlink'.
--- apkg.orig 2014-09-18 23:20:09.000000000 -0700
+++ apkg 2014-10-24 13:38:52.851202831 -0700
@@ -6,20 +6,38 @@
# Upgrade code by Cedric Schieli
# Rundiff code and various improvements by Paul Traina
# Package dependency loading code by David M Brooke
-#
+# Package_changed_files() now backs up symbolic links and
+# empty directories; more detailed rundiff(); upgrade() now
+# prompts before committing changes and other enhancements;
+# changed expandpath by Jorge Contreras
+#
# Licensed under the terms of the GPL-2
# ---------------------------------------------------------
-# expandpath - given a path, expand it
-# code from apkg by David Douthitt
-expandpath () {
- local D=$(dirname $1)
- if `echo "$D" | grep -v "^/" > /dev/null`; then
- [ `dirname $1` = "." ] && D=$PWD || D=$PWD/$(dirname $1)
+# expandpath - given a path, expand it; does not expect a valid path;
+# if available `readlink -m /some/path` is best, but that will canonicalize
+# symlinks, which is not always desired. Now get's rid of redundant slashes
+# (eg., ///dir1/dir2) and accepts null paths.
+# code from apkg by David Douthitt - Modified by Jorge Contreras
+expandpath() {
+
+ if [ "$1" = "" ] || [ "$1" = "." ]; then
+ echo $PWD
+ elif [ "$1" = "/" ]; then
+ echo "/"
+ else
+ local DN=$(dirname $1 | sed 's#//*#/#g')
+ if $(echo "$1" | grep -v "^/" > /dev/null); then
+ [ "$DN" = "." ] && \
+ echo $PWD/$(basename $1) || \
+ echo $PWD/$DN/$(basename $1)
+ else
+ echo $DN/$(basename $1)
fi
- echo $D/$(basename $1)
- }
+ fi
+
+}
# ---------------------------------------------------------
@@ -200,24 +218,46 @@
# figure out which files have changed from this package
package_changed_files () {
- local tmp
+ local tmp upgrade fullpkg NL tmpdir mktmpd s_syms s_dirs s_files
tmp=$TMP/$SESSIONID.sha1
+ tmpdir=$TMP/$SESSIONID.tar
+ # Hackish way of dealing with upgrades and symlinks
+ if [ "$1" = "-u" ]; then
+ upgrade=1; fullpkg=$2; SHIFT 2
+ fi
(
cd $PKGROOT
echo > $tmp
-
+ NL="
+"
for pkg in $@ ; do
- if [ -f $PKGDIR/$pkg.local ]; then
- for a in $(find $(cat $PKGDIR/$pkg.local) -type f 2>/dev/null); do
- ! grep -h "[ /]${a}\$" $PKGDIR/*.sha1 >>$tmp 2>/dev/null && \
- echo "0000000000000000000000000000000000000000 ${a}" >>$tmp
- done
- fi
+ if [ -f $PKGDIR/$pkg.local ] ; then
+ for a in $(find $(cat $PKGDIR/$pkg.local) 2>/dev/null); do
+ if [ -L $a ] ; then
+ [ "$mktmpd" != "1" ] && mkdir $tmpdir && mktmpd=1
+ [ "$upgrade" != 1 ] && fullpkg=$STORAGE_MEDIA/$pkg.lrp
+ # if symlink doesn't exist or if it changed
+ if ! tar xzf $fullpkg -C $tmpdir $a 2>/dev/null || \
+ [ "$(readlink $a)" != "$(readlink $tmpdir/$a)" ] ; then
+ s_syms=$s_syms"$a"$NL
+ fi
+ elif [ -d $a ] ; then
+ # Only add empty directories, non-empty dirs are always
backed up
+ if ! [ "$(ls -A $a)" ] ; then
+ s_dirs=$s_dirs"$a"$NL
+ fi
+ elif [ -f $a ] ; then
+ ! grep -h "[ /]${a}\$" $PKGDIR/*.sha1 >>$tmp 2>/dev/null
&& \
+ echo "0000000000000000000000000000000000000000 ${a}"
>>$tmp
+ fi
+ done
+ [ "$mktmpd" = "1" ] && rm -rf $tmpdir && mktmpd=0
+ fi
done
-
- sha1sum -c $tmp 2>/dev/null | grep FAILED | sed -e "s/: FAILED//" | \
- sort | uniq
+
+ s_files=$(sha1sum -c $tmp 2>/dev/null | grep FAILED | sed -e "s/:
FAILED//")
+ echo "$s_syms$s_dirs$s_files" | sort | uniq
)
rm -f $tmp
@@ -225,13 +265,23 @@
}
# ---------------------------------------------------------
+# upg_cmdins - inserts a command into the upgrade script
+
+upg_cmdins() {
+
+ if [ -n $1 ]; then
+ echo "$@ && [ \$? -ne 0 ] && upgexit=\$?" >> $do_upgrade
+ fi
+}
+
+# ---------------------------------------------------------
# upgrade - upgrades a package
upgrade () {
- local pkg pth
+ local pkg pth commit do_upgrade automated opt upgexit
if [ -z "$1" ]; then
- echo "No package name given." ; return 1
+ echo "No package name given."; return 1
fi
pth=$( makeFN $1 )
@@ -239,71 +289,121 @@
if [ -z "$pkg" ]; then
echo "No package name given."; return 1
- fi
- if ! list_pkgs "$pkg" >/dev/null; then
+ elif ! list_pkgs "$pkg" >/dev/null; then
echo "$pkg not installed."; return 1
- fi
- if [ ! -f "$pth" ]; then
+ elif ! [ -f "$pth" ]; then
echo "$pth not found."; return 1
fi
# ok, its there, installed... let's upgrade it...
(
- if [ -f $PKGDIR/$pkg.local ]; then
- package_changed_files $pkg >$TMP/$SESSIONID.changed
+ commit=0
+ [ "$2" = "1" ] && automated=1 || automated=0
+
+ do_upgrade=$TMP/$SESSIONID.ucmds
+ # Does the OUTDATED, running package have a .local file?
+ if [ -f $PKGDIR/$pkg.local ]; then
mkdir $TMP/$SESSIONID.tmpdir
cd $TMP/$SESSIONID.tmpdir
tar -zxpf $pth $LRPKG/$pkg.local
+ # Does the UPDATED, non-running package also have a .local file?
if [ -f $LRPKG/$pkg.local ] ; then
+ package_changed_files -u $pth $pkg >$TMP/$SESSIONID.changed
+
tar -zxpf $pth -T $LRPKG/$pkg.local
+
+ if [ $automated = 1 ]; then
+ # Abort if update type is "freshen" and config files have
changed
+ for file in $(cat $TMP/$SESSIONID.changed); do
+ test -f $file && \\
+ echo "$pkg freshen failed - config file(s) are
changed, try manual freshen" && \\
+ return 1
+ done
+ fi
+
tar -ztf $pth >$LRPKG/$pkg.list
find $(cat $LRPKG/$pkg.local) -type f | \
xargs sha1sum > $LRPKG/$pkg.sha1
- # remove local files that have not changed from
- # the installed version of this package
- rm -f $(cat $PKGDIR/$pkg.sha1 | sed '/ -/d' | \
- sha1sum -c 2>/dev/null | grep OK | sed 's/: OK$//')
-
+ # If changes are detected, merge/replace changed or added
+ # config files, symlinks, and empty directories
for file in $(cat $TMP/$SESSIONID.changed); do
- if [ "$2" = 1 ]; then
- test -f $file && echo "$pkg upgrade failed -
config file(s) are changed, try manual upgrade" && return 1
+ if [ -L $file ]; then
+ while [ 1 ]; do
+ echo -e "\nModified symbolic link:" $(echo
$PKGROOT/$file | sed 's#//#/#g')
+ echo "Current:" $(basename $PKGROOT/$file)
"->" $(readlink $PKGROOT/$file)
+ echo "Updated:" $(basename $PKGROOT/$file)
"->" $(readlink $file)
+ echo -n -e "\nKeep/Replace? (k/r)"
+ read opt
+ case $opt in k|K)
+ break ;;
+ r|R)
+ upg_cmdins mv $file $PKGROOT/$file
+ break ;;
+ esac
+ done
+ elif [ -d $file ]; then
+ test -d $PKGROOT/$file && \
+ upg_cmdins rmdir $PKGROOT/$file
+ upg_cmdins mv $file $PKGROOT/$file
+ elif [ -f $file ]; then
+ apkg.merge $PKGROOT $PWD $file
+ test -f $file && upg_cmdins mv $file $PKGROOT/$file
fi
-
- test -f $file && apkg.merge $PKGROOT . $file
- test -f $file && mv $file $PKGROOT/$file
done
- tar -zxpf $pth -X $TMP/$SESSIONID.changed -C $PKGROOT
- mv $LRPKG/$pkg.list $PKGDIR
- mv $LRPKG/$pkg.sha1 $PKGDIR
- else
- tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list
- create_sha1 $pkg
+ upg_cmdins tar -zxpf $pth -X $TMP/$SESSIONID.changed -C $PKGROOT
+ upg_cmdins mv $LRPKG/$pkg.list $PKGDIR
+ upg_cmdins mv $LRPKG/$pkg.sha1 $PKGDIR
+
+ else # No .local
+ upg_cmdins tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list
+ upg_cmdins rm -f $PKGDIR/$pkg.local $PKGDIR/$pkg.sha1
fi
else
- tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list
- create_sha1 $pkg
+ upg_cmdins tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list
+ upg_cmdins create_sha1 $pkg
fi
- )
- if [ $? -eq 0 ]; then
- echo "$pkg upgraded"
- # process any package dependencies by recursively calling install()...
- deplist=""
- if [ -f $PKGDIR/$pkg.deplrp ] ; then
- for deplrp in `cat $PKGDIR/$pkg.deplrp` ; do
- [ -f "$PKGDIR/$deplrp.list" ] || deplist="$deplist $deplrp"
- done
- fi
- [ -n "$deplist" ] && echo "Required packages that are missed: $deplist"
- return 0
+
+ upgexit=0
+
+ if [ $automated = 1 ]; then
+ . $do_upgrade
else
- return $?
+ while [ 1 ]; do
+ read -p "Commit changes? (y/n)" opt
+ case $opt in y|Y)
+ commit=1
+ . $do_upgrade
+ break ;;
+ n|N)
+ break ;;
+ esac
+ done
+ fi
+
+ if [ $commit = 1 ]; then
+ if [ $upgexit -eq 0 ]; then
+ echo "$pkg upgraded."
+ # Display list of dependencies...
+ deplist=""
+ if [ -f $PKGDIR/$pkg.deplrp ] ; then
+ for deplrp in `cat $PKGDIR/$pkg.deplrp` ; do
+ [ -f "$PKGDIR/$deplrp.list" ] || deplist="$deplist $deplrp"
+ done
+ fi
+ [ -n "$deplist" ] && echo "Required packages that are missed:
$deplist"
+ return 0
+ else
+ echo "one or more errors while processing updates."
+ return $upgexit
+ fi
fi
+ )
}
# ---------------------------------------------------------
@@ -407,7 +507,7 @@
#
rundiff () {
- local backup_path vs_saved saved changed interest lrp
+ local backup_path vs_saved saved changed interest lrp run_sym sav_sym
vs_saved=$1
if [ ! -f $BACKUP_PATH/$configdb.lrp ] ; then
@@ -442,14 +542,32 @@
interest=$(for file in $interest ; do echo $file ; done | sort | uniq)
for file in $interest ; do
- if [ ! -f running/$file ] ; then
- echo "*** $file has been deleted"
+ if [ -L running/$file ] ; then
+ run_sym=$(readlink running/$file)
+ sav_sym=$(readlink $vs_saved/$file)
+ if [ "$run_sym" != "" ] && [ "$sav_sym" = "" ]; then
+ echo "*** $file is NEW symbolic link"
+ elif [ "$run_sym" != "$sav_sym" ]; then
+ echo "*** $file is MODIFIED symbolic link"
+ fi
+ elif [ -d running/$file ] ; then
+ if ! [ -d $vs_saved/$file ] && ! [ -d distribution/$file ] ; then
+ echo "*** $file is NEW empty directory"
+ fi
+ elif [ ! -f running/$file ] ; then
+ if [ -L $vs_saved/$file ] ; then
+ echo "*** $file is DELETED symbolic link"
+ else
+ echo "*** $file has been DELETED"
+ fi
+ elif ! [ -s running/$file ] && ! [ -f $vs_saved/$file ] ; then
+ echo "*** $file is NEW empty file"
elif [ -f $vs_saved/$file ] ; then
- diff -u $vs_saved/$file running/$file
+ diff -u $vs_saved/$file running/$file
elif [ -f distribution/$file ] ; then
- diff -u distribution/$file running/$file
+ diff -u distribution/$file running/$file
else
- diff -u /dev/null running/$file
+ diff -u /dev/null running/$file
fi
done
}
------------------------------------------------------------------------------
_______________________________________________
leaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/leaf-devel