Pacroll
From ArchWiki
About
Pacroll is a bash shell script to roll back changes made by pacman. It requires root to run and also requires that you have the old version of the package saved in your cache. See Downgrade packages for more about this. Currently, it is limited to rolling back the most recent 'pacman -S[y]u'.
Pacroll is currently NOT in a working state.
TODO
- Add the ability to download packages, so that they are not required to be in the local cache
- Add the ability to select individual packages
- Add the ability to roll back more than just the most recent upgrade
- Improve upgrade detection (parsing pacman.log)
Code
#!/bin/bash ### # Roll back the previous "pacman -Syu" # Written by Daenyth # # Run with pacroll --help for usage # Requires root to roll back packages ### VERSION='1.0' # Where do we store our temp files? TEMPDIR='/tmp/pacroll' # A list of packages installed INSTALLEDPKGS="installed.$$" # Packages in /var/cache/pacman/pkg CACHEPKGS="cached.$$" # Location of pacman.log export PACLOG='/var/log/pacman.log' # Location of package cache PACCACHE='/var/cache/pacman/pkg' # A list of updated packages which will be rolled back (packagename-version.etc.etc) ROLLPKGS="rollme.$$" ### # Declare some functions first ### # Call this if we hit an error function die () { echo "$1" cleanup exit } # Remove our files from temp storage function cleanup () { cd $TEMPDIR rm -f $INSTALLEDPKGS rm -f $CACHEPKGS rm -f $ROLLPKGS rmdir $TEMPDIR # Use rmdir rather than rm -rf because at this point, there should be no files remaining in the directory, so this will alert us if there are for some reason } function usage () { echo "pacroll version $VERSION - coded by Daenyth" echo "Usage: $0" echo "Rolls back the most recent 'pacman -Su'" echo "This will NOT currently roll back updates done via pacman -S or pacman -U" echo "Requires root to roll back packages. The old version of the package must exist in your package cache" echo "" echo "This software is not guaranteed to run or keep your system safe. Run it at your own risk." exit } function graceful_close () { cleanup exit } function listpkgs () { pacman -Q | sed 's/ /-/' > $INSTALLEDPKGS ls $PACCACHE | sed 's/\.pkg\.tar\.gz$//' > $CACHEPKGS } function listupdated () { tail -n $(expr $(wc -l $PACLOG | awk '{ print $1 }') - $(grep -n 'full system upgrade' $PACLOG | tail -n 1 | cut -d : -f 1)) $PACLOG \ | grep upgraded \ | awk '{ print $4 $5 }' \ | sed 's/(/-/' > $ROLLPKGS } function rollback () { cat $ROLLPKGS | pacman -U } ### # Some error checking is a good place to start the program... ### if [[ $1 == "--help" ]] then usage fi mkdir -p $TEMPDIR || die "Cannot create $TEMPDIR" [ -w $TEMPDIR ] || die "Cannot write to $TEMPDIR" # Should never fail, hopefully [ -r $PACLOG ] || die "Cannot read $PACLOG" [ -r $PACCACHE ] || die "Cannot read $PACCACHE" ### # code ### cd $TEMPDIR listpkgs listupdated # Remove from the update list any packages which we do not have stored in cache. comm -1 -2 $CACHEPKGS $ROLLPKGS > $ROLLPKGS # Give us the filename of the packages to be installed awk '{ print $1 ".plg.tar.gz" }' $ROLLPKGS > $ROLLPKGS echo "" echo "Rolling back `wc -l $ROLLPKGS | awk '{ print $1 }'` packages" echo -n "Proceed? (y/n) " read proceed if [[ $proceed != "y" ]] then echo "Exiting without rollback" exit fi rollback graceful_close