This is a follow-up to “Redis and php-resque on Ubuntu 12.04.”
Why pinning a package may be desirable
In my previous post, after adding the dotdeb.org repository to an Ubuntu system, then performing an system-wide upgrade, mysql-server and php (if already installed) will be also upgraded to the latest versions available from the dotdeb repository.
There are few reasons why an administrator may not elect to go down this route for the latest version of dotdeb packages and instead, stick with the older versions from official or mirrored Ubuntu repositories.
The PHP and mysql-server packages from an official or mirrored Ubuntu repository, may be a bit older but have been throughly battle-tested by many developers and users. These packages are more likely to be stable and less prone to problems. Additionally, the installation process of those packages have been “Ubuntuized” so they fit snugly within the distribution and work well with other Ubuntu-sanctioned software.
Once the administrator starts to deviate from the official Ubuntu path and install mysql-server and PHP from other sources, there’s no guarantee that these packages will work right off the bat and may require additional modifications to get them to work properly on the server. While this is unlikely to be a major concern with the particular packages from dotdeb repository, the possibility cannot be completely disregarded.
Setting up APT to pin a package
However, there is a way to set up APT to accept one dotdeb.org package and exclude all other dotdeb.org packages.
In this case, we want to retain only the redis-server package from dotdeb.org while disregarding PHP and mysql-server from dotdeb.org, in favor of the standard packages from Ubuntu distribution. This is called “pinning a package.”
Before setting up the dotdeb.org repository on the system, first check APT’s policy about the redis-server package:
# apt-cache policy redis-server redis-server: Installed: (none) Candidate: 2:2.2.12-1build1 Version table: 2:2.2.12-1build1 0 500 http://ftp.usf.edu/pub/ubuntu/ precise/universe amd64 Packages
This output shows that redis-server is yet to be installed, and that if it were to be installed, it would come from Ubuntu standard packages which offers redis-server 2.2.12.
APT uses a priority number (500 in the example above) to indicate the how preferred this particular package is over the same package from other repositories. The priority number 500 shows that this package version is right smack in the middle of the pecking order.
If a new repository was to be added to the system and happened to offer redis-server package with same priority score of 500, this package would be preferred over the Ubuntu provided package. If the added repository package was marked with lower priority score, say 400, then it would be pushed down the pecking order then Ubuntu package would be preferred by APT.
After adding the dotdeb.org repository (steps here), but before installing redis-server:
# apt-cache policy redis-server redis-server: Installed: (none) Candidate: 2:2.4.16-1~dotdeb.0 Version table: 2:2.4.16-1~dotdeb.0 0 500 http://packages.dotdeb.org/ stable/all amd64 Packages 2:2.2.12-1build1 0 500 http://ftp.usf.edu/pub/ubuntu/ precise/universe amd64 Packages
The APT policy now shows that dotdeb.org’s redis-server 2.4.16 package will be preferred for installation.
However, now that dotdeb.org repository has been set up, it also affects PHP5 package. The system now prefers the dotdeb.org package for PHP5, as seen from this APT policy output:
# apt-cache policy php5 php5: Installed: 5.3.10-1ubuntu3.2 Candidate: 5.3.16-1~dotdeb.0 Version table: 5.3.16-1~dotdeb.0 0 500 http://packages.dotdeb.org/ stable/all amd64 Packages *** 5.3.10-1ubuntu3.2 0 500 http://ftp.usf.edu/pub/ubuntu/ precise-updates/main amd64 Packages 500 http://ftp.usf.edu/pub/ubuntu/ precise-security/main amd64 Packages 100 /var/lib/dpkg/status 5.3.10-1ubuntu3 0 500 http://ftp.usf.edu/pub/ubuntu/ precise/main amd64 Packages
Modify APT preferences for a package
In order to disregard all other dotdeb.org packages, except for redis-server package, we need to modify APT preferences with two new rules:
Rule 1: Lower the priority score to 400 for all dotdeb.org packages, so that standard Ubuntu packages will override them.
Rule 2: Increase the priority score for redis-server dotdeb.org package back to 500 so that it’ll be preferred over the standard Ubuntu package.
Create file with these two sections: /etc/apt/preferences.d/redis-server-dotdeb-pin-400
Package: * Pin: release o=packages.dotdeb.org Pin-Priority: 400
Package: *redis-server* Pin: release o=packages.dotdeb.org Pin-Priority: 500
To find out what to put in on the Pin: line,
# apt-cache policy | grep dotdeb 400 http://packages.dotdeb.org/ stable/all i386 Packages release o=packages.dotdeb.org,a=stable,n=squeeze,l=packages.dotdeb.org,c=all origin packages.dotdeb.org 400 http://packages.dotdeb.org/ stable/all amd64 Packages release o=packages.dotdeb.org,a=stable,n=squeeze,l=packages.dotdeb.org,c=all origin packages.dotdeb.org redis-server -> 2:2.4.16-1~dotdeb.0 redis-server:i386 -> 2:2.4.16-1~dotdeb.0
Double checking APT policy for PHP5 to verify that it’s now sticking to Ubuntu standard package:
# apt-cache policy php5 php5: Installed: 5.3.10-1ubuntu3.2 Candidate: 5.3.10-1ubuntu3.2 Version table: 5.3.16-1~dotdeb.0 0 400 http://packages.dotdeb.org/ stable/all amd64 Packages *** 5.3.10-1ubuntu3.2 0 500 http://ftp.usf.edu/pub/ubuntu/ precise-updates/main amd64 Packages 500 http://ftp.usf.edu/pub/ubuntu/ precise-security/main amd64 Packages 100 /var/lib/dpkg/status 5.3.10-1ubuntu3 0 500 http://ftp.usf.edu/pub/ubuntu/ precise/main amd64 Packages
Now APT is configured properly for the installation of redis-server package from dotdeb.org repository while retaining standard Ubuntu packages for everything else.
Overriding the preferred repository
If redis-server isn’t installed and the system has both Ubuntu and dotdeb.org packages available, you can force the installation of redis-server package from Ubuntu repository over the preferred dotdeb.org repository:
# apt-get install -t precise redis-server