Pacroll

From ArchWiki

Jump to: navigation, search

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
Personal tools