Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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?

share|improve this question
add comment

4 Answers

well using xorg-eg}dgers ppa for daily work...is a pretty bad idea

you can get latest drivers, true but you can also get working o not working drivers

to uninstall a PPA and also all the packages incluided on it (the procces will downgrade oackages to the ones aviable on the official reository); first install ppa-purge:

sudo apt-get install ppa-purge

And now to remove the ppa & packages

sudo ppa-purge

PS. you can find the name of the ppa on the same launchpad page of it

share|improve this answer
    
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 '11 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 '11 at 19:24
add comment

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.

share|improve this answer
add comment

[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))
share|improve this answer
    
Poor you. Did you know that the installation history is just available in /var/log/apt/history.log? –  Lekensteyn Jun 27 '11 at 21:13
    
dpkg.log is the same info but also including other apps than apt. –  Will Jun 27 '11 at 21:15
    
What other apps use dpkg directly then? Synaptic is a front-end of apt-get. –  Lekensteyn Jun 27 '11 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 '11 at 21:30
add comment

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
     [...]
    
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.