Tue 23 December 2014


Mirroring ppa repos with reprepro and fixing Not Invented Here

Where did that repo go?

If you haven't yet been burned by 3rd party repos disappearing, wait a year.

For us this was the combination of Ubuntu Lucid, nginx, and php5-fpmbuntu's 10.04 LTS never packaged php-fpm - thus making thier long-term-supported nginx long-term-useless to our PHP developers.

As evidenced by pages and pages of google results everyone on earth circumvented this by running add-apt-repository ppa:brianmercer/php5 and moved on. Years later Brian Mercer disabled public access to his ppa and now all that google wisdom fail spectacularly! The comments on those pages are full of alternatives that also long ago passed their expiration dates.

Automation scripts don't mix well with 3rd party repos. The solution is to mirror them in house.

Not Invented Here is better when At Least Its Hosted Here.

Gather requirements

We'll go about mirroring l-mierzwa/lucid-php5 and ppa:tuxpoldo/munin. There are some blanks to fill in order to configure reprepro.

  1. Each repo's URL
  2. Each repo's gpg key id
  3. Each repo's gpg fingerprint

First - discover the location of the repo with add-apt-repository

apt-get install python-software-properties

add-apt-repository ppa:tuxpoldo/munin

cat /etc/apt/sources.list.d/tuxpoldo-munin-lucid.list
deb http://ppa.launchpad.net/tuxpoldo/munin/ubuntu lucid main

add-apt-reposutory ppa:l-mierzwa/lucid-php5

cat /etc/apt/sources.list.d/l-mierzwa-lucid-php5-lucid.list
deb http://ppa.launchpad.net/l-mierzwa/lucid-php5/ubuntu lucid main

Save the sources.list.d entries for later:

  repo: deb http://ppa.launchpad.net/tuxpoldo/munin/ubuntu lucid main 
  repo: deb http://ppa.launchpad.net/l-mierzwa/lucid-php5/ubuntu lucid main

Next - inspect the repos gpg key

apt-key finger | grep -B2 "Mierzwa"
pub   1024R/67E15F46 2011-09-22
      Key fingerprint = 9EFE E11E 2963 CEB2 29DB  0F93 9E51 F822 67E1 5F46
uid                  Launchpad PPA for Ɓukasz Mierzwa

apt-key finger | grep -B2 "Leo Moll"
pub   1024R/D294A752 2010-01-09
      Key fingerprint = 4BF1 FB36 64EC B114 3F8A  53FF D6D9 510D D294 A752
uid                  Launchpad Leo Moll's PPA

Note the key's id and fingerprint and save them for later:

  Id: 67E15F46
  Fingerprint: 9EFE E11E 2963 CEB2 29DB  0F93 9E51 F822 67E1 5F46
  Id: D294A752
  Fingerprint: 4BF1 FB36 64EC B114 3F8A  53FF D6D9 510D D294 A752

Also required is your own gpg public key

gpg --list-keys
pub   1024R/CDA332F2 2012-12-21
uid                  deploy (deb key) <deploy@lead.flightlookup.com>
sub   2048R/000FE233 2012-12-21

# The public key id required is CDA332F2

Configure reprepro

We need to create two configuration files: conf/distributions and conf/updates.

Create the repos directories:

mkdir -p /srv/repo/ubuntu/conf

To create the conf/distributions file we need bits and pieces of the information we've collected.

Arbitrary one-word label
Generally the last word in the apt deb line
I don't know what the initial '-' is for. The 'lucid-munin' is an arbitrary one-word label that corresponds to the conf/updates configuration file we'll be getting to in a moment
Your GPG public key to re-sign the packages with, not the upstream's key

The conf/updates file needs:

That arbitrary one-word label matching the Update field in conf/distributions
The URL of the repo
The last 16 characters of the upstream repo's gpg fingerprint

Here is a working example for conf/distributions:

Origin: Ubuntu
Codename: lucid-munin
Description: Mirror of ppa tuxpoldo munin
Architectures: i386 amd64
Components: main
UDebComponents: main
Contents: .gz
Update: - lucid-munin
Log: /var/log/reprepro-mirror.log
SignWith: CDA332F2

Origin: Ubuntu
Codename: lucid-php5-fpm
Description: Mirror of ppa l-mierzwa lucid-php5
Architectures: i386 amd64
Components: main
UDebComponents: main
Contents: .gz
Update: - lucid-php5-fpm
Log: /var/log/reprepro-mirror.log
SignWith: CDA332F2

Here is the corresponding conf/updates file:

Name: lucid-munin
Method: http://ppa.launchpad.net/tuxpoldo/munin/ubuntu
Suite: lucid
Components: main
Architectures: *
VerifyRelease: D6D9510DD294A752

Name: lucid-php5-fpm
Method: http://ppa.launchpad.net/l-mierzwa/lucid-php5/ubuntu
Suite: lucid
Components: main
Architectures: i386 amd64
VerifyRelease: 9E51F82267E15F46

Run reprepro to mirror the repos

cd /srv/repo/ubuntu
reprepro -V update
# -- many lines of output here --

Verify the packages downloaded

find pool/main/m/munin/ -type f

Congratulations on your new ppa mirror!

How to use your new repo

Just serve /srv/repo via http (here, nginx):

server {
  server_name apt.example.com;
  location /ubuntu { alias /srv/repo/ubuntu; }

Add two lines to /etc/apt/sources.list on all your servers:

deb http://apt.example.com/ubuntu/ lucid-munin main
deb http://apt.example.com/ubuntu/ lucid-php5-fpm main

Update, and install

apt-get update -qq && apt-get install munin-node

How (not) to update your new repo

Add the reprepro command to /etc/cron.d/mirror-reprepro

# Our very own Patch Thursday Surpise!
30 11 15-22 * Thu cd /srv/repo/ubunutu &&  reprepro update

Although it would build sympathy and understanding for our windows administrators I wouldn't recommend thisnstead I would just have cron mail me if an update were available, and configure nagios to nag me if it doesn't happen.

Go Top
comments powered by Disqus