Thursday, July 10, 2008

HOW-TO: Create an automated apt-repository

Today we'll create an automated apt repository. For the automation, we'll use a simple script which is executed on a timer (in cron). This script will automatically detect and add new packages from an "incoming" directory. We'll sign our packages using a GPG key, and publish the site to users with apache. The repository example used will import i386 and amd64 packages for installation.

Starting with a fully patched Ubuntu host, we'll install the following debs:

apt-get install apache2 libapache2-mod-perl2 reprepro

If you would like to build custom debian packages (covered in a future article coming soon!), install the following additional packages.

apt-get install devscripts dh-make fakeroot build-essential linux-headers-`uname -r`

Once all of the packages have installed, edit the apache default site (this assumes that this server hosts no other sites, if so adjust accordingly).

Configure the default site as follows, changing the admin@fewt.com to a custom email address (Note: I'll de-ugly this as I figure out how to best post *ML on blogger):

NameVirtualHost *

<VirtualHost *>
ServerAdmin admin@fewt.com
DocumentRoot /var/www/
ServerName apt.asurion.com
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory "/var/www">
Options Indexes FollowSymLinks MultiViews
DirectoryIndex index.html
AllowOverride Options
Order allow,deny
allow from all
</Directory>
<Directory "/var/www/conf">
Order allow,deny
Deny from all
Satisfy all
</Directory>
<Directory "/var/www/db">
Order allow,deny
Deny from all
Satisfy all
</Directory>
</VirtualHost>

Save and quit by pressing escape, followed by : then wq and enter ({ESC}:wq{ENTER})

Restart apache with the following command:

apache2ctl restart

Next, cd into /var/www and create the default directories needed for reprepro:

cd /var/www
mkdir conf
mkdir override
mkdir incoming
chown you:bin incoming
chmod 0775 incoming

Next; Create the default files:

cd conf
vi distributions

Origin: Your Name or Company Here
Label: public private whatever
Suite: stable
Codename: hardy
SignWith: default
Architectures: i386 amd64 all source
Components: main non-free contrib
Description: Something like "Packages for my systems"

Now; Create an options file:

vi options

verbose
ask-passphrase
basedir /var/www

Save and quit by pressing escape, followed by : then wq and enter ({ESC}:wq{ENTER})

Create your GPG key for repository signing and make sure it's in root's keystore:

sudo -s
gpg --gen-key

Note: If you choose a password for signing, automated package processing will not work.

Now, export the public key for import into apt:

gpg --list-public-keys

Using the line that states "pub" look for the hex numbers after the / (Ex: pub 1024D/5F6DEDCD 2008-07-10)

We'll use my temporary key hex for this example, be sure to change it.

gpg --export 0x5F6DEDCD >repo.key

Whenever you connect a new system to this apt repository you will need to place a copy of the key into your working directory and issue the following command:

apt-key add repo.key

Note: In a future article I will walk you through inserting this key into the Ubuntu keychain package for installation, and into a custom package for management.

Now we'll create the initial repository, then add the automation to ensure packages placed in /var/www/incoming are processed. Be sure to replace "hardy" with the Codename from the distributions file.

cd /var/www
reprepro check hardy

Once we have a repository, lets create the automation:

mkdir ~/bin
cd ~/bin
vi process-debs.sh (Note: add the following content, change all instances of hardy to match the Codename: line in the distributions file.)

#!/bin/bash
cd /var/www
if [ -e "./db/lockfile" ]; then
echo Error creating lockfile './db/lockfile', quitting.
exit
fi

for item in incoming/*deb; do
if [ ! -e $item ]; then
exit
fi
if [ -e $item ]; then
reprepro includedeb hardy $item >/dev/null 2>&1 && (rm $item >/dev/null 2>&1; logger -t user:notice Added package [$item] to the repository)
fi
done

Save and quit by pressing escape, followed by : then wq and enter ({ESC}:wq{ENTER})

Make the script owned by root and executable by world by issuing:

chown root:bin ./process-debs.sh
chmod 755 ./process-debs.sh

Create an entry in crontab containing the following (change the time to whatever you want here):

*/5 * * * * /path/to/process-debs.sh >> /var/log/repository.log 2>&1

Add a debian package to /var/www/incoming and wait. Once the job executes you should see it move to the pool.

Add an entry to a host to use the new repository (replace "main non-free contrib" with the definition of components in the distribution file):

vi /etc/apt/sources.list.d/my.repo

deb http://yourserver hardy main non-free contrib

Save and quit by pressing escape, followed by : then wq and enter ({ESC}:wq{ENTER})

If you have added the key using the steps above, you can 'apt-get update' then 'apt-get install what-ever-you-put-in-your-repo'

1 comments:

William said...

When are you going to post the 'later post' and expand on the info you have here? This post is awesome and the visitors would greatly benefit with another post.

Thanks.