16

The backstory is that the normal Intel GPU drivers don't do the various OpenGL extensions that my hobby coding and some games want. So I have to install xorg-edgers and then its happy. However, last Wednesday or so there was an update to xorg-edgers - lots of packages - and it broke badly; the drivers lock up and take the whole computer with them; hard reset required.

So how can you downgrade - select package versions in a PPA that represent a point in the past, ignoring versions newer than that?

4 Answers 4

20

Using xorg-edgers ppa for daily work could be a pretty bad idea.

It may gives you latest drivers, true, but you can also get not working drivers.

To remove a PPA and downgrade the packages replaced by it (so going back to the ones available on the official repositories), first install ppa-purge:

sudo apt-get install ppa-purge

And then remove the PPA, downgrading gracefully to official packages:

sudo ppa-purge ppaname

This should downgrade your packages back to official ones.

Other packages that were in PPA but not in official repositories won't be uninstalled. You should manually tell the package manager to remove them, for example using apt:

sudo apt-get purge packagename

You can find the name of the ppa looking at the "Software Sources" section of Ubuntu Settings, and see a list of packages it provides on its launchpad page (or looking at the "Origin" section of Synaptic Package Manager, if installed).

4
  • 1
    As I said, the normal drivers don't work for me. I need xorg-edgers. I just want to sidestep the very latest version of my drivers.
    – Will
    Jun 27, 2011 at 19:47
  • ten the next time you use xorg edgers ppa (and works) just disable the ppa and stick with those package versions
    – xangua
    Jul 4, 2011 at 19:24
  • 3
    sudo ppa-purge ppa:someppa/ppa Dec 22, 2014 at 15:25
  • it removing everyting in my case
    – user690429
    Nov 1, 2017 at 20:15
2

I had the same problem today, I noticed that ~2 weeks ago I installed updates to my system and still had ubuntu-x-swat ppa enabled which had a new nvidia driver. The old one was fine, the new one broke my system (only slightly, it took me a while to notice).

So I looked in /var/log/apt/history.log to find the previous version number of the nvidia driver package I had installed and then tried to find the package in /var/cache/apt/archives, where you'll normally find all packages downloaded by apt, but it wasn't there. And the ppa does not keep previous version of its packages around once they are superseded by a newer version so I couldn't get it from there either.

But, the diff from the previous package version to the newer is kept in the ppa for all versions, and together with the original tarball and its debian patches it is possible to reverse all changes of the newer version and get the previous version sources.

I'll briefly describe the neccessary steps:

  • Go to the ppa, find the newest package version and download the original tarball and the (optional) debian patches, in my case those were found on that page:

    https://launchpad.net/~ubuntu-x-swat/+archive/x-updates/+sourcepub/2087970/+listing-archive-extra
    

    The original tarball is named:

    nvidia-graphics-drivers_290.10.orig.tar.gz
    

    The debian patches that make a buildable package out of the tarball is:

    nvidia-graphics-drivers_290.10-0ubuntu1~lucid~xup1.diff.gz
    
  • Extract those somewhere preferably in a new and empty directory, then apply the patches to the source tree

    ~/nvidia> tar xvzf nvidia-graphics-drivers_290.10.orig.tar.gz
    [...]
    ~/nvidia> gzip -d nvidia-graphics-drivers_290.10-0ubuntu1\~lucid\~xup1.diff.gz
    ~/nvidia> patch -p0 < nvidia-graphics-drivers_290.10-0ubuntu1\~lucid\~xup1.diff
    [...]
    

    You should not get any rejected chunks when patching.

  • On the same ppa page you'll find a diff from the previous package version to the one you are looking at, under the "Available Diffs" secton.

    For me that was:

    diff from 285.05.09-0ubuntu1~lucid~xup1 to 290.10-0ubuntu1~lucid~xup1
    
  • Download that, extract and reverse apply it to the patched original sources:

    ~/nvidia> gzip -d nvidia-graphics-drivers_285.05.09-0ubuntu1\~lucid\~xup1_290.10-0ubuntu1\~lucid\~xup1.diff.gz
    ~/nvidia> patch -R -p0 < nvidia-settings_285.05.09-0ubuntu1\~lucid\~xup1_290.10-0ubuntu1\~lucid\~xup1.diff
    [...]
    
  • Presto! Now you should have the previous version source tree ready to build a package:

    ~/nvidia> mv nvidia-settings-290.10/ nvidia-settings-285.05.09
    ~/nvidia> cd nvidia-settings-285.05.09/
    ~/n/nvidia-settings-285.05.09> dpkg-buildpackage
    
  • Which should give you a the previous version package that can be installed with dpkg:

     ~/n/nvidia-settings-285.05.09> cd ..
     ~/nvidia> sudo dpkg -i nvidia-current_285.05.09-0ubuntu1\~lucid\~xup1_amd64.deb
     [...]
    
0

In the future, if you're using synaptic (assuming you can boot into X) you can select from the available versions by highlighting the package to be changed and then selecting 'force version' from the menu. From there you should be able to downgrade.

0

[Original Poster]

Not having much fun, I wrote a script to compute the difference and execute the restore command; there were about 100 packages involved. Sadly my downgrade failed as many packages are no longer available :(

#!/usr/bin/env python

import sys, getopt, os
from datetime import datetime
datefmt = "%Y-%m-%d %H:%M:%S"

dry_run = True
try:
    opts,args = getopt.getopt(sys.argv[1:],"y")
    if not args:
        raise Exception("no date specified")
    elif len(args) == 1:
        args.append("00:00:00") # default time
    elif len(args) != 2:
        raise Exception("unexpected arguments")
    snapshot = datetime.strptime(" ".join(args),datefmt)
    for opt,_ in opts:
        if opt == "-y":
            dry_run = False
        else:
            raise Exception("unsupported option %s"%opt)
except Exception as e:
    print "error:",e
    print "usage:",sys.argv[0],"[flags] YYYY-MM-DD [HH:MM:SS]"
    print "flags: -y = for real; don\'t just show it, restore it"
    sys.exit(1)

# work out what to do
history = {}
restore = set()
remove = set()
with open("/var/log/dpkg.log","r") as log:
    for line in log:
        date,time,action,line = line.split(None,3)       
        when = datetime.strptime("%s %s"%(date,time),datefmt)
        package,ver = line.strip().split(None,1)
        if when <= snapshot:
            if action in ("upgrade","install"):
                prev_ver,new_ver = ver.split()
                history[package] = new_ver
            elif action == "remove":
                if package in history:
                    del history[package]
                else:
                    print "(cannot remove %s)"%line
        else:
            if action == "install":
                remove.add(package)
            elif action == "upgrade":
                if package in history:
                    restore.add(package)
                elif package not in remove:
                    print "(cannot revert %s)"%line
            elif action == "remove":
                if package in history:
                    restore.add(package)
                elif package in remove:
                    remove.remove(package)
                else:
                    print "(cannot revert %s)"%line

# show what to do
for package in restore:
    print "restore",package,history[package]
for package in remove:
    print "remove",package

# do it
if not dry_run:
    print "======"
    def execute(cmd):
        print cmd
        os.system(cmd)
    #execute("apt-get remove "+" ".join(remove))
    execute("apt-get install "+" ".join("%s=%s"%(package,history[package]) for package in restore))
4
  • Poor you. Did you know that the installation history is just available in /var/log/apt/history.log?
    – Lekensteyn
    Jun 27, 2011 at 21:13
  • dpkg.log is the same info but also including other apps than apt.
    – Will
    Jun 27, 2011 at 21:15
  • What other apps use dpkg directly then? Synaptic is a front-end of apt-get.
    – Lekensteyn
    Jun 27, 2011 at 21:21
  • the user can use dpkg directly; the user may use gdebi or some other tool instead too. I had to pick a file to parse, so I picked the one proper file - dpkg.log. It happens I use apt exclusively, but same difference.
    – Will
    Jun 27, 2011 at 21:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .