It doesn't happen often, but occasionally portupgrade will upgrade a port to a newer version that doesn't sit well with your system.
It can be very frustrating when an application that was working just fine an hour ago suddenly stops working after an upgrade. Now what?
At first glance, the solution isn't obvious. Because ports don't contain revision labels, you can't just cvsup back to an earlier version. However, the commits or changes to each port are tracked in the CVS repository. You could learn the syntax of the cvs command and use it to connect to the CVS repository, manually review the port's commit history, find an earlier version that worked on your system, check out that version, and rebuild the port. Whew! There must be an easier way.
That's what Heiner Eichmann thought when he created portdowngrade . His script does all of the work for you; you only need to choose which version of the port to use.
8.10.1 Using portdowngrade
Installing portdowngrade is easy enough:
# cd /usr/ports/sysutils/portdowngrade # make install clean
A few moments later, you'll have the script and an informative manpage. To run the script, simply specify which port you'd like to downgrade. Here, I'll demonstrate an arbitrary port:
# portdowngrade apinger portdowngrade 0.1 by Heiner Eichmann Please note, that nothing is changed in the ports tree unless it is explicitly permitted in step 6! Seeking port apinger ... found: net/apinger Step 1: Checking out port from CVS repository CVS root directory: :pserver:anoncvs:anoncvs@anoncvs.FreeBSD.org/home/ncvs Step 2: Reading the port history from the CVS repository Step 3: Analyzing the port history from the CVS repository Step 4: Load port version numbers and present results Keys: <space> : next page d : details p : previous page <enter> : leave presentation and downgrade if wanted number date portversion comment 1 2003/11/05 15:39:39 Fix whitespace. 2 2003/06/07 11:43:13 Fix breakage. 3 2003/06/04 09:49:31 Add startup script for apinger. 4 2003/05/07 11:37:52 Change maintainer email to my @FreeBSD. 5 2003/03/28 03:41:45 Update to 0.6.1 6 2003/02/21 13:14:34 De-pkg-comment. 7 2003/01/02 17:54:17 Update to 0.6 8 2002/10/14 14:02:52 upgrade to 0.5 9 2002/10/05 19:06:00 Upgrade to 0.4.1. 10 2002/07/19 23:02:53 Update to 0.3 11 2002/07/18 12:55:14 Alarm Pinger (apinger) is a little tool
Here are the first four of six steps run by portdowngrade. It has logged into the CVS server, found the desired port, and presented you with its commit history. This particular port has had 11 revisions and number 1 is the latest.
At this point, the script pauses for user input. I'm going to go back a few revisions to Version 4:
Total lines: 11. Command: press enter Enter version number to change port to (0: exit): 4 Step 5: Checking out chosen date of the port from the CVS repository Step 6: Modifying the port Port: net/apinger at : 2003/05/07 11:37:52 Type 'yes' to bring the port to the state of the date above or 'no' to exit without changing anything. Note, that this only changes the port, not the installed software! yes or no: yes The port has been set to the selected version. Install it if you wish. If you have portupgrade installed, you should run portsdb -Uu now, to see the changes in the ports database. In any case portupgrade -f apinger will install the changed port. Note: if you run cvsup, the port is changed back to the chosen label! #
When I typed yes, I chose to change the port version in the ports tree. The downgrade won't actually take place until I run portupgrade -f apinger. Note the use of the -f flag to force the reinstallation of an installed port. Since this port has changed in my tree, the reinstallation will overwrite my previously installed version.
# portupgrade -f apinger [Updating the pkgdb <format:bdb1_btree> in /var/db/pkg ... - 288 packages found (-0 +2) .. done] ---> Downgrading 'apinger-0.6.1_1' to 'apinger-0.6.1' (net/apinger) <snip build output> = ==> Registering installation for apinger-0.6.1 = ==> Cleaning for apinger-0.6.1 ---> Cleaning out obsolete shared libraries [Updating the pkgdb <format:bdb1_btree> in /var/db/pkg ... - 288 packages found (-0 +1) . done]
8.10.2 Preventing Automated Re-Upgrades
You'll notice that the next time you run your cvsup process [Hack #80], your downgraded port will appear as needing upgrading. If you've totally automated the process, it may re-upgrade to that new, buggy version.
It's easy to prevent that from happening. In fact, you can prevent automated upgrading of any port by using the HOLD_PKGS array in pkgtools.conf. Start by copying the sample configuration file to the real configuration file:
# cp /usr/local/etc/pkgtools.conf.sample /usr/local/etc/pkgtools.conf
Then, open /usr/local/etc/pkgtools.conf in your favorite editor and search for this section:
# HOLD_PKGS: array # This is a list of ports you don't want portupgrade(1) to upgrade, # portversion(1) to suggest upgrading, or pkgdb(1) to fix. # You can use wildcards ("ports glob" and "pkgname glob"). # -f/--force with each command will override the held status. # e.g.: # HOLD_PKGS = [ # 'bsdpan-*', # 'x11*/XFree86*', # ] HOLD_PKGS = [ 'bsdpan-*', ]
Simply follow the syntax to add the packages you want to keep as is:
HOLD_PKGS = [ 'bsdpan-*', 'apinger-*', ]
8.10.3 See Also