Table of Contents

Howto create a Debian repository

Using reprepro

Vedere gli articoli Setting up your own APT repository with upload support e Setting up and managing an APT repository with reprepro.

Il programma reprepro consente di gestire agevolmente un repository per diverse suite (stable, testing, ecc.) e diverse architetture (source, i386, amd64, ecc.).

Se si gestisce più di una suite i nomi dei pacchetti e il numero di versione devono essere accuratamente scelti.

In generale conviene che nel numero di versione sia compresa anche la suite, in modo che i file .diff.gz, .dsc, .changes e .deb possano coesistere nella directory pool/ quando sono compilati dalla stessa versione di sorgente, ma per suite differenti. Ad esempio:

libgdal-perl_1.6.3-3~gfossit50+1_i386.deb
libgdal-perl_1.6.3-3~gfossit60+1_i386.deb

sono due pacchetti generati dallo stesso sorgente gdal_1.6.3.orig.tar.gz, entrambi per architettura i386, ma compilati il primo su Debian Lenny (v.5.0) e il secondo su Debian Squeeze (presumibilmente v.6.0).

Altrimenti si corre il rischio di non poter aggiungere il file al repository, per via dell'errore:

File "pool/main/p/proj/proj-bin_4.7.0-1_i386.deb" is already registered with other md5sum!

Inizializzazione

Nella radice del repository creare una struttura di directory:

mkdir conf incoming

quindi creare il file di configurazione conf/distributions:

Origin: Niccolo Rigacci <niccolo@rigacci.org>
Label: Debian Lenny GFOSS packages
Suite: stable
Codename: lenny
Version: 5.0.4
Architectures: i386 amd64 source
Components: main
Description: Geographic Free and Open Source Software. Unofficial Debian packages: use at your own risk.
SignWith: 0FC37F09

Origin: Niccolo Rigacci <niccolo@rigacci.org>
Label: Debian Squeeze GFOSS packages
Suite: testing
Codename: squeeze
Architectures: i386 amd64 source
Components: main
Description: Geographic Free and Open Source Software. Unofficial Debian packages: use at your own risk.
SignWith: 0FC37F09

La chiave per firmare le release (in questo caso 0FC37F09) deve essere disponibile nel proprio keyring, verificare con gpg –list-keys.

Alcune opzioni che vogliamo sempre passare al comando reprepro (vedi avanti) possono essere messe in conf/options

verbose
ask-passphrase
basedir .

Gestione pacchetti

ATTENZIONE: in tutti i comandi che seguono sono state omesse le opzioni --ask-passphrase -Vb . in quanto presenti nel file di configurazione conf/options.

Per aggiunge un singolo pacchetto .deb ad una suite:

reprepro includedeb lenny /tmp/python-gdal_1.6.3-1_amd64.deb

La release viene firmata con chiave GPG creando il file dists/<codename>/Release.gpg.

Per aggiungere tutti i pacchetti risultanti da un dpkg-buildpackage ad una suite, si utilizza il file .changes. Generalmente questo comprende i pacchetti per la specifica architettura (es. i386), i source e gli all:

reprepro include squeeze /tmp/qgis_1.5.0~svn20100318+gfossit-1_i386.changes

L'eventuale vecchia versione del pacchetto viene automaticamente rimossa, dalla suite e dalla directory pool/.

Se il pacchetto è stato compilato per unstable mentre lo si vuole aggiungere a lenny, è necessario il parametro --ignore=wrongdistribution.

Se reprepro non riesce a trovare il file .orig.tar.gz può essere necessario il parametro --ignore=missingfile.

Per elencare tutti i pacchetti presenti in una suite (si usa il trucco di chiedere che abbiano Section diversa da un valore fasullo):

reprepro listfilter lenny "Section (!= none)"

Per elencare tutti i file presenti nel database degli md5sum (dovrebbero essere tutti i file presenti in pool/):

reprepro _listmd5sums

Per vedere la versione di un pacchetto contenuto in una suite:

reprepro list lenny grass

Per rimuovere un pacchetto da una suite (vengono tolte le versioni per tutte le architetture, compresa source e vengono rimossi i rispettivi file dalla directory pool/):

reprepro remove lenny grass

Se si toglie a mano un file da pool/ bisogna correggere l'inconsistenza con _forget, vedi sotto.

Per rigenerare tutti gli indici (normalmente non è necessario se le operazioni di inclusione e rimozione dei pacchetti sono state effettuate correttamente):

reprepro export

Per verificare la consistenza del repository:

reprepro check lenny
reprepro checkpool

Per risolvere un Missing file pool/…. Se il file manca dalla directory pool/ ed è elencato nel database degli md5sum:

reprepro _forget pool/main/libg/libgdal-grass/libgdal-grass_1.6.3-1.diff.gz

Se invece il file risulta necessario per la presenza di altri file, è necessario rimuovere gli altri file:

reprepro check lenny
Checking lenny...
Missing file pool/main/libg/libgdal-grass/libgdal-grass_1.6.3-1.dsc
Files are missing for 'libgdal-grass'!

reprepro list lenny libgdal-grass
lenny|main|source: libgdal-grass 1.6.3-1                                     

reprepro remove lenny libgdal-grass
removing 'libgdal-grass' from 'lenny|main|source'...

Using apt-ftparchive

We will create the repository debian-nic, with a single distribution etch (testing) and two sections: gis and server.

Create the directory tree

This is the directory tree to be created:

/
└─ var
   └─ www
      └─ default
         └─ debian-nic
            ├─ dists
            │  ├─ etch
            │  │  ├─ gis
            │  │  │  ├─ binary-i386
            │  │  │  └─ source
            │  │  └─ server
            │  │     ├─ binary-i386
            │  │     └─ source
            │  └─ testing -> etch
            ├─ ftparchive
            └─ pool
               ├─ gis
               └─ server

Generate a DSA key to sign the archive

In this example the administrator of the repository will be the root user, use another user if you can!

cd /var/www/default/debian-nic
mkdir .gnupg
chown root:root .gnupg
chmod 0700 .gnupg
gpg  --homedir .gnupg --gen-key

Those are the info provided to generate the key:

kind of key (1) DSA and Elgamal (default)
DSA keypair size 1024 bits
ELG-E keys size 2048 bits
Key is valid for 2y
Real name Niccolo Rigacci
Email address niccolo at rigacci.org
Comment Debian packages archive

The public key should be exported and published as an ASCII armored file:

cd /var/www/default/debian-nic
gpg --homedir .gnupg --list-keys
gpg --homedir .gnupg --export -a > debian-nic.key

Configuring apt-ftparchive

We will use apt-ftparchive to build the Debian archive, this is the configuration file /var/www/default/debian-nic/repository.conf:

//------------------------------------------------------------------------
// This is an apt-ftparchive(1) configuration file used to create
// a repository of Debian packages.
//
// We intend to provide packages to be installed onto a standard Debian
// box, so our distributions $(DIST) are named upon official Debian
// ones: woody, sarge, etch, ...
//
// Our sections $(SECTION) are named accordingly to the purpose of the
// packages: gis (packages for a GIS workstation), server (packages
// suitable for a server), ...
// We do not follow the official Debian components (main, non-free, ...)
//
// Usage:  apt-ftparchive generate repository.conf
//
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// The Dir section defines the standard directories needed to locate
// the files  required during the generation process.
//------------------------------------------------------------------------
Dir {
    // Specifies the root of the FTP archive, this is the
    // directory that contains the dist node.
    ArchiveDir "/var/www/default/debian-nic";

    // Specifies the location of the cache files used by
    // apt-ftparchive to cache the contents of .deb files.
    CacheDir "/var/www/default/debian-nic/ftparchive/";

    // Specifies the location of the override files.
    // There can be override files for binary, source and extra.
    OverrideDir "/var/www/default/debian-nic/indices";

    // Specifies the location of the file list files, if the
    // FileList setting is used (see below).
    FileListDir "/var/www/default/debian-nic/indices";

    // What is an override file?
    // What is a file list file?
};


//------------------------------------------------------------------------
// The  Default section specifies default values, and settings that
// control the operation of the generator. Other sections may override
// these defaults with a per-section setting.
//------------------------------------------------------------------------
Default {
    Packages::Compress ". gzip bzip2";
    Sources::Compress ". gzip bzip2";
    Contents::Compress ". gzip bzip2";
};


//------------------------------------------------------------------------
// Sets defaults specific to Tree sections. All of these variables are
// substitution variables and have the strings $(DIST), $(SECTION) and
// $(ARCH) replaced with their respective values.
//
// DIST      Something like stable, testing, ...
// SECTION   Something like main, non-free, contrib
// ARCH      Something like i386, m68k, ...
//------------------------------------------------------------------------
TreeDefault {
    // Binary cache database for this section. Creted into CacheDir.
    BinCacheDB "packages-$(SECTION)-$(ARCH).db";
    // Sets the top of the .deb directory tree.
    Directory "pool/$(SECTION)";
    // Sets the output Packages file.
    Packages "$(DIST)/$(SECTION)/binary-$(ARCH)/Packages";
    // Sets the top of the source package directory tree.
    SrcDirectory "pool/$(SECTION)";
    // Sets the output Sources file.
    Sources "$(DIST)/$(SECTION)/source/Sources";
    // Sets the output Contents file.
    Contents "$(DIST)/Contents-$(ARCH)";

    // Specifies that instead of walking the directory tree,
    // apt-ftparchive should read the list of files from the
    // given file. Relative file names are prefixed with the
    // FileListDir.
    //FileList "$(DIST)/$(SECTION).filelist";

};


//------------------------------------------------------------------------
// The Tree section defines a standard Debian file tree which consists
// of a base directory, then multiple sections in that base directory
// and finally multiple Architectures in each section.
//------------------------------------------------------------------------
Tree "dists/etch" {

    // This is a space separated list of sections which appear under
    // the distribution, typically this is something like main
    // contrib non-free
    Sections "gis server";

    // This is a space separated list of all the architectures that
    // appear under search section. The special architecture 'source'
    // is used to indicate that this tree has a source archive.
    Architectures "i386 source";
}

Update the archive contents

Once you have filled the archive with packages, you need to generate Packages, Sources, Contents-* files, we created the following script /var/www/default/debian-nic/repository-update:

#!/bin/sh
 
ArchiveDir="/var/www/default/debian-nic"
 
# Basically the following command will generate:
# - dists/$(DIST)/$(SECTION)/binary-$(ARCH)/Packages
# - dists/$(DIST)/$(SECTION)/source/Sources
# - dists/$(DIST)/Contents-$(ARCH)
# See repository.conf for extensive comments.
apt-ftparchive generate "$ArchiveDir/repository.conf"
 
# Create the "dists/$(DIST)/Release" file, needed if the
# archive is to be signed.
#
# It recursively searches the given directory for Packages,
# Sources, Release and md5sum.txt files. It then writes to
# stdout a Release file containing an MD5 digest and SHA1
# digest for each file.
# Values for the additional metadata fields in the Release file
# are taken from the -c configuration file.
#
# TODO: How to skip top level Release file itself?
#
apt-ftparchive -c "$ArchiveDir/release.conf" \
    release "$ArchiveDir/dists/etch" \
    > "$ArchiveDir/dists/etch/Release"
 
# Sign the Release file:
# -b  Make a detached signature
# -a  Create ASCII armored output
gpg --homedir /var/www/default/debian-nic/.gnupg \
    --output "$ArchiveDir/dists/etch/Release.gpg" \
    -ba "$ArchiveDir/dists/etch/Release"
#
# The public key of this repository should be exported as an
# ASCII armored file, and then added by the client using
# apt-key (will be stored into /etc/apt/trusted.gpg).
#
#   gpg --homedir /var/www/default/debian-nic/.gnupg --list-keys
#   gpg --homedir /var/www/default/debian-nic/.gnupg --export -a > debian-nic.key
#
#   apt-key add debian-nic.key
#   apt-key list
#   apt-key del <HEX_ID>
#

Client configuration

Must add into /etc/apt/sources.list:

deb      http://paros.rigacci.org/debian-nic/   etch   gis server
deb-src  http://paros.rigacci.org/debian-nic/   etch   gis server

Must execute

wget http://paros.rigacci.org/debian-nic/debian-nic.key
apt-key add debian-nic.key