Crear un repositorio parcial de Ubuntu

Crear un repositorio parcial de Ubuntu

Uno de los problemas que nos encontramos en la administración de los equipos es que no podemos permitir que la gente instale cualquier paquete disponible para Ubuntu, porque sus sistemas duran muy poco tiempo usables y pueden instalar software no deseado como servidores de correo.

Para solucionarlo, durante mucho tiempo no hemos permitido la instalación de paquetes a los usuarios, y cada vez que querían instalar software, ha tenido que ser mediando a través de nosotros, los administradores.

Afortunadamente, esta solución nos permite saltarnos ese paso: Creando un repositorio que solo contenga los paquetes que nosotros aprobemos previamente podemos ofrecérselos a todo el mundo una vez una única persona nos lo pida y lo aprobemos. Tenemos así un repositorio tipo lista blanca.

En los clientes es necesario configurar este repositorio, quitar todos los demás y permitir la instalación de los paquetes a los usuarios. Esto se sale del objetivo del tutorial así que no lo cubriremos aquí.

Material necesario

  • Un servidor, donde almacenaremos el repositorio. Puede ser virtual perfectamente.
  • Se recomiendan al menos 15GB de almacenamiento exclusivos para /var/local, aunque cuidado porque se pueden necesitar más si crece mucho el repositorio. Si se va a crear un repositorio multiarquitectura (para Ubuntu 12.04 en adelante), recomendamos al menos 20GB.
  • Puertos abiertos para HTTP, ya que el servidor estará accesible mediante este protocolo.

Resumen del funcionamiento

El funcionamiento básicamente es este:

  1. Colocamos en una lista de texto los paquetes que queremos.
  2. Se la pasamos a apt-get en modo sólo descarga, de forma que los deja en caché.
  3. Con apt-move, movemos los paquetes en caché a un repositorio.

El problema es que el apt del sistema necesita ser capaz de instalar todos los paquetes que queramos, y eso quiere decir que o bien el servidor tiene exactamente el mismo sistema operativo y versión que los clientes a los que va dirigido el repositorio, o debemos crear un entorno chroot con debootstrap. Optaremos por esta última opción.

Creación del entorno chroot

El siguiente script instalará bootstrap y hará el trabajo de crear el directorio y el entorno básico de los entornos chroot de 32 y de 64 bits:

mirror_generate.sh
#!/bin/sh
# generate a partial Debian mirror with debootstrap and apt-move
# 2004-02, W. Borgert <debacle@debian.org>
# Released under the terms of the GNU General Public License
# 2012-12 Modified by Jorge Suárez de Lis <jorge.suarez@usc.es>
# 2014-07 Modified again by Jorge Suárez de Lis <jorge.suarez@usc.es>
 
# the root directory of the mirror system
CHROOT64=/var/local/chroot-amd64
CHROOT32=/var/local/chroot-i386
# the mirror directory inside of the chroot
MIRRORDIR64=/var/local/mirrors-amd64
MIRRORDIR32=/var/local/mirrors-i386
# the Debian archive next to you
DEBIANREPO=http://fr.archive.ubuntu.com/ubuntu
# the release name
RELEASENAME=trusty
 
####
 
OUT=adduser,aptitude,apt-utils,at,base-config,bsdmainutils,\
console-common,console-data,console-tools,cpio,cron,debconf-i18n,\
dhcp-client,ed,exim4,exim4-base,exim4-config,exim4-daemon-light,\
fdutils,gettext-base,groff-base,ifupdown,info,ipchains,iptables,\
iputils-ping,klogd,libconsole,libgcrypt1,libgcrypt7,libgdbm3,\
libgnutls10,libgpg-error0,libident,liblocale-gettext-perl,\
liblockfile1,liblzo1,libnewt0.51,libopencdk8,libpcap0.7,libpcre3,\
libpopt0,libsigc++-1.2-5c102,libssl0.9.7,libtasn1-0,\
libtext-charwidth-perl,libtext-iconv-perl,libtext-wrapi18n-perl,\
libwrap0,lilo,logrotate,mailx,makedev,man-db,manpages,mbr,modconf,\
modutils,nano,netbase,netkit-inetd,net-tools,nvi,pciutils,ppp,\
pppconfig,pppoe,pppoeconf,procps,psmisc,setserial,slang1,sysklogd,\
syslinux,sysvinit,tasksel,tcpd,telnet,wget,whiptail
 
IN=apt-move,bc,bzip2,dash,debconf,libbz2-1.0,libpam0g,\
libreadline5
 
####
 
apt-get install debootstrap
 
mkdir -p $CHROOT64$MIRRORDIR64/ubuntu
debootstrap --components=main,universe --exclude="$OUT" --include="$IN" $RELEASENAME $CHROOT64 $DEBIANREPO
mkdir -p $MIRRORDIR64
ln -s $CHROOT64$MIRRORDIR64/ubuntu $MIRRORDIR64
 
mkdir -p $CHROOT32$MIRRORDIR32/ubuntu
debootstrap --components=main,universe --exclude="$OUT" --include="$IN" $RELEASENAME $CHROOT32 $DEBIANREPO
mkdir -p $MIRRORDIR32
ln -s $CHROOT32$MIRRORDIR32/ubuntu $MIRRORDIR32

Es posible que falle para algunas releases de Ubuntu. Por ejemplo, este funciona para Ubuntu 14.04, pero es posible que necesites cambiar el nombre de algún paquete para otras versiones, o para usarlo en Debian.

Una vez terminado, tendremos un sistema base limpito, listo para hacer chroot, en /var/local/chroot-amd64 y en /var/local/chroot-i386.

Configuración de apt y apt-move dentro del entorno chroot

Editamos el archivo /var/local/chroot-amd64/etc/apt/sources.list poniendo todos los repositorios de los que deseemos instalar paquetes. Por ejemplo, en nuestro caso:

deb http://fr.archive.ubuntu.com/ubuntu precise main universe multiverse
deb http://fr.archive.ubuntu.com/ubuntu precise-updates main universe multiverse
deb http://fr.archive.ubuntu.com/ubuntu precise-security main universe multiverse
deb http://download.virtualbox.org/virtualbox/debian precise contrib non-free

Si añades repositorios externos, no olvides añadir las claves GPG dentro del entorno chroot, o todo dejará de funcionar correctamente. Por ejemplo, aquí hemos añadido el de Virtualbox. Al hacer sudo chroot /var/local/chroot-amd64 apt-get update recibiremos el siguiente error:

W: Error de GPG: download.virtualbox.org lucid Release Las firmas siguientes no se pudieron verificar porque su llave pública no está disponible: NO_PUBKEY 54422A4B98AB5139

Lo único que tenemos que hacer es añadir esa llave pública descargándola de un servidor de llaves:

chroot /var/local/chroot apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 54422A4B98AB5139

Comprueba que volviendo a hacer sudo chroot /var/local/chroot-amd64 apt-get update ya no recibes la advertencia.

Ahora edita la configuración de apt-move. Establece lo siguiente en el archivo /var/local/chroot-amd64/etc/apt-move.conf:

LOCALDIR=/var/local/mirrors-amd64/ubuntu
DIST=lucid
PKGCOMP="none gzip"
CONTENTS=yes

Y ahora crea el mirror vacío con los siguientes comandos:

chroot /var/local/chroot-amd64 apt-get update
chroot /var/local/chroot-amd64 apt-move get

A partir de aquí nos serviremos de dos scripts más, ambos fuera del entorno chroot.

El primero nos servirá para generar los archivos Release, ya que apt-move no lo hace por nosotros. Colócalo en /usr/local /sbin/generate_release_files.sh:

generate_release_files.sh
#!/bin/sh
# generate Release files for a Debian mirror
# 2003-10, W. Borgert <debacle@debian.org>
# Released under the terms of the GNU General Public License
# 2012-12 Modified by Jorge Suárez de Lis <jorge.suarez@usc.es>
 
ORIGIN="Ubuntu"
LABEL="Ubuntu CITIUS"
SUITE="lucid"
CODENAME="precise"
DESC="Paquetes para Ubuntu CITIUS 12.04"
UNPACK=0
ARCHIVE=.
SIGN_RELEASE=0
SIGN_KEY=0
 
# long options not yet implemented
args=`getopt 'a:c:d:l:o:s:u' $*`
for o
    do case "$o" in
        -a | --arch*) ARCHIVE="$2"; shift; shift;;
        -c | --code*) CODENAME="$2"; shift; shift;;
        -d | --desc*) DESC="$2"; shift; shift;;
        -l | --label) LABEL="$2"; shift; shift;;
        -o | --orig*) ORIGIN="$2"; shift; shift;;
        -s | --suite) SUITE="$2"; shift; shift;;
        -u | --unpa*) UNPACK=1; shift;;
        --) shift; break;;
    esac
done
 
####
 
cd $ARCHIVE
DATE=`date -u`
if [ $UNPACK -eq 1 ]; then
    PACKAGGZ=`find . -follow -name Packages.gz -o -name Sources.gz`
    for p in $PACKAGGZ; do
        gunzip -c $p > `dirname $p`/`basename $p .gz`
    done
fi
 
PACKAGES=`find . -follow -name Packages -o -name Packages.gz -o \
    -name Sources -o -name Sources.gz`
DIRS=`for p in $PACKAGES; do dirname $p; done|sort -u`
COMPS=`for d in $DIRS; do echo $d | \
    sed 's,[^A-Za-z0-9-]*\([A-Za-z0-9-]*\)/.*,\1,'; done|sort -u`
ARCHS=`for d in $DIRS; do echo $d | \
    sed 's,.*binary-\([A-Za-z0-9-]*\),\1,'; done|sort -u`
 
for d in $DIRS; do
    cd $d
        ARCH=`echo $d | sed 's,.*binary-\([A-Za-z0-9-]*\),\1,'`
        COMP=`echo $d | \
            sed 's,[^A-Za-z0-9-]*\([A-Za-z0-9-]*\)/.*,\1,'`
        echo "Archive: $SUITE
Component: $COMP
Origin: $ORIGIN
Label: $LABEL
Architecture: $ARCH" > Release
    cd -
done
 
rm -f Release
MD5FILES=`find . -follow -name Packages -o -name Packages.gz -o \
    -name Sources -o -name Sources.gz -o -name Release \
    | sed 's,^[^/]*/,,'`
 
echo "Origin: $ORIGIN
Label: $LABEL
Suite: $SUITE
Codename: $CODENAME
Date: $DATE
Architectures:" `echo $ARCHS`"
Components:" `echo $COMPS`"
Description: $DESC
MD5Sum:" > Release
 
for m in $MD5FILES; do
    echo -n " " >> Release
    SIZE=`wc -c $m | sed 's/ *\([0-9]*\).*/\1/'`
    SUM=`md5sum $m | sed 's/^ *\([A-Fa-f0-9]*\) .*/\1/'`
    printf "%s %16d %s\n" $SUM $SIZE $m >> Release
done
 
echo "SHA1:" >> Release
for m in $MD5FILES; do
    echo -n " " >> Release
    SIZE=`wc -c $m | sed 's/ *\([0-9]*\).*/\1/'`
    SUM=`sha1sum $m | sed 's/^ *\([A-Fa-f0-9]*\) .*/\1/'`
    printf "%s %16d %s\n" $SUM $SIZE $m >> Release
done
 
if [ $SIGN_RELEASE -eq 1 ] ; then
    gpg --armor --default-key $SIGN_KEY --yes -b -o $ARCHIVE/Release.gpg $ARCHIVE/Release
fi

No te olvides de modificar las variables de arriba, que definirán el nombre del repositorio y la descripción.

Por último, el siguiente script que será el único que manejemos directamente a partir de ahora, será el que nos sirva para gestionar la instalación de nuevos paquetes, las actualizaciones, búsquedas, etc. Colócalo en /usr/local/sbin/update_mirror.sh:

update_mirror.sh
#!/bin/sh
# update a partial Debian mirror with apt-move
# 2004-02, W. Borgert <debacle@debian.org>
# Released under the terms of the GNU General Public License
# 2012-12 Modified by Jorge Suárez de Lis <jorge.suarez@usc.es>
 
# the root directory of the mirror system
CHROOT=/var/local/chroot-amd64
# the mirror directory inside of the chroot
MIRRORDIR=/var/local/mirrors-amd64/ubuntu/dists/precise
# master packages file inside of the chroot
MASTER=/var/local/packages
 
####
 
MODE=$1; shift
 
case "$MODE" in
    clean)
        chroot $CHROOT apt-move delete
        exit 0
        ;;
    search|policy|show)
        chroot $CHROOT_BASEDIR-$ARCH apt-cache $MODE $@
        exit 0
        ;;
    install)
        PACKAGES="$*"
        if [ -f $CHROOT/$MASTER ]; then
            OLDPACKAGES=`cat $CHROOT/$MASTER`
        else
            OLDPACKAGES=
        fi
        for p in $OLDPACKAGES $PACKAGES; do echo $p; done | \
            sort -u > $CHROOT/$MASTER
        ;;
    upgrade)
        if [ -f $CHROOT/$MASTER ]; then
            PACKAGES=`cat $CHROOT/$MASTER`
        else
            exit 0
        fi
        ;;
    *)
        echo "Usage:"
        echo "$0 clean"
        echo "$0 install <packages>"
        echo "$0 upgrade"
        echo "$0 search"
        echo "$0 policy <package>"
        echo "$0 show <package>"
        exit 1
        ;;
esac
 
chroot $CHROOT apt-get update
chroot $CHROOT apt-get -d --yes --reinstall install $PACKAGES
chroot $CHROOT apt-move get
chroot $CHROOT apt-move move
chroot $CHROOT apt-move packages
/usr/local/sbin/generate_release_files.sh -a $MIRRORDIR
chroot $CHROOT apt-get autoclean

No te olvides de darle permiso de ejecución a ambos scripts.

Una de bugs

apt-move tiene un bug en Ubuntu 10.04 y 12.04 que debes solucionar. No le gustan los paquetes de universe y multiverse, entre otros. Para solucionarlo, hay que editar el archivo /var/local/chroot-amd64/usr/share/apt-move/getdist.awk y dejarlo así:

function getdist(section, dist, a) {
        if (section in _getdist) {
                return _getdist[section]
        }
 
        dist = section
        ldist = tolower(dist)
 
        if (match(ldist, /^non-us\/[^\/]*/)) {
                dist = "non-US" substr(dist, 7, RLENGTH - 6)
        } else if (ldist == "non-us") {
                dist = "non-US/main"
        #} else if (match(dist, /^[^\/]*\//)) {
        #       dist = substr(dist, 1, RLENGTH - 1)
        } else {
                dist = "main"
        }
        return _getdist[section] = dist
}

Si usas Ubuntu 12.04, ten presente también este bug. Instalar el paquete deb directamente desde Debian, donde a fecha de escribir esto ya han arreglado el bug, soluciona todos los problemas. No te olvides de volver a aplicar el parche de más arriba de nuevo una vez vuelvas a instalar apt-move.

Funcionamiento y actualización

Para añadir paquetes (con sus dependencias correspondientes) al repositorio, ejecuta lo siguiente:

update_mirror.sh install <nombres_de_paquetes>

Ten en cuenta que esto añade nombres de paquetes al archivo /var/local/chroot-amd64/var/local/packages. Si te equivocas y empiezas a recibir advertencias o errores en el script de actualización debido a paquetes mal escritos o conflictivos, puedes eliminarlos de allí.

Para actualizar el repositorio, escribe lo siguiente:

update_mirror.sh upgrade

Servir el repositorio mediante HTTP

Dependiendo del volumen de peticiones, interesará instalar un servidor u otro. En nuestro caso, es suficiente con Lightttpd.

  sudo apt-get install lighttpd

Editamos el archivo de configuración /etc/lighttpd/lighttpd.conf para servir el repositorio:

server.document-root       = "/var/local/mirrors-amd64"

Reiniciamos lighttpd:

invoke-rc.d lighttpd restart

Y tras esto ya pueden conectarse los clientes. Para ello hace falta añadir esta línea en el sources.list de cada uno:

deb http://<URL_DEL_SERVIDOR>/ubuntu lucid main contrib

Nótese que solo se añaden main ycontrib independientemente de cómo se llamen las secciones en Ubuntu. Apt-move deja los paquetes que haya en contrib allí y el resto los manda a main (universe, multiverse y demás).

Firmar los archivos Release

Crea la firma usando gnupg en el entorno chroot:

# chroot /var/local/chroot-lucid/ gpg --gen-key
gpg (GnuPG) 1.4.10; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y
 
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
 
Real name: Unidade de Xestion de Infraestruturas TIC <citius.tic@usc.es>
Invalid character in name
Real name: "Unidade de Xestion de Infraestruturas TIC <citius.tic@usc.es>"
Invalid character in name
Real name: Unidade de Xestion de Infraestruturas TIC
Email address: citius.tic@usc.es
Comment: Chave para o repositorio de paquetes de Ubuntu 
You selected this USER-ID:
    "Unidade de Xestion de Infraestruturas TIC (Chave para o repositorio de paquetes de Ubuntu) <citius.tic@usc.es>"
 
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

Edita el archivo /var/local/chroot-amd64/etc/apt-move.conf y establece la llave correcta:

# Set this to key name to be used for signing Release files.
GPGKEY="Unidade de Xestion de Infraestruturas TIC (Chave para o repositorio de paquetes de Ubuntu) <citius.tic@usc.es>"

Edita el script /usr/local/sbin/generate_release_files.sh. Establece la llave correcta y habilita el firmado:

SIGN_RELEASE=1
SIGN_KEY="D91685C4"

Exporta la llave privada y añádela a los entornos chroot:

gpg --export-secret-keys --armor --output /var/local/repositorio.gpg 'Unidade de Xestion de Infraestruturas TIC'
cp /var/local/repositorio.gpg /var/local/chroot-amd64/
cp /var/local/repositorio.gpg /var/local/chroot-i386/
chroot /var/local/chroot-amd64 gpg --allow-secret-key-import --import /repositorio.gpg
chroot /var/local/chroot-i386 gpg --allow-secret-key-import --import /repositorio.gpg
rm -f /var/local/chroot-amd64/repositorio.gpg
rm -f /var/local/chroot-i386/repositorio.gpg

Por último, actualiza la lista de paquetes de nuevo:

/usr/local/sbin/update_mirror.sh upgrade

Para obtener la llave pública que se deberá añadir a los clientes, ejecuta lo siguiente:

gpg --armor --output /var/local/repositorio.pub --export 'Unidade de Xestion de Infraestruturas TIC'

Esta clave pública debe añadirse en todos los clientes que vayan a usar el repositorio:

apt-key add /tmp/repositorio.pub

Actualizar automáticamente el repositorio

Sencillamente, ejecuta una tarea en cron todas las noches, o cuando quieras.

crontab -e
# m h  dom mon dow   command
0 2 * * * /usr/local/sbin/update_mirror.sh upgrade

Soporte multiarquitectura

Desde Ubuntu 12.04 en adelante apt soporta multiarquitectura, y en equipos de 64 bits (arquitectura amd64) buscará repositorios de i386, e incluso puede haber dependencias entre arquitecturas. Por ejemplo, al instalar skype en realidad el paquete depende de skype:i386 y se descarga el paquete de 32 bits.

Por lo tanto, si se quiere montar un repositorio completo para Ubuntu 12.04 con la arquitectura amd64, hay que tener esto en cuenta.

Desafortunadamente, apt-move hoy en día NO soporta multiarquitectura, por lo que ignorará los paquetes i386. Los clientes tampoco podrán descargar la lista de paquetes de i386 y recibirán advertencias, y no podrán instalar paquetes de 32 bits como skype o wine.

Os habréis dado cuenta de que el entorno lo hemos creado previamente en /var/local/chroot-amd64. No era gratuito, era por esto.

Lo primero que debes hacer es crear otro entorno chroot con apt-move, pero de 32 bits. Hazlo en /var/local/chroot-i386 siguiendo las instrucciones de más arriba, pero cambiando los directorios.

Si usas Ubuntu 10.04 o 12.04, corrige los bugs pertinentes también en el entorno de 32 bits, no te olvides. Importa también la llave privada en el entorno de 32 bits.

Ahora viene lo divertido.

Crea un nuevo directorio /var/local/mirror-agregate haciendo enlaces a los archivos y directorios particulares de cada arquitectura en caso del directorio dists, y al pool del entorno de 64 bits, que incluye en realidad todos los paquetes. Vamos, resumiendo, esto:

mkdir -p /var/local/mirror-agregate/ubuntu/dists/precise/main
mkdir -p /var/local/mirror-agregate/ubuntu/dists/precise/contrib
ln -s /var/local/mirrors-i386/ubuntu/dists/precise/main/binary-i386 /var/local/mirror-agregate/ubuntu/dists/precise/main/
ln -s /var/local/mirrors-amd64/ubuntu/dists/precise/main/binary-amd64 /var/local/mirror-agregate/ubuntu/dists/precise/main/
ln -s /var/local/mirrors-amd64/ubuntu/dists/precise/contrib/binary-amd64 /var/local/mirror-agregate/ubuntu/dists/precise/contrib/
ln -s /var/local/mirrors-amd64/ubuntu/dists/precise/Contents-amd64.gz /var/local/mirror-agregate/ubuntu/dists/precise/
ln -s /var/local/mirrors-amd64/ubuntu/pool /var/local/mirror-agregate/ubuntu/

Modifica la configuración de Lighttpd para que sirva este nuevo directorio, en lugar del que solo contiene los paquetes de 64 bits. Solo es cambiar un directorio en la configuración, seguro que sabes hacerlo.

Sustituye el script update_mirror.sh por la siguiente versión:

update_mirror.sh
#!/bin/sh
# update a partial Debian mirror with apt-move
# 2004-02, W. Borgert <debacle@debian.org>
# Released under the terms of the GNU General Public License
# 2012-12 Modified by Jorge Suárez de Lis <jorge.suarez@usc.es>
 
# the root directory of the mirror system
CHROOT64="/var/local/chroot-amd64"
CHROOT32="/var/local/chroot-i386"
# master packages file inside of the chroot
MASTER="/var/local/packages"
 
####
 
MODE=$1; shift
 
case "$MODE" in
    clean)
	chroot $CHROOT64 apt-move delete
        exit 0
        ;;
 
    search|policy|show)
        chroot $CHROOT64 apt-cache $MODE $@
        exit 0
        ;;
 
    install)
	        PACKAGES="$*"
	        if [ -f $CHROOT64/$MASTER ]; then
	            OLDPACKAGES=`cat $CHROOT64/$MASTER`
	        else
	            OLDPACKAGES=
	        fi
	        for p in $OLDPACKAGES $PACKAGES; do echo $p; done | \
	            sort -u > $CHROOT64/$MASTER
        ;;
    upgrade)
	        if [ -f $CHROOT64/$MASTER ]; then
	            PACKAGES=`cat $CHROOT64/$MASTER`
	        else
	            exit 0
	        fi
        ;;
    *)
        echo "Usage:"
        echo "$0 clean"
        echo "$0 install <packages>"
        echo "$0 upgrade"
        exit 1
        ;;
esac
 
 
# Sync amd64 and i386 config files and apt caches
cp $CHROOT64/etc/apt/sources.list $CHROOT32/etc/apt/sources.list
chroot $CHROOT32 apt-get update
 
# Get all the packages
chroot $CHROOT64 apt-get update
chroot $CHROOT64 apt-get -d --yes --reinstall  install $PACKAGES
 
# Move i386 packages to the i386 chroot environment and get all dependencies
cp -f $CHROOT64/var/cache/apt/archives/*_i386.deb $CHROOT32/var/cache/apt/archives/
PACKAGES_i386=$(cd $CHROOT32/var/cache/apt/archives/ && ls -1 *.deb | cut -d'_' -f1)
chroot $CHROOT32 apt-get -d --yes --reinstall install $PACKAGES_i386
 
# Apt-move i386 chroot
chroot $CHROOT32 bash -c "export LANG=C ; apt-move get"
chroot $CHROOT32 bash -c "export LANG=C ; apt-move move"
chroot $CHROOT32 bash -c "export LANG=C ; apt-move packages"
chroot $CHROOT32 apt-get autoclean
 
# Apt-move amd64 chroot
chroot $CHROOT64 bash -c "export LANG=C ; apt-move get"
chroot $CHROOT64 bash -c "export LANG=C ; apt-move move"
chroot $CHROOT64 bash -c "export LANG=C ; apt-move packages"
chroot $CHROOT64 apt-get autoclean
 
# Generate Release files
/usr/local/sbin/generate_release_files.sh -a /var/local/mirrors-agregated/ubuntu/dists/precise

Eso es todo. Ejecuta update_mirror.sh upgrade para crear la primera versión de tu repositorio multiarquitectura.

Añadir paquetes sueltos al repositorio

Sigamos peleándonos con apt-move. En teoría puedes decirle movefile esto y moverá archivos sueltos al repositorio, pero en la práctica no, los ignora. Apt-move es así, hay que quererle como es.

La mejor opción para añadir paquetes sueltos al repositorio es escapar de apt-move creando un repositorio local, añadir los paquetes ahí, y dejar que apt-move coja los paquetes como si se tratara de cualquier otro repositorio.

Para ello instalamos reprepro.

apt-get install reprepro

Hacemos un directorio local donde almacenar la configuración y el repositorio. Debe estar colgando del entorno chroot:

mkdir -p /var/local/chroot-amd64/var/local/local-repository/conf

Creamos allí tres archivos con la configuración:

distributions
Origin: Ubuntu-CITIUS-local
Label: Ubuntu CITIUS 12.04 Local Repository
Codename: precise
Architectures: amd64
Components: main
Description: Apt repository for local packages
DebOverride: override.precise
DscOverride: override.precise
SignWith: # Rellenar con el ID de la clave para firmar los paquetes
options
verbose
basedir /var/local/local-repository

En el tercer archivo se añadirán los paquetes del repositorio con alguna metainformación que se puede editar. Creamos el archivo vacío por ahora:

touch /var/local/chroot/var/local/local-repository/conf/override.precise

Cubre el archivo distributions con el ID de la clave privada, que por si a estas alturas ya has perido, puedes obtener con el comando gpg –list-keys.

Ahora, para añadir paquetes al repositorio:

reprepro -b /var/local/chroot/var/local/local-repository includedeb precise /ruta/al/archivo/debian.deb

Ahora podríamos añadir sin más el repositorio en el sources.list del entorno chroot, pero no. Debemos servirlo por HTTP, porque sino apt no cachea los archivos copiándolos a /var/cache/apt/archives al instalarlos, y apt-move no los encontrará. Suponemos que has hecho lo que se indica en la sección Servir el repositorio mediante HTTP. Ahora solo resta hacer un enlace:

ln -s /var/local/chroot-amd64/var/local/local-repository /var/local/

Y añadirlo en la configuración del lighttpd, al final del archivo /etc/lighttpd/lighttpd.conf:

$HTTP["host"] == "localhost" {
  server.document-root = "/var/local/local-repository/"                              
}

Reinicia lighttpd:

/etc/init.d/lighttpd restart

Y ahora sí, toca agregar al entorno chroot al repositorio local, para que pueda instalar paquetes desde allí. Agregamos la siguiente línea al archivo /var/local/chroot/.

deb http://localhost precise main

Un pequeño extra. Podemos comprobar que el paquete aparece en el apt del entorno chroot, y que la versión almacenada allí es la candidata para la instalación. En nuestro caso, un paquete opensc que incluye los drivers para el DNIe:

$ sudo chroot /var/local/chroot-amd64 apt-get update
$ sudo chroot /var/local/chroot-amd64 apt-cache policy opensc
opensc:
  Instalados: (ninguno)
  Candidato:  0.12.2-2ubuntu1
  Tabla de versión:
     0.12.2-2ubuntu1 0
        500 http://fr.archive.ubuntu.com/ubuntu/ precise/universe amd64 Packages
     0.12.1-1ubuntu1~svn385 0
        500 file:/var/local/local-repository/ precise/main amd64 Packages

Como en este caso está pero nuestra versión es inferior a la incluida con Ubuntu y tiene la misma prioridad, nuestra versión nunca se instalará. tenemos dos opciones: o bien modificar la puntuación de los paquetes (algo que no entraremos a detallar aquí) o especificar la versión a la hora de añadirlo al repositorio. Por ejemplo, para este caso:

$ sudo update_mirror.sh install opensc=0.12.1-1ubuntu1~svn385

Crear metapaquetes

Puedes crear metapaquetes y meterlos en tu repositorio local. Para ello necesitas equivs:

$ sudo apt-get install equivs

Agora, crea a plantilla con:

$ equivs-control nome-do-paquete

Crearase un arquivo nome-do-paquete que debes encher co nome do paquete, a descrición, a versión e as dependencias. Unha vez feito, crea o paquete con:

$ equivs-build nome-do-paquete

Enlaces externos