You are not logged in.

#1 2008-11-04 09:34:54

bsdson.tw
Member
From: Taiwan
Registered: 2005-05-06
Posts: 161

a bash script to help you rollback your package upgrade

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

#2 2008-11-04 15:06:55

g33k
Member
Registered: 2007-09-11
Posts: 16

Re: a bash script to help you rollback your package upgrade

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

#3 2008-11-05 04:27:31

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: a bash script to help you rollback your package upgrade

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.

Offline

Board footer

Powered by FluxBB