You are not logged in.
Sometimes a "full system upgrade" may go wrong, and surely you can "rollback" your system manually-- just a little bit tiresome.
So here comes this script. It can generate the command to "downgrade" your newly upgraded packages, by either specifying a date (with time) or how many times back of the "full system upgrade".
It will parse pacman.log and analyse which packages need to be downgraded or can be ignored, and whether the old packages exist in the system cache.
This is the very 1st version, and only test for once. Be warned that the generated commad may ruin your system. Please check it out before executing.
The script is currently placed in /tmp/rollpac.sh.tmp2
#!/bin/bash
# argv[1] a date to roll back (to the state before the date)
# a number to roll back how many times of full system upgrade
# argv[2] optional,
# "-d": dry run.
# "-p": allow partial roll-back.
# "--FORCE": pacman force, bypass file conflict check
# "--NODEPS": pacman nodeps, skip all dependency checks
# init
LOG=/var/log/pacman.log
TMP=/tmp/$(basename $0).tmp
ARCH=i686
CACHE=/var/cache/pacman/pkg
PACMAN="sudo pacman"
if [ 17 -eq $(expr " $1 " : " [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}") ] ; then
echo "1=$1 2=$2 3=$3 4=$4 5=$5"
elif [ 2 -lt $(expr " $1 " : " [0-9]\+ ") -a 0 != "$1" ] ; then
date=$(grep "synchronizing package lists$" "$LOG" -A 1 | grep "starting full system upgrade$" | tail -n "$1" | head -n 1 | cut -d " " -f 1-2 | cut -d "[" -f 2 | cut -d "]" -f 1)
shift
echo "$0" "$date" "$@"
"$0" "$date" "$@"
exit $?
else
echo "unknow argument $1"
echo usage
exit 4
fi
if echo "$@" | grep -q -e "-p" ; then
PARTIAL=true
else
PARTIAL=false
fi
if echo "$@" | grep -q -e "-d" ; then
DRY_RUN=true
else
DRY_RUN=false
fi
if echo "$@" | grep -q -e "--FORCE" ; then
pacman_arg="--force"
else
pacman_arg=""
fi
if echo "$@" | grep -q -e "--NODEPS" ; then
pacman_arg="--nodeps $pacman_arg"
fi
echo PARTIAL=$PARTIAL DRY_RUN=$DRY_RUN pacman_arg=$pacman_arg
# parse pacman.log and collect packages that would be "down-graded"
history=$(tail -n +$(grep -m 1 -n "$1" "$LOG" | cut -d ":" -f 1) "$LOG" | grep "upgraded" | cut -d " " -f 4-)
if [ -z "$history" ] ; then
echo "nothing to be done"
exit 0
fi
analysed=""
echo -n > "$TMP"
echo "$history" | while read pkg ; do
name=$(echo "$pkg" | cut -d " " -f 1)
echo "analysing $name..."
# if parsed, continue
if echo "$analysed" | grep -q "$name" ; then
echo "done that before, ignore"
continue
fi
analysed="$name:$analysed"
# get init status
from=$(echo "$pkg" | cut -d " " -f 2 | cut -d "(" -f 2)
# get last status
to=$(echo "$history" | grep "^$name " | tail -n 1 | cut -d " " -f 4 | cut -d ")" -f 1)
if [ "$from" = "$to" ] ; then
echo "the same version, skip"
continue
fi
echo "$name $from $to" >> "$TMP"
done
# check if we have these ".tar.gz" (check if we got everything)
echo "$PACMAN $pacman_arg -U \\\
" > "$TMP"2
while read pkg ; do
name=$(echo "$pkg" | cut -d " " -f 1)
from=$(echo "$pkg" | cut -d " " -f 2)
if [ -e "$CACHE/$name-$from-$ARCH.pkg.tar.gz" ] ; then
echo "$CACHE/$name-$from-$ARCH.pkg.tar.gz \\\
" >> "$TMP"2
elif [ -e "$CACHE/$name-$from.pkg.tar.gz" ] ; then
echo "$CACHE/$name-$from.pkg.tar.gz \\\
" >> "$TMP"2
else
echo "package cache $name-$from(-$ARCH).pkg.tar.gz does not exist"
if [ "false" = "$PARTIAL" ] ; then
exit 6
fi
fi
done < "$TMP"
if [ 1 -eq $(wc -l "$TMP"2 | cut -d " " -f 1 ) ] ; then
echo > "$TMP"2
else
echo >> "$TMP"2
fi
# do it
#sh "$TMP"2
Offline
Thanks for this script. Nice work.
Can we traverse the pacman.log backwards up and rollback each operation (including "installed" in this). Something like:
history=$(tail -n +$(grep -m 1 -n "$1" "$LOG" | cut -d ":" -f 1) "$LOG" | tac | grep -E "(upgraded|installed)" | cut -d " " -f 3-)
Last edited by g33k (2008-11-04 15:08:07)
arch x86_64 / ratpoison,musca / urxvt / screen / mpd+ncmpcpp / opera,jumanji
Keep Smiling !
Offline
Nice work! I had written something similar called pacroll, but it was total trash. I think you can find it on the wiki, maybe you can find something useful from it. Disclaimer: it probably doesn't work, and from all accounts will not only destroy your computer but steal your girlfriend and kill your parents as well.
[git] | [AURpkgs] | [arch-games]
Offline