IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Creació de paquets Debian

De SergiTurWiki
Share/Save/Bookmark
Revisió de 15:01, 31 gen 2012; Sergi (Discussió | contribucions)

(dif) ←Versió més antiga | Versió actual (dif) | Versió més nova→ (dif)
Dreceres ràpides: navegació, cerca
https://wiki.ubuntu.com/PackagingGuide
http://www.cs.rug.nl/~jurjen/DebPackaging/
Alert.png Aquesta wiki forma part dels materials d'un curs
Curs: LinuxProgramacio
Fitxers: CreacioPaquetsDebian.pdf (CreacioPaquetsDebian.odp)
Repositori SVN: https://anonymous@svn.projectes.lafarga.cat/svn/iceupc/LinuxProgramacio
Usuari: anonymous
Paraula de pas: sense paraula de pas
Autors: Sergi Tur Badenas

Contingut

Introducció

Tipus de paquets

Hi ha dos tipus de paquets Debian:

Recursos:

  • Debian policy manual

Paquets font

Són més complicats que els binaris. Consulteu l'article Debian Source Packages.

Paquets Binaris

Aquest tipus de paquets contenen una sèrie de fitxers a instal·lar en el sistema

Aquests tipus de fitxers tenen la extensio deb:

.deb

I normalment són gestionats i interpretats per l'aplicació dpkg (tot i que sovint els usuaris finals utilitzem front-ends de dpkg com apt, aptitude o synaptic). L'aplicació dpkg és una aplicació fonamental a Debian i distribucions basades en Debian com Ubuntu

NOTA: Podeu utilitzar altres aplicacions a més de dpkg com per exemple GDebi/gdebi-gtk

Els paquets Debian es poden crear manualment des de zero (consulteu l'apartat Exemple pas a pas per crear un paquet Hola Mon! Debian manualment). Aquesta última opció és massa artesanal i només serveix com a exemple didàctic. És més habitual utilitzar l'ordre:

$ dpkg -b path_to_foo package_name.deb
NOTA: -b és l'opció build i path_to_foo és una carpeta que conté els fitxers a instal·lar i una carpeta DEBIAN amb la informació de control. Aquesta carpeta conté metadades i fitxers que no s'instal·len directament al sistema (nota: en tot cas els fitxers s'emmagatzemen en bases de dades/cache d'eines com apt). Consulteu: Creació de paquets Debian binaris amb dpkg -b

Cal a dir però que aquesta última opció també es força artesanal. El més normal és utilitzar eines de suport com dh_make, dpkg-buildpackage, deb-helpers, debreate... En aquest article s'expliquen els detalls de com crear paquets Debian, pels impacients podeu provar amb l'apartat:

 Creació d'un paquet Debian. Servidor d'echos
NOTA: L'ordre dpkg no instal·la les dependencies del paquet, de fet no te cap opció per descarregar fitxers. Aquesta tasca s'ha de fer manualment o de forma assistida/automàtica amb eines com apt-get que obtenen els paquets i les seves dependències dels repositoris de paquets. Cal indicar però que apt acaba utilitzant dpkg per fer tasques com la instal·lació o desinstal·lació del paquet

Nom dels fitxers Debian

El format del fitxer .deb és el següent:

<nom_del_paquet>_<numero_de_versio>-<numero_de_revisio_debian>.deb

El número de versió és especificat pel desenvolupador de l'aplicació. (Crec que) No hi ha un estàndard i ens podem trobar diferents tipus de codificacions com "19990513" o "1.3.8pre1".

El número de revisió de Debian és especificat pel desenvolupador Debian (o per qui realment crei el paquet). Aquest número es correspon amb el nivell de revisió del paquet Debian. En el cas de que sigui un paquet Ubuntu aquí trobarem la versió d'Ubuntu.

També es convenient indicar l'arquitectura del microprocessador als paquets binaris. Així es normal trobar noms com:

foo_i386.deb 

Fent referència a l'arquitectura i386 o:

foo_amd64.deb

fent referència a l'arquitectura amd64. A la carpeta:

/var/cache/apt/archive

Podeu trobar els paquets que teniu en cache local (p.ex. paquets que heu instal·lat recentment amb apt-get o aptitude)

$ ls -la /var/cache/apt/archive
total 7036
drwxr-xr-x 3 root root   40960 2011-06-23 08:01 .
drwxr-xr-x 3 root root    4096 2011-06-23 08:00 ..
-rw-r--r-- 1 root root   65538 2007-06-22 18:03 apg_2.2.3.dfsg.1-2_amd64.deb
-rw-r--r-- 1 root root   83294 2009-12-18 07:04 dctrl-tools_2.14_amd64.deb
-rw-r--r-- 1 root root 1844280 2010-07-26 11:05 debian-policy_3.9.1.0_all.deb
-rw-r--r-- 1 root root  596430 2010-08-20 08:05 devscripts_2.10.67ubuntu1_amd64.deb
-rw-r--r-- 1 root root   40752 2010-06-04 18:05 dh-make_0.55_all.deb
-rw-r--r-- 1 root root   49434 2010-07-16 10:07 dput_0.9.6.1ubuntu1_all.deb
-rw-r--r-- 1 root root   75664 2011-04-13 09:09 gosa-help-en_2.7.1-1_all.deb
-rw-r--r-- 1 root root   61160 2011-04-13 09:09 gosa-plugin-dhcp_2.7.1-1_all.deb
...

Estructura d'un paquet binari

NOTA: TODO Pendent de documentar, creac que en els nous paquets hi ha un format diferent!

Cada paquet Debian és un arxiu ar compost per:

  • data.tar.gz: Fitxers a instal·lar al sistema
  • control.tar.gz: Scripts de manteniment i metadades
  • debian-binary: Número de versió del binari Debian

Ark.png

GestordArxius.png

El fitxer control.tar.gz conté les metadades del paquet. Dins d'aquest paquet hi podem trobar fitxers com:

GestordArxius1.png

El fitxer control conté les metadades. Per exemple el fitxer control del paquet apache2.2-common:

Package: apache2.2-common
Version: 2.2.3-3.2build1
Section: web
Priority: optional
Architecture: i386
Depends: apache2-utils, net-tools, libmagic1, mime-support, lsb-base
Conflicts: apache2-common, libapache2-mod-php5 (<= 5.1.6-3), libapache2-mod-php4 (<= 4:4.4.4-2), libapache2-mod-mime-xattr (<= 0.3-2),     
libapache2-mod-mono (<= 1.1.17-3), libapache2-mod-proxy-html (<= 2.4.3-2), libapache2-mod-scgi (<= 1.11-1), libapache2-mod-speedycgi (<= 2.22-3),  
libapache2-modxslt (<= 2005072700-1), libapache2-redirtoservername (<= 0.1-1), libapache2-webauth (<= 3.5.3-1), libapache2-webkdc (<= 3.5.3-1)
Replaces: apache2-common
Installed-Size: 3460
Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
Original-Maintainer: Debian Apache Maintainers <debian-apache@lists.debian.org>
Source: apache2
Description: Next generation, scalable, extendable web server
Apache v2 is the next generation of the omnipresent Apache web server. This
version - a total rewrite - introduces many new improvements, such as
threading, a new API, IPv6 support, request/response filtering, and more.
.
It is also considerably faster, and can be easily extended to provide services
other than http.
.
This package contains all the standard apache2 modules, including SSL support.
However, it does *not* include the server itself; for this you need to
install one of the apache2-mpm-* packages; such as worker or prefork.

Que coincideix amb la informació que podeu trobar amb Synaptic si seleccioneu el paquet i amb el boto dret escolliu l'opció Propietats del menú Contextual:

PropietatsPaquetApache1.png

Els continguts d'aquests fitxers en el cas de Debian venen regulats per la Debian policy.

El fitxer md5sums conté les sumes de comprovació (checksums) que permeten comprovar que no hi ha cap diferència entre el paquet que tenim i l'original:

c4d71eca239992365ff6bb0dd2b087e6  usr/bin/krusader
a1bea18a70b85afac022cfe6e05d6b64  usr/share/icons/crystalsvg/22x22/apps/krusader_blue.png
29847c1108bc50911de6eb9e231fee69  usr/share/icons/crystalsvg/22x22/apps/krusader_root.png 
c963d8938d45793ed937abdf1f874685  usr/share/icons/crystalsvg/22x22/apps/krusader_shield.png
1d046e13a24bc4db374fdd599727b233  usr/share/icons/crystalsvg/22x22/apps/krusader_user.png
e2b220c05fa7c83b5f53e1843715cced  usr/share/icons/crystalsvg/22x22/apps/krusader_red.png
.............

La resta de fitxers són els scripts de manteniment (postrm, postinst, etc) que s'expliquen en més detall en un altre apartat.

Recursos:

Extreure els fitxers de dades d'un paquet binari

Ho podeu fer amb:

$ dpkg --fsys-tarfile packagename.deb > tarfile.tar

Per exemple, us podeu baixar un paquet Debian sense instal·lar-lo amb l'ordre apt-get i l'opció -d/--download-only:

$ sudo apt-get -d hello

Els paquets es guarden a /var/cache/apt/archives. Podeu extreure la informació de control amb:

$ dpkg --fsys-tarfile /var/cache/apt/archives/hello_2.5-1_amd64.deb > hello_2.5-1_amd64.tar

Ara ja teniu un paquet tar:

$ tar tf hello_2.5-1_amd64.tar 
./
./usr/
./usr/share/
./usr/share/doc/
./usr/share/doc/hello/
./usr/share/doc/hello/NEWS
./usr/share/doc/hello/copyright
./usr/share/doc/hello/changelog.gz
./usr/share/doc/hello/changelog.Debian.gz
./usr/share/info/
./usr/share/info/hello.info.gz
./usr/share/man/
./usr/share/man/man1/
./usr/share/man/man1/hello.1.gz
./usr/bin/
./usr/bin/hello

Extreure informació de control d'un paquet binari

Ho podeu fer amb:

$ dpkg -e packagename.deb 

Per exemple, us podeu baixar un paquet Debian sense instal·lar-lo amb l'ordre apt-get i l'opció -d/--download-only:

$ sudo apt-get -d hello

Els paquets es guarden a /var/cache/apt/archives. Podeu extreure la informació de control amb:

$ sudo dpkg -e /var/cache/apt/archives/hello_2.5-1_amd64.deb 
NOTA: Observeu que a l'exemple s'està utilitzant un sistema amb arquitectura amd64, el vostre fitxer pot ser diferent (per exemple per a l'arquitectura i386)
$ ls
DEBIAN
$ ls DEBIAN
control
$ cat DEBIAN/control 
Package: hello
Version: 2.5-1
Architecture: amd64
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Santiago Vila <sanvila@debian.org>
Installed-Size: 648
Depends: libc6 (>= 2.3.4), dpkg (>= 1.15.4) | install-info
Section: devel
Priority: optional
Homepage: http://www.gnu.org/software/hello
Description: The classic greeting, and a good example
 The GNU hello program produces a familiar, friendly greeting.  It
 allows non-programmers to use a classic computer science tool which
 would otherwise be unavailable to them.
 .
 Seriously, though: this is an example of how to do a Debian package.
 It is the Debian version of the GNU Project's `hello world' program
 (which is itself an example for the GNU Project).
NOTA: opcionalment (si el paquet els utilitza) també poden aparèixer altres fitxers com els fitxer postinst o similars

Fitxers GNU ar

La comanda ar la proporciona el paquet binutils:

$ dpkg -S /usr/bin/ar
binutils: /usr/bin/ar

Vegeu també ar.

Per crear un paquet Debian en ar executeu:

$ ar -r your-package-name.deb debian-binary control.tar.gz data.tar.gz

On el nom del paquet creat serà your-package-name.deb i heu de tenir ja preparats els fitxers debian-binary control.tar.gz data.tar.gz a la carpeta on executeu l'ordre.

Exemple pas a pas per crear un paquet Debian Hola mon des de zero

$ mkdir hola_deb
$ cd hola_deb/
$ mkdir -p usr/bin
$ joe usr/bin/hola

Poseu el següent:

#!/bin/bash
echo "Hola mon!"

Feu-lo executable:

$ chmod +x usr/bin/hola

Ara ja el podeu empaquetar i comprimir:

$ tar czvf data.tar.gz usr/bin

Ara preparem el fitxer de control:

$ joe control

Podeu adaptar el contingut a partir de la següent plantilla (la qual és molt simple):

Package: hola
Version: 0.1
Priority: optional
Architecture: all
Installed-Size: TODO
Maintainer: Sergi Tur <sergi.tur@upc.edum>
Description: Paquet hola mon! 

 Bla bla bla bla bla la bla...
 asd
 asdads

Podeu calcular la mida dels fitxers quan els tingueu tots i executant:

du -ks usr|cut -f 1

Empaqueteu-lo i comprimiu-lo:

$ tar czvf control.tar.gz control

Finalment cal crear l'últim fitxer:

$ echo 2.0 > debian-binary

I ara fem l'empaquetament final amb ar:

$  ar -r hola.deb debian-binary control.tar.gz data.tar.gz

Ja el podeu instal·lar amb:

$ sudo dpkg -i hola.deb

Creació de paquets binaris. dpkg -b

Anem a veure un exemple molt bàsic (i molt tonto ;-)) de com crear un paquet bàsic. La comanda que volem executar és:

$ dpkg -b carpeta_preparada_amb_fitxers_i_carpeta_DEBIAN paquet.deb
NOTA: Ordres com dpkg-buildpackage segueixen un circuit més complet per a la creació de paquets, però cal indicar que finalment una de les passes que executen és dpkg -b

Abans de poder executar l'ordre necessitem crear una carpeta que ha de contenir els fitxers a instal·lar i una carpeta DEBIAN amb la informació de control. Farem un exemple minimalista que instal·la un sol fitxer (un fitxer de text README).

NOTA: Cal tenir en compte que aquest exemple tonto no passaria cap estàndard de qualitat ni tampoc compliria la Debian Policy però és útil com a exemple didàctic

Primer preparem una carpeta de treball:

$ cd
$ mkdir paquetDebianTonto && cd paquetDebianTonto

Ara creem l'estructura necessària, al paquet l'anomenarem foo:

$ mkdir foo 
$ mkdir -p foo/usr/share/doc/foo
$ joe 2011  joe usr/share/doc/foo/README

Ompliu el fitxer README amb qualsevol text d'exemple. Ara creem la carpeta amb la informació de control:

$ mkdir foo/DEBIAN

I el fitxer mínim que ha de contenir (fitxer control):

$ joe foo/DEBIAN/control

Poseu els camps mínims (consulteu la Policy):

Package: foo
Version: 1
Architecture: all
Maintainer: Sergi Tur          
Description: Descripció curta 
 Descripció llarga? 
IMPORTANT: Cal posar el fitxer exactament igual que a l'exemple, per exemple cal deixar un espai al principi de la última línia

Ara ja podem crear el paquet (amb però algun warning):

$ dpkg -b foo
dpkg-deb: s'està construint el paquet «foo» en «foo.deb».

Ara ja teniu un mínim paquet anomenat foo.deb:

$ ls -l
total 8
drwxrwxr-x 4 sergi sergi 4096 2011-06-23 17:48 foo
-rw-r--r-- 1 sergi sergi  654 2011-06-23 18:01 foo.deb

O podeu comprovar amb l'eina file:

$ file foo.deb 
foo.deb: Debian binary package (format 2.0)

Proveu d'instal·lar-lo:

$ sudo dpkg -i foo.deb 
(S'està llegint la base de dades … hi ha 270127 fitxers i directoris instal·lats actualment.)
S'està preparant per a reemplaçar foo 1 (fent servir foo.deb) …
S'està desempaquetant el reemplaçament de foo …
S'està configurant foo (1) …

Podeu comprovar la instal·lació amb:

$ dpkg -L foo
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/foo
/usr/share/doc/foo/README
$ ls -la /usr/share/doc/foo/README
-rw-rw-r-- 1 sergi sergi 30 2011-06-23 17:47 /usr/share/doc/foo/README
IMPORTANT: Oco! Observeu un problema important! El sistema instal·la els fitxers amb el nom de l'usuari i permisos que tenien al ser creats abans de crear el paquet! Aquesta és una qüestió important que es soluciona amb eines més avançades de creació de paquets com dpgk-buildpackage

Metadades

Podem consultar les metadades d'un paquet Debian mitjançant la comanda:

$ dpkg --info talk_0.17-11ubuntu1_i386.deb 
paquet de debian nou, versió 2.0.
mida 21638 bytes: arxiu de control= 1084 bytes.
    611 bytes,    17 línies     control              
    449 bytes,     7 línies     md5sums              
    357 bytes,    14 línies  *  postinst             #!/bin/sh
    158 bytes,     8 línies  *  prerm                #!/bin/sh
Package: talk
Version: 0.17-11ubuntu1
Section: net
Priority: optional
Architecture: i386
Depends: libc6 (>= 2.5-0ubuntu1), libncurses5 (>= 5.4-5), update-inetd, openbsd-inetd | inet-superserver
Suggests: talkd
Replaces: netstd
Installed-Size: 88
Maintainer: Ubuntu MOTU Developers <ubuntu-motu@lists.ubuntu.com>
Original-Maintainer: Alberto Gonzalez Iniesta <agi@inittab.org>
Source: netkit-ntalk
Description: Chat with another user
 Talk is a visual communication program which copies lines from your terminal
 to that of another user.
 .
 In order to talk locally, you will need to install the talkd package.  

Les metadades s'enmagatzemen al fitxer control de dins del fitxer comprimit control.tar.gz d'un fitxer debian binary.

La Debian Policy determina com s'han d'utilitzar els camps del fitxer control.

Recursos:

Scripts de manteniment

Durant la instal·lació o desinstal·lació d'un paquet Debian no simplement s'instal·len o s'eliminen fitxers al sistema, sinó que també es duen a terme diferents accions per configurar el paquets. Aquestes accions les duen a terme el següents scripts de manteniment:

  • preinst: S'executa abans d'extreure els fitxers del paquet al sistema.
  • postinst: S'executa després d'extreure els fitxers del sistema.
  • prerm: S'executa abans d'esborrar els fitxers del sistema.
  • postrm: S'executa després d'esborrar els fitxers del sistema
  • config: Fitxer de configuració de Debconf.
  • templates: Plantilles de Debconf.

Tots aquests fitxers es troben dins del fitxer control.tar.gz d'un paquet Debian. Durant el procés de construcció del paquet, els fitxers es troben a la carpeta debian.

La següent gràfica mostra quan s'executen aquests scripts.

ScriptsManteniment.png

La Debian Policy determina com s'han d'utilitzar els scripts de manteniment. Si consulteu l'enllaç anterior a més veureu que hi han altres scripts de manteniment a part dels esmentats.

Recursos:

Relacions entre paquets

  • El paquet A depèn del Paquet B: Implica que és absolutament necessari que el paquet B estigui instal·lat abans de poder instal·lar A. També inclús pot ser que A depengui d'una versió especifica de B.
  • El paquet A recomana B: B no és necessari però el desenvolupador de A creu que la majoria d'usuaris d'A trobaran útil B
  • El paquet A suggereix B: El paquet A suggereix el B per què B conté funcionalitats relacionades amb A (i que sovint el milloren la seva funcionalitat).
  • El paquet A entra en conflicte amb el paquet B: El paquet A no pot operar al sistema si existeix B. Sovint per què tots dos proporcionen el mateix fitxer.
  • El paquet A reemplaça B: A l'instal·lar A s'esborren els fitxers de B i en alguns casos es sobreescriuen.
  • El paquet A proveeix de B: Quan tots els fitxers i funcionalitats de B han estar incorporades a A.

Recursos:

Importància d'un paquet

  • Required: Paquets imprescindibles per al correcte funcionament del sistema. Això inclou totes les eines necessàries per reparar els defectes d'un sistema. Sense aquests paquets el sistema estarà trencat i no es podrà utilitzar dpkg per arreglar-lo. Els sistemes que només tenen paquets requerits no són utilitzables, però tenen les suficients funcionalitats per permetre que l'administrador del sistema pugui iniciar la màquina i instal·lar més programari.
  • Important: Paquets que s'haurien de trobar en tot sistema. Aquests paquets no inclouen Emacs o X11 o TeX ni cap altre "gran" aplicació. Aquests paquets només constitueixen la infraestructura bàsica.
  • Standard: Els paquets Standard, són aquells paquets mínims que s'haurien de trobar a tota màquina. Hi han les eines bàsiques per navegar per la web (w3m), enviar correus electrònics (mutt) o descarregar fitxers o servidors FTP. Aquests paquets (i els de prioritat superior) són els que s'instal·len per defecte. No inclou moltes aplicacions importants.
  • Optional: Paquets que possiblement molta gent voldrà instal·lar però que no són imprescindibles pel sistema. Aquí trobem paquets tant importants com X11.
  • Extra: Paquets que entren en conflicte amb altres de major prioritat però que en certes condicions els usuaris poden preferir.

Una instal·lació per defecte de Debian instal·la tots els paquets de prioritat Standard o superior.

Recursos:

Utilitats

Paquet dpkg-dev

$ sudo dpkg -L dpkg-dev | grep bin
/usr/bin
/usr/bin/dpkg-architecture
/usr/bin/dpkg-genchanges
/usr/bin/dpkg-source
/usr/bin/dpkg-buildpackage
/usr/bin/dpkg-parsechangelog
/usr/bin/dpkg-gensymbols
/usr/bin/dpkg-name
/usr/bin/dpkg-vendor
/usr/bin/dpkg-distaddfile
/usr/bin/dpkg-gencontrol
/usr/bin/dpkg-shlibdeps
/usr/bin/dpkg-scanpackages
/usr/bin/dpkg-checkbuilddeps
/usr/bin/dpkg-scansources


dpkg-architecture

dpkg-genchanges

dpkg-source

IMPORTANT: Consulteu Debian source package format

Segons el manual:

$ man dpgk-source
...
dpkg-source - Debian source package (.dsc) manipulation tool

SYNOPSIS
      dpkg-source [options] command

DESCRIPTION
      dpkg-source packs and unpacks Debian source archives.

És l'ordre encarregada de crear els fitxers font de Debian.

Els fitxer dsc (sigles de Debian source control files...)

Hi ha diferents formats, el format que es vol utilitzar es pot indicar amb l'opció --format o especificant-ho al fitxer:

debian/source/format
NOTA: Actualment (--acacha 13:35, 23 juny 2011 (UTC)) la versió per defecte que apareix a aquest fitxer és 3.0 (quilt). Si no s'indica res el valor utilitzat és 1.0 però no s'hauria de fer (comportament deprecat)

Esta ordre és utilitzada per l'ordre dpkg-buildpackage com un de les subaccions a realitzar a l'hora de crear un paquet. De fet el que s'executa és l'ordre que permet construir el paquet font (vegem un exemple):

$ dpkg-buildpackage 
dpkg-buildpackage: export CFLAGS from dpkg-buildflags (origin: vendor): -g -O2
...
dpkg-source --before-build highschoolusers-0.1
fakeroot debian/rules clean
dh clean 
  dh_testdir
  dh_auto_clean
  dh_clean
dpkg-source -b highschoolusers-0.1
dpkg-source: info: using source format `3.0 (quilt)'
dpkg-source: info: building highschoolusers using existing ./highschoolusers_0.1.orig.tar.gz
dpkg-source: warning: executable mode 0775 of 'convert_to_ldif.sh' will not be represented in diff
dpkg-source: warning: file highschoolusers-0.1/add_schema.php has no final newline 
...

L'ordre pot donar diversos tipus de errors i avisos (warnigs). Els més comuns són:

dpkg-source: error: cannot represent change to XXXX

Per exemple:

dpkg-source: error: cannot represent change to highschoolusers-0.1/usr/share/gosa/html/pdfreports/images/signature.jpeg: binary file contents changed

executable mode perms of file will not be represented in diff o

special mode perms of file will not be represented in diff

TODO: Patch files do not record permissions of files and thus modified permissions are not stored in the source package. This warning reminds you of that fact.


Segons el manual:

$ man dpkg-source
...
WARNINGS AND ERRORS
   no source format specified in debian/source/format
       The file debian/source/format should always exist and indicate the desired source format. For backwards compatibility,  format  "1.0"  is   assumed
      when  the  file  doesn't  exist  but  you should not rely on this: at some point in the future dpkg-source will be modified to fail when that file
      doesn't exist.

      The rationale is that format "1.0" is no longer the recommended format, you should usually pick one of the  newer  formats  ("3.0  (quilt)",  "3.0
      (native)")  but dpkg-source will not do this automatically for you.  If you want to continue using the old format, you should be explicit about it
      and put "1.0" in debian/source/format.

  the diff modifies the following upstream files
      When using source format "1.0" it is usually a bad idea to modify upstream files directly as the changes end up hidden and mostly undocumented  in
      the .diff.gz file. Instead you should store your changes as patches in the debian directory and apply them at build-time. To avoid this complexity
      you can also use the format "3.0 (quilt)" that offers this natively.

  cannot represent change to file
      Changes to upstream sources are usually stored with patch files, but not all changes can be represented with patches: they can only alter the con‐
      tent  of  plain text files. If you try replacing a file with something of a different type (for example replacing a plain file with a symlink or a
      directory), you will get this error message.

  newly created empty file file will not be represented in diff
      Empty files can't be created with patch files. Thus this change is not recorded in the source package and you are warned about it.

  executable mode perms of file will not be represented in diff
  special mode perms of file will not be represented in diff
      Patch files do not record permissions of files and thus modified permissions are not stored in the source package. This  warning  reminds  you  of
      that fact.

Hi ha una sèrie de fitxers que poden modificar el comportament de dpkg-source al crear un paquet. Són:

Més informació a la secció FILE FORMATS del manual de dpkg-source.

dpkg-buildpackage

Vegeu també Debuild
IMPORTANT: Per poder executar dpkg-buildpackage amb el format Debian 3.0 (quilt) cal tenir un fitxer orig.tar sinó us donarà l'error
$ dpkg-buildpackage 
...
dpkg-source -b ubuntucustom-0.1
dpkg-source: error: can't build with source format '3.0 (quilt)': no orig.tar file found
dpkg-buildpackage: error: dpkg-source -b ubuntucustom-0.1 gave error exit status 255

Aleshores el que heu de fer es crear prèviament el fitxer NOMPAQUET_VERSIO.orig.tar.gz. Es simplement fer una copia del tar.gz original:

/bin/cp NOMPAQUET-VERSIO.tar.gz NOMPAQUET_VERSIO.orig.tar.gz
IMPORTANT: El paquet original es crearà d'una carpeta anomenada (és obligatori per què funcioni!) NOMPAQUET-VERSIO. Observeu el guió normal! En canvi el orig ha de ser amb guió baix!

Un cop és té una carpeta Debian preparada per construir el paquet (consulteu dh_make) l'ordre dpkg-buidpackage crea el paquet:

$ fakeroot
# dpkg-buidpackage
NOTA: Aquesta ordre sempre s'ha d'executar dins d'una carpeta que compleixi la Debian Policy. Podeu utilitzar dh_make per crear aquesta carpeta. Entre d'altre hi ha d'haver una carpeta debian (amb els fitxers necessaris: control, etc), cal tenir un Makefile i també que el nom de la carpeta compleixi una política de noms

Un altre exemple:

$ dpkg-buildpackage -uc -us -rfakeroot

On -r:

-rgain-root-command
             When dpkg-buildpackage needs to execute part of the build process as root, it prefixes the command it executes  with  gain-root-command  
             if one has been specified. Otherwise, if none has been specified, fakeroot will be used by default, if the command is present.  
             gain-root-command should start with the name of a program on the PATH and will get as arguments the name of the real command to run and 
             the arguments it should take.  gain-root-command can include parameters (they must be space-separated) but no shell metacharacters.  
             gain-root-command might typically be fakeroot, sudo, super or really.  su is not suitable, since it can only invoke the user's shell 
             with  -c  instead  of  passing arguments individually to the command to be run.

TODO:

Segons el manual:

$ man dpkg-buildpackage
...
NAME
      dpkg-buildpackage - build binary or source packages from sources

DESCRIPTION
      dpkg-buildpackage is a program that automates the process of building a Debian package. It consists of the following steps:
  1. It prepares the build environment by setting various environment variables (see ENVIRONMENT) and calls dpkg-source --before-build (unless -T or --target has been used).
  2. It checks that the build-dependencies and build-conflicts are satisfied (unless -d is specified).
  3. If a specific target has been selected with the -T or --target option, it calls that target and stops here. Otherwise it calls fakeroot debian/rules clean to clean the build-tree (unless -nc is specified).
  4. It calls dpkg-source -b to generate the source package (unless a binary-only build has been requested with -b, -B or -A).
  5. It calls debian/rules build followed by fakeroot debian/rules binary-target (unless a source-only build has been requested with -S). Note that binary-target is either binary (default case, or if -b is specified) or binary-arch (if -B is specified) or binary-indep (if -A is specified).
  6. It calls gpg to sign the .dsc file (if any, unless -us is specified).
  7. It calls dpkg-genchanges to generate a .changes file. Many dpkg-buildpackage options are forwarded to dpkg-genchanges.
  8. It calls gpg to sign the .changes file (unless -uc is specified).
  9. If -tc is specified, it will call fakeroot debian/rules clean again. Finally it calls dpkg-source --after-build.


Podeu veure un exemple d'ús a:

Creació_de_paquets_Debian#Creaci.C3.B3_d.27un_paquet_Debian._Servidor_d.27echos_.28echod.29

dpkg-parsechangelog

dpkg-gensymbols

dpkg-name

dpkg-vendor

dpkg-distaddfile

dpkg-shlibdeps

dpkg-scanpackages

dpkg-checkbuilddeps

dpkg-scansources

dpkg-gencontrol

Serveix per a generar el fitxer de control d'un paquet binari a partir d'un paquet font.

Del manual:

$ man dpkg-gencontrol
dpkg-gencontrol  reads  information  from  an  unpacked  Debian source tree and generates a
      binary package control file (which  defaults  to  debian/tmp/DEBIAN/control);  during  this
      process it will simplify the relation fields.

      Thus Pre-Depends, Depends, Recommends and Suggests are simplified in this order by removing
      dependencies which are known to be true according  to  the  stronger  dependencies  already
      parsed.  It  will  also  remove  any self-dependency (in fact it will remove any dependency
      which evaluates to true given the current version of the package as  installed).  Logically
      it keeps the intersection of multiple dependencies on the same package. The order of depen‐
      dencies is preserved as best as possible: if  any  dependency  must  be  discarded  due  to
      another dependency appearing further in the field, the superseding dependency will take the
      place of the discarded one.
      The other relation fields (Enhances, Conflicts, Breaks, Replaces  and  Provides)  are  also
      simplified  individually  by computing the union of the various dependencies when a package
      is listed multiple times in the field.

      dpkg-gencontrol also adds an entry for the binary package to debian/files.

OPTIONS
      -vversion
             Sets the version number of the binary package which will be generated.

      -Vname=value
             Set an output substitution variable. See deb-substvars(5) for discussion  of  output
             substitution.

      -Tsubstvarsfile
             Read substitution variables in substvarsfile; the default is debian/substvars.

Consulteu debian/substvars

deb-substvars

deb-substvars(5)                                              dpkg  utilities                                             deb-substvars(5)

NAME
      deb-substvars - Debian source substitution variables

SYNOPSIS
      substvars

DESCRIPTION
      Before  dpkg-source,  dpkg-gencontrol  and  dpkg-genchanges  write  their control information (to the source control file .dsc for
      dpkg-source and to standard output for dpkg-gencontrol and dpkg-genchanges) they perform some variable substitutions on the output
      file.

      A variable substitution has the form ${variable-name}.  Variable names consist of alphanumerics, hyphens and colons and start with
      an alphanumeric. Variable substitutions are performed repeatedly until none are left; the full text of the field after the substi‐
      tution is rescanned to look for more substitutions.

      After  all the substitutions have been done each occurrence of the string ${} (which is not a legal substitution) is replaced with
      a $ sign.

      While variable substitution is done on all control fields, some of those fields are used and needed during the build when the sub‐
      stitution did not yet occur. That's why you can't use variables in the Package, Source and Architecture fields.

      Variables  can  be set using the -V common option. They can be also specified in the file debian/substvars (or whatever other file
      is specified using the -T option). This file consists of lines of the form name=value.  Trailing whitespace on  each  line,  blank
      lines, and lines starting with a # symbol (comments) are ignored.

      Additionally, the following standard variables are available:

      Arch   The current build architecture (from dpkg --print-architecture).

      source:Version
             The source package version.

      source:Upstream-Version
             The upstream source package version, including the Debian version epoch if any.

      binary:Version
             The binary package version (which may differ from source:Version in a binNMU for example).

      Source-Version
             The  source package version (from the changelog file). This variable is now deprecated as its meaning is different from its
             function, please use the source:Version or binary:Version as appropriate.

      Installed-Size
             The total size of the package's installed files. This value is copied into the corresponding control file field; setting it
             will  modify  the  value  of  that  field. If this variable isn't set dpkg-gencontrol will use du -k debian/tmp to find the
             default value.

      Extra-Size
             Additional disk space used when the package is installed. If this variable is set  its  value  is  added  to  that  of  the
             Installed-Size  variable  (whether  set  explicitly or using the default value) before it is copied into the Installed-Size
             control file field.

      F:fieldname
             The value of the output field fieldname (which must be given in the canonical capitalisation). Setting these variables  has
             no effect other than on places where they are expanded explicitly.

      Format The  .changes  file  format version generated by this version of the source packaging scripts. If you set this variable the
             contents of the Format field in the .changes file will change too.

      Newline, Space, Tab
             These variables each hold the corresponding character.

      shlibs:dependencyfield
             Variable settings with names of this form are generated by dpkg-shlibdeps.

      dpkg:Upstream-Version
             The upstream version of dpkg.
       dpkg:Version
             The full version of dpkg.

      If a variable is referred to but not defined it generates a warning and an empty value is assumed.

FILES
      debian/substvars
             List of substitution variables and values.

BUGS
      The point at which field overriding occurs compared to certain standard output field settings is rather confused.

SEE ALSO
      dpkg(1), dpkg-genchanges(1), dpkg-gencontrol(1), dpkg-shlibdeps(1), dpkg-source(1).

AUTHOR
      Copyright © 1995-1996 Ian Jackson
      Copyright © 2000 Wichert Akkerman

      This is free software; see the GNU General Public Licence version 2 or later for copying conditions. There is NO WARRANTY.

Debian Project                                                  2008-08-18                                               deb-substvars(5)

install

Aquest ordre permet instal·lar un fitxer al sistema. Per instal·lar entenem:

  • Copiar un fitxer a la seva destinació final dins del sistema de fitxers
  • Establir els permisos del fitxer
  • Establir els propietaris

És a dir equival a executar en ordre les ordres:

cp
chmod
chown

Un exemple (part d'un fitxer makefile):

OWNER=root
GROUP=root
PROGRAM=echod
INSTALL=/usr/bin/install
BINDIR=/usr/sbin

...
$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 755 $(PROGRAM) $(BINDIR)

Es a dir esteu executant:

/usr/bin/install -c -o root -g root -m 755 echod /usr/sbin

Aquest ordre és força utilitzada en fitxers Makefile. Vegeu per exemple el Makefile de l'exemple del servidor d'ecos:

Creació_de_paquets_Debian#Creaci.C3.B3_d.27un_paquet_Debian._Servidor_d.27echos_.28echod.29

fakeroot

Fakeroot és al mateix temps un paquet i una ordre de sistema. Per instal·lar-lo:

$ sudo apt-get isntall fakeroot

Els executables són:

$ dpkg -L fakeroot | grep bin
/usr/bin
/usr/bin/fakeroot-tcp
/usr/bin/faked-tcp
/usr/bin/fakeroot-sysv
/usr/bin/faked-sysv

fakeroot utilitza alternatives:

$ ls -la /usr/bin/fakeroot
lrwxrwxrwx 1 root root 26 2010-03-26 17:24 /usr/bin/fakeroot -> /etc/alternatives/fakeroot

Segons el manual:

$ man fakeroot
NAME
      fakeroot - run a command in an environment faking root privileges for file manipulation

Simula que teniu privilegis de root per tal de poder manipular fitxers. Si executeu:

$ fakeroot
#

Us posa en un entorn que simula root (fitxeu-vos el simbol #). Això és útil per tal de poder crear fitxers tipus paquets ([ar]], tar, paquets Debian, etc) que dins continguin fitxers amb permisos i que siguin propietat de root (si no fos per fakeroor l'única forma de crear aquests fitxers seria entrar com a root al sistema). Per exemple s'utilitza conjuntament amb dpkg-buildpackage:

$ fakeroot
# dpkg-buildpackage
NOTA: Que simuli que sigueu root no vl dir que ho sigueu. De fet per evitar "efectes extranys" és molt important que un cop acabeu d'utilitzar les ordres que voleu executar a l'entorn fakeroot, en sortiu amb un exit.

fakeroot funciona canviar les funcions de manipulació de fitxers (chmod,stat, etc...) i el sistema temporalment veu els fitxers que son del vostre usuari com si fossin fitxers de root.

Vegeu també install.

Comanda patch

TODO

Recursos:

Comanda debdiff

Permet comparar fitxer debian. Veiem un exemple:

$ wget http://ch.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2-2_i386.deb
$ wget http://ch.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2-2_powerpc.deb
$ debdiff hello_2.2-2_i386.deb hello_2.2-2_powerpc.deb 
File lists identical (after any substitutions)
Can't compare control files; wdiff package not installed

Instal·lem doncs wdiff:

$ sudo apt-get install wdiff
$ debdiff hello_2.2-2_i386.deb hello_2.2-2_powerpc.deb 
File lists identical (after any substitutions) 

Control files: lines which differ (wdiff format)
------------------------------------------------
Architecture: [-i386-] {+powerpc+}
Installed-Size: [-584-] {+588+} 

Són fitxer debian idèntics però per a diferents arquitectures.

Recursos:

Comanda dpkg-source

Continuant amb l'exemple hello. Si descarreguem els fitxer font

$ wget http://ch.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2-2.dsc
$ wget http://ch.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2-2.diff.gz
$ wget http://ch.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2.orig.tar.gz

Ara podem crear la carpeta amb el codi font del paquet Debian amb:

$ dpkg-source -x hello_2.2-2.dsc

NOTA: Totes aquestes passes són equivalent a executar apt-source get.

Recursos:

Nota sobre Paquets Ubuntu

Així, la primera revisió de la versió 1.0 del paquet «dirhola» sería «dirhola_1.0-1» si és el primer cop que la versió 1.0 d'aquest paquet entra a Debian, «dirhola_1.0-2» si és la segona revisió, etc... A l'Ubuntu el nom és el mateix, però si es dóna el cas de que Ubuntu també hi fa canvis aquest últim passaria a ser «dirhola_1.0-2ubuntu1»; si troben algun altre problema doncs sortiria el paquet «dirhola_1.0-2ubuntu2», etc. En el cas de que un paquet estigui a l'Ubuntu però no a Debian el numero de revisio de debian es 0, per exemple «diradeu_0.1-0ubuntu1», si és el primer cop que es fa un paquet de la versió 0.1 del programa «diradeu» i aquesta només es fa a Ubuntu (o es fa independentment del de Debian, cas que també es pot donar).

Recursos:

  • Gràcies a Siegfried-Angel Gevatter Pujals (RainCT).

Debconf

http://www.fifi.org/doc/debconf-doc/tutorial.html

Debconf és una utilitat de programari que permet dur a terme tasques de configuració en sistemes Debian GNU/Linux. Debconf està molt lligat a dpkg.

Molt paquets al instal·lar-se iniciant una interfície amb l'usuari per demanar aquells paràmetres de configuració que creguin adients:

Debconf es proporcionat pel paquet del mateix nom. Executant:

$ dpkg -L debconf | grep bin
/usr/sbin
/usr/sbin/dpkg-preconfigure
/usr/sbin/dpkg-reconfigure
/usr/bin
/usr/bin/debconf
/usr/bin/debconf-apt-progress
/usr/bin/debconf-communicate
/usr/bin/debconf-copydb
/usr/bin/debconf-escape
/usr/bin/debconf-set-selections
/usr/bin/debconf-show

Podem veure quines són les comandes proporcionades per Debconf. La més important és dpkg-reconfigure que ens permet reconfigurar paquets ja instal·lats en el nostre sistema. Un del exemples més comuns és executar:

$ sudo dpkg-reconfigure xserver-xorg
NOTA: Des de que les X es configuren automàticament (--acacha 15:41, 25 gen 2011 (UTC)) aquesta comanda ja no és tant rellevant! De fet ara ja no fa absolutament res.

Que permet configurar el servidor X tal i com podeu veure a l'article Configurar_el_paquet_Debian_xserver-xorg.

Hi ha altres paquets relacionats amb debconf:

L'especificació de Debconf a la Debian Policy us pot donar més detalls sobre Debconf.

Vegeu també:

Recursos:

Manual

Debconf fa referència tant al paquet com a l'ordre especifica. Si voleu consultar el manual del paquet heu de consultar la secció 7 del manual:

$ man 7 debconf
NAME
      debconf - Debian package configuration system

DESCRIPTION
      Debconf is a configuration system for Debian packages. There is a rarely-used command named debconf, 
      documented in debconf(1)

      Debconf  provides  a consistent interface for configuring packages, allowing you to choose from several 
      user interface frontends. It supports preconfiguring packages
      before they are installed, which allows large installs and upgrades to ask you for all the necessary 
      information up front, and then go do the work while you do some‐
      thing else.  It lets you, if you're in a hurry, skip over less important questions and information while 
      installing a package (and revisit it later).

Preconfiguring packages
      Debconf  can  configure  packages  before they are even installed onto your system. This is useful because 
      it lets all the questions the packages are going to ask be
      asked at the beginning of an install, so the rest of the install can proceed while you are away getting a 
      cup of coffee.

      If you use apt (version 0.5 or above), and you have apt-utils installed, each package apt installs will  
      be  automatically  preconfigured.  This  is  controlled  via
      /etc/apt/apt.conf.d/70debconf

      Sometimes  you  might  want  to preconfigure a package by hand, when you're not installing it with apt. You 
      can use dpkg-preconfigure(8) to do that, just pass it the
      filenames of the packages you want to preconfigure. You will need apt-utils installed for that to work.

Reconfiguring packages
      Suppose you installed the package, and answered debconf's questions, but now that you've used it awhile,  
      you realize you want to go back  and  change  some  of  your answers.  In the past, reinstalling a package 
      was often the thing to do when you got in this situation, but when you reinstall the package, debconf seems 
      to remember you have answered the questions, and doesn't ask them again (this is a feature).

      Luckily, debconf makes it easy to reconfigure any package that uses it.  Suppose you want to reconfigure 
      debconf itself. Just run, as root:

         dpkg-reconfigure debconf

      This will ask all the questions you saw when debconf was first installed.  It may ask you other questions 
      as well, since it asks even low priority questions that may
      have been skipped when the package was installed.  You can use it on any other package that uses debconf, 
      as well.


Protocol Debconf

Les aplicacions que volen utilitzar debconf han d'utilitzar un protocol de comunicació amb debconf. Les comandes del protocol són:

  • VERSION: Normalment no cal utilitzar aquesta ordre. Indica quina versió del protocol s'utilitzarà per a la comunicació amb Debconf. La versió actual (--acacha 19:45, 31 gen 2011 (UTC)) del protocol és 2.0 i a més s'espera que les versions 2.x siguin compatibles enrere.
  • CAPB (capabilities): Vegeu capabilities (TODO)
  • TITLE: Estableix el títol que es mostrarà a l'usuari. Normalment no es toca ja que debconf pot posar un titol adient segons el nom del paquet.
  • SETTITLE: This sets the title to the short description of the template for the specified question. The template should be of type title. The advantage this has over the TITLE command is that it allows for titles to be stored in the same place as the rest of the debconf questions, and allows them to be translated.
  • INPUT priority question: priority indica la prioritat. Ask debconf to prepare to display a question to the user. The question is not actually displayed until a GO command is issued; this lets several INPUT commands be given in series, to build up a set of questions, which might all be asked on a single screen.
  • GO
  • CLEAR
  • BEGINBLOCK
  • ENDBLOCK
  • STOP
  • GET
  • SET
  • RESET
  • SUBST
  • FGET
  • FSET
  • METAGET
  • REGISTER
  • UNREGISTER
  • PURGE





      GO
             Tells debconf to display the accumulated set of questions (from INPUT commands) to the user.
             If the backup capability is supported and the user indicates they want to back  up  a  step,  debconf
             replies with code 30.
      CLEAR  Clears the accumulated set of questions (from INPUT commands) without displaying them.
      BEGINBLOCK
      ENDBLOCK
             Some  debconf frontends can display a number of questions to the user at once.  Maybe in the future a
             frontend will even be able to group these questions into blocks on screen.  BEGINBLOCK  and  ENDBLOCK
             can  be placed around a set of INPUT commands to indicate blocks of questions (and blocks can even be
             nested). Since no debconf frontend is so sophisticated yet, these commands are ignored for now.
      STOP   This command tells debconf that you're done talking to it. Often debconf can  detect  termination  of
             your program and this command is not necessary.
      GET question
             After  using  INPUT  and GO to display a question, you can use this command to get the value the user
             entered. The value is returned in the extended result code.
      SET question value
             This sets the value of a question, and it can be used to override the default  value  with  something
             your program calculates on the fly.
      RESET question
             This  resets  the  question  to its default value (as is specified in the 'Default' field of its tem‐
             plate).
      SUBST question key value
             Questions can have substitutions embedded in their 'Description' and 'Choices' fields (use of substi‐
             tutions  in  'Choices' fields is a bit of a hack though; a better mechanism will eventually be devel‐
             oped). These substitutions look like "${key}". When the question is displayed, the substitutions  are
             replaced with their values. This command can be used to set the value of a substitution. This is use‐
             ful if you need to display some message to the user that you can't hard-code in the templates file.
             Do not try to use SUBST to change the default value of a question; it won't work since there is a SET
             command explicitly for that purpose.
      FGET question flag
             Questions  can have flags associated with them. The flags can have a value of "true" or "false". This
             command returns the value of a flag.
      FSET question flag value
             This sets the value of a question's flag. The value must be either "true" or "false".
             One common flag is the "seen" flag. It is normally only set if a user has already  seen  a  question.
             Debconf  usually only displays questions to users if they have the seen flag set to "false" (or if it
             is reconfiguring a package).  Sometimes you want the user to see a question again -- in  these  cases
             you can set the seen flag to false to force debconf to redisplay it.
      METAGET question field
             This  returns  the value of any field of a question's associated template (the Description, for exam‐
             ple).
      REGISTER template question
             This creates a new question that is bound to a template. By default each template has  an  associated
             question  with  the  same name. However, any number of questions can really be associated with a tem‐
             plate, and this lets you create more such questions.
      UNREGISTER question
             This removes a question from the database.
      PURGE  Call this in your postrm when your package is purged. It removes all of your package's questions from
             debconf's database.


Al manual de debconf-devel trobareu una explicació de cada comanda. Les més importants (o les que utilitzem en els exemples d'aquest article):

  • VERSION: Estableix la versió. Utilitzem la versió 2.0
  • CAPB: Estableix les capacitats de DEBCONF. L'utilitzarem per establir la capacitat backup.
  • INPUT: Prepara una plantilla de debconf per tal de ser mostrada. Cada finestra té una certa prioritat.
  • GET: Obtenim el resultat de cridar a una plantilla. Depenent de la plantilla pot ser un resposta sí/no, un string, etc...
  • GO: Mostra la plantilla que em preparat amb INPUT.

Cada comanda té una funció equivalent en shell. Aquestes funcions són proporcionades per l'script de shell /usr/share/debconf/confmodule i els seus noms són:

$ db_comandadebconf

On comandadebconf és una comanda de debconf. Exemples:db_capb, db_version, db_get. També es podem comunicar amb debconf mitjançant altres llenguatges com Perl.

Backend Database

Vegeu també debconf-show

Extret del manual:

$ man 7 debconf

Backend Database
      Debconf uses a rather flexible and potentially complicated backend database for storing data such as the  
      answers to questions. The file /etc/debconf.conf is used  to configure  this  database. If you need to 
      set up something complicated, like make debconf read a remote database to get defaults, with local 
      overrides, read the debconf.conf(5) man page for all the gory details. Generally, the backend database is 
      located in /var/cache/debconf/

Podeu consultar doncs també el manual:

$ man 5 debconf.conf

La base de dades es troba a:

$ ls -la /var/cache/debconf/
total 4356
drwxr-xr-x  2 root root    4096 2011-01-25 16:38 .
drwxr-xr-x 21 root root    4096 2011-01-25 16:37 ..
-rw-r--r--  1 root root   50906 2011-01-25 16:38 config.dat
-rw-r--r--  1 root root   50832 2011-01-25 16:38 config.dat-old
-rw-------  1 root root    1594 2011-01-25 16:38 passwords.dat
-rw-r--r--  1 root root 2159293 2011-01-25 16:38 templates.dat
-rw-r--r--  1 root root 2159293 2011-01-25 16:38 templates.dat-old

Conm podeu veure hi ha un fitxer per guardar les variables de configuració utilitzades per qualsevol paquet del sistema amb debconf (/var/cache/debconf/config.dat).

Les paraules de pas es guarden a part al fitxer:

/var/cache/debconf/passwords.dat

Que com podeu veure només és accessible per l'usuari root.

I finalment també conté totes les plantilles debconf utilitzades al fitxer:

/var/cache/debconf/templates.dat

Depurant Debconf

Una eina molt útil per a identificar errors amb debconf és activar el mode DEBUG de debconf establint la variable d'entorn:

$ export DEBCONF_DEBUG=developer

Ara si executem l'script config tindrem més informació sobre l'execució:

$ sudo debian/config
debconf (developer): frontend started
debconf (developer): Trying to find a templates file..
debconf (developer): Trying ./config.templates
debconf (developer): Trying ./templates
debconf (developer): I guess it is ./templates
debconf (developer): frontend running, package name is 
debconf (developer): starting ./config
debconf (developer): <-- VERSION 2.0
debconf (developer): --> 0 2.0
................................

Prioritats de debconf

El paràmetre debconf/priority defineix la prioritat més alta dels missatges a mostrar per debconf.

Les prioritats (segons el manual són:)

$ man 7 debconf
Priorities
      Another  nice  feature of debconf is that the questions it asks you are prioritized. If you don't want to be
      bothered about every little thing, you can set up debconf to only ask you the most important questions.   On
      the other hand, if you are a control freak, you can make it show you all questions. Each question has a pri‐
      ority. In increasing order of importance:

      low    Very trivial questions that have defaults that will work in the vast majority of cases.

      medium Normal questions that have reasonable defaults.

      high   Questions that don't have a reasonable default.

      critical
             Questions that you really, really need to see (or else).

      Only questions with a priority equal to or greater than the priority you choose will be shown  to  you.  You
      can  set  the priority value by reconfiguring debconf, or temporarily by passing --priority= followed 
      by the value to the dpkg-reconfigure(8) and dpkg-preconfigure(8) commands, or by setting the 
      DEBIAN_PRIORITY  environment variable.
Important: La instal·lació predeterminada utilitza priority=high.

En aquest cas es mostraran els missatges amb prioritat high i critical, però s'anul·laran els missatges amb prioritat medium i low.

Aquests paràmetres s'utilitzen amb debconf i amb la instal·lació del sistema. Si utilitzeu el paràmetre d'arrencada priority=medium, se us mostrarà el menú d'instal·lació i disposareu de més control sobre la instal·lació. Quan s'utilitza el paràmetre priority=low es mostraran tots els missatges (és equivalent al mètode d'arrencada expert). En el cas de priority=critical, el sistema d'instal·lació mostrarà únicament els missatges crítics i procurarà fer la feina correctament sense mostrar missatges.

Per mostrar els missatges de totes les prioritats podeu especificar el llindar mínim amb dpkg-reconfigure:

$ sudo dpkg-reconfigure --priority=low phpmyadmin

Recursos:

Plantilles. Templates

THE TEMPLATES FILE
       A package that uses debconf probably wants to ask  some  ques‐
       tions.  These  questions  are stored, in template form, in the
       templates file.

       Like the config script, the templates file is put in the  con‐
       trol.tar.gz  section  of  a  deb.  Its  format is similar to a
       debian control file; a  set  of  stanzas  separated  by  blank
       lines, with each stanza having a RFC822-like form:

         Template: foo/bar
         Type: string
         Default: foo
         Description: This is a sample string question.
          This is its extended description.
          .
          Notice that:
           - Like in a debian package description, a dot
             on its own line sets off a new paragraph.
           - Most text is word-wrapped, but doubly-indented
             text is left alone, so you can use it for lists
             of items, like this list. Be careful, since
             it is not word-wrapped, if it's too wide
             it will look bad. Using it for short items
             is best (so this is a bad example).

         Template: foo/baz
         Type: boolean
         Description: Clear enough, no?
          This is another question, of boolean type.

       For   some   real-life   examples   of  templates  files,  see
       /var/lib/dpkg/info/debconf.templates,  and  other   .templates
       files in that directory.

       Let's look at each of the fields in turn..

       Template
              The  name  of the template, in the 'Template' field, is
              generally prefixed with the name of the package.  After
              that  the  namespace is wide open; you can use a simple
              flat layout like the one above, or set up  "subdirecto‐
              ries" containing related questions.

       Type   The type of the template determines what kind of widget
              is displayed to the user. The currently supported types
              are:

              string Results in a free-form input field that the user
                     can type any string into.

              password
                     Prompts the user for a password. Use  this  with
                     caution;  be  aware  that  the password the user
                     enters will be written  to  debconf's  database.
                     You  should probably clean that value out of the
                     database as soon as is possible.

              boolean
                     A true/false choice.

              select A choice between one of a number of values.  The
                     choices  must  be  specified  in  a  field named
                     'Choices'. Separate  the  possible  values  with
                     commas and spaces, like this:
                       Choices: yes, no, maybe

              multiselect
                     Like  the  select data type, except the user can
                     choose any number of items from the choices list
                     (or choose none of them).

              note   Rather  than  being  a  question  per  se,  this
                     datatype indicates a note that can be  displayed
                     to  the  user. It should be used only for impor‐
                     tant notes that  the  user  really  should  see,
                     since  debconf  will  go  to great pains to make
                     sure the user sees it; halting the  install  for
                     them  to  press  a  key.  It's best to use these
                     only for warning about  very  serious  problems,
                     and the error datatype is often more suitable.

              error  This  datatype  is used for error messages, such
                     as input validation errors.  Debconf will show a
                     question  of  this  type even if the priority is
                     too high or the user has already seen it.

              title  This datatype is used for titles, to be set with
                     the SETTITLE command.

              text   This datatype can be used for fragments of text,
                     such as labels, that can be  used  for  cosmetic
                     reasons in the displays of some frontends. Other
                     frontends will not use it at all.  There  is  no
                     point in using this datatype yet, since no fron‐
                     tends support it well. It may even be removed in
                     the future.

Interfícies de debconf

El paràmetre DEBIAN_FRONTEND és un paràmetre que defineix el tipus d'interfície d'usuari utilitzat durant les instal·lacions i també amb les configuracions amb Debconf. Els possibles paràmetres de configuració actuals per a la instal·lació del sistema són:

  • DEBIAN_FRONTEND=noninteractive: No hi ha interacció amb l'usuari.
  • DEBIAN_FRONTEND=text: Text per línia de comandes. readline és una opció equivalent.
  • DEBIAN_FRONTEND=newt
  • DEBIAN_FRONTEND=gtk: Entorn gràfic GTK
$ export DEBIAN_FRONTEND=readline

Si executem l'script, les preguntes es faran des de la línia de comandes:

$ sudo debian/config
Configuració del paquet «»

Please enter the hostname of the database server host.

Database server hostname: 8001

NOTA: Realment debconf utilitza les interfícies definides a la carpeta /usr/share/perl5/Debconf/FrontEnd:

$ ls
Dialog.pm  Editor.pm  Gnome.pm  Kde  Kde.pm  Noninteractive.pm  Passthrough.pm  Readline.pm  ScreenSize.pm  Teletype.pm  Text.pm  Web.pm

Per exemple per provar amb Gnome em d'executar:

$ export DEBIAN_FRONTEND=gnome
$ sudo debian/config

DebconfGnome.png

Per defecte, debconf utilitza Dialog és un conjunt d'eines que utilitzant ncurses per crear formularis d'interfície amb els usuaris per línia de comandes. Les pantalles es mostren si fa no fa de la següent forma:

DebconfDialog.png

Podeu provar la resta d'interfícies:

Dialog.pm  Editor.pm  Gnome.pm  Kde  Kde.pm  Noninteractive.pm  Passthrough.pm  
Readline.pm  ScreenSize.pm  Teletype.pm  Text.pm  Web.pm

Establint la variable d'entorn al nom del fitxer però en minúscules. Per exemple:

$ export DEBIAN_FRONTEND=kde

Recursos:

Ordres

$ sudo dpkg -L debconf | grep bin
/usr/sbin
/usr/sbin/dpkg-reconfigure
/usr/sbin/dpkg-preconfigure
/usr/bin
/usr/bin/debconf
/usr/bin/debconf-communicate
/usr/bin/debconf-set-selections
/usr/bin/debconf-copydb
/usr/bin/debconf-apt-progress
/usr/bin/debconf-show
/usr/bin/debconf-escape

ordre debconf

Un exemple per tal d'executar un programa de shell que utilitzi debconf:

debconf --frontend=readline sh -x my-shell-prog

TODO

dpkg-reconfigure

Consulteu dpkg-reconfigure

dpkg-preconfigure

Per defecte les últimes versions de apt, és a dir la versió 0.5 o superior (--acacha 16:10, 25 gen 2011 (UTC)) preconfiguren tots els paquets:

$ cat /etc/apt/apt.conf.d/70debconf
// Pre-configure all packages with debconf before they are installed.
// If you don't like it, comment it out.
DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt || true";};

debconf-show

Vegeu també Creació_de_paquets_Debian#Backend_Database

Mostra les variables establertes durant la configuració amb debconf per a un paquet (owner en terminologia debconf) específic:

$ sudo debconf-show phpmyadmin
  phpmyadmin/app-password-confirm: (password omitted)
  phpmyadmin/mysql/admin-pass: (password omitted)
  phpmyadmin/password-confirm: (password omitted)
  phpmyadmin/setup-password: (password omitted)
  phpmyadmin/mysql/app-pass: (password omitted)
  phpmyadmin/remove-error: abort
  phpmyadmin/setup-username: admin
* phpmyadmin/db/app-user: phpmyadmin
* phpmyadmin/install-error: ignore
* phpmyadmin/reconfigure-webserver: apache2
  phpmyadmin/remote/host:
* phpmyadmin/dbconfig-install: true
  phpmyadmin/remote/port:
  phpmyadmin/dbconfig-upgrade: true
* phpmyadmin/mysql/admin-user: root
  phpmyadmin/internal/reconfiguring: false
  phpmyadmin/missing-db-package-error: abort
  phpmyadmin/remote/newhost:
  phpmyadmin/upgrade-error: abort
  phpmyadmin/dbconfig-reinstall: false
* phpmyadmin/db/dbname: phpmyadmin
  phpmyadmin/database-type: mysql
  phpmyadmin/internal/skip-preseed: false
  phpmyadmin/upgrade-backup: true
  phpmyadmin/dbconfig-remove:
  phpmyadmin/passwords-do-not-match:
* phpmyadmin/mysql/method: unix socket
  phpmyadmin/purge: false

Es pot especificar una base de dades concreta:

$ sudo debconf-show phpmyadmin --db=passwords
* phpmyadmin/app-password-confirm: (password omitted)
* phpmyadmin/mysql/admin-pass: (password omitted)
  phpmyadmin/password-confirm: (password omitted)
  phpmyadmin/setup-password: (password omitted)
* phpmyadmin/mysql/app-pass: (password omitted)

Mostrar els paquets (owners en terminologia debconf):

$ sudo debconf-show --listowners

Mostrar les bases de dades de debconf :

$ sudo debconf-show --listdbs
configdb
configdb/config
configdb/passwords

debconf-communicate

Es pot utilitzar per comunicar-se amb debconf. Per exemple la comanda:

$ sudo -i 
$ echo get echod/port | debconf-communicate
0 8001

Ens retorna el resultat d'executar la qüestió echod/port.

Recursos:

debconf-apt-progress

Permet mostrar una barra de progrés:

$ sudo debconf-apt-progress -- aptitude -y install gnome x-window-system-dev

Exemples extrets del manual:

$ man debconf-apt-progress
...

Install the GNOME desktop and an X window system development
      environment within a progress bar:

       debconf-apt-progress -- aptitude -y install gnome x-window-system-dev

      Install the GNOME, KDE, and XFCE desktops within a single progress bar,
      allocating 45% of the progress bar for each of GNOME and KDE and the
      remaining 10% for XFCE:
       #! /bin/sh
        set -e
        case $1 in
          '')
            eval "$(debconf-apt-progress --config)"
            "$0" debconf
            ;;
          debconf)
            . /usr/share/debconf/confmodule
            debconf-apt-progress --start
            debconf-apt-progress --from 0 --to 45 -- apt-get -y install gnome
            debconf-apt-progress --from 45 --to 90 -- apt-get -y install kde
            debconf-apt-progress --from 90 --to 100 -- apt-get -y install xfce4
            debconf-apt-progress --stop
            ;;
        esac

debconf-set-selections

NOTA: Vegeu també l'ordre debconf-get-selections del paquet debconf-utils

La sintaxi és:

$ sudo debconf-set-selections file

On file és un fitxer que conté les seleccions per defecte. Permet fer una pre-configuració (pre-seed). Del manual:

$ man debconf-set-selections
...

NAME
      debconf-set-selections - insert new default values into the debconf database

SYNOPSIS
        debconf-set-selections file
        debconf-get-selections | ssh newhost debconf-set-selections

DESCRIPTION
      debconf-set-selections can be used to pre-seed the debconf database with answers, or to change answers in the database. Each question will be marked as seen to
      prevent debconf from asking the question interactively.

      Reads from a file if a filename is given, otherwise from stdin.

WARNING
      Only use this command to seed debconf values for packages that will be or are installed. Otherwise you can end up with values in the database for uninstalled
      packages that will not go away, or with worse problems involving shared values. It is recommended that this only be used to seed the database if the originating
      machine has an identical install.

...

Alguns exemple de fitxer:

# Force debconf priority to critical.
debconf debconf/priority select critical

# Override default frontend to readline, but allow user to select.
debconf debconf/frontend select readline
debconf debconf/frontend seen false

El format està indicat al manual:

 DATA FORMAT
       The data is a series of lines. Lines beginning with a # character are comments. Blank lines are ignored. All other lines set the value of one question, and
      should contain four values, each separated by one character of whitespace. The first value is the name of the package that owns the question. The second is the
      name of the question, the third value is the type of this question, and the fourth value (through the end of the line) is the value to use for the answer of the
      question.

      Alternatively, the third value can be "seen"; then the preseed line only controls whether the question is marked as seen in debconf's database. Note that
      preseeding a question's value defaults to marking that question as seen, so to override the default value without marking a question seen, you need two lines.

      Lines can be continued to the next line by ending them with a "\" character.

debconf-copydb

Permet fer una copia de seguretat:

      debconf-copydb configdb backup
      Copy all of configdb to backup, assuming you already have the backup database defined in
      debconf.conf.

debconf-escape

TODO:

DEBCONF-ESCAPE(1)                                                 Debconf                                                DEBCONF-ESCAPE(1)

NAME
      debconf-escape - helper when working with debconf's escape capability

SYNOPSIS
       debconf-escape -e < unescaped-text
       debconf-escape -u < escaped-text

DESCRIPTION
      When debconf has the 'escape' capability set, it will expect commands you send it to have backslashes and newlines escaped (as "\\"
      and "\n" respectively) and will in turn escape backslashes and newlines in its replies. This can be used, for example, to
      substitute multi-line strings into templates, or to get multi-line extended descriptions reliably using "METAGET".

SEE ALSO
      debconf-devel(7) (available in the debconf-doc package)

Programar paquets utilitzant Debconf

El millor recurs per aprendre a programar paquets Debian amb debconf és utilitzar el manual:

$ man 7 debconf-devel
...
NAME
      debconf - developers guide

DESCRIPTION
      This is a guide for developing packages that use debconf.

      This manual assumes that you are familiar with debconf as a user, and are familiar with the basics of  
      debian package construction.

      This manual begins by explaining two new files that are added to debian packages that use debconf. Then it explains how the debconf protocol works, and points you at
      some libraries that will let your programs speak the protocol. It discusses other maintainer scripts that debconf is typically  used  in:  the  postinst  and  postrm
      scripts.  Then  moves  on  to  more advanced topics like shared debconf templates, debugging, and some common techniques and pitfalls of programming with debconf. It
      closes with a discussion of debconf's current shortcomings.

El fitxer /debian/config

Normalment s'utilitza l'script de manteniment postinst per a configurar els paquets. També és possible però a més utilitzar el fitxer config el qual utilitza normalment debconf per tal de fer preguntes a l'usuari i configurar el paquet.

Igual que l'script postinst, se li passen dos paràmetres:

  • Primer paràmetre posicional ($1): action: Quina acció sestà executant (valors possibles: )
  • Segon paràmetre posicional ($2): versió: versió del paquet que s'està instal·lant (permet utilitzar dpkg --compare-versions amb el paràmetre $2)

Els fitxer config es poden executar de tres formes diferents:

  • Amb dpkg-preconfigure: se li passa el paràmetre 1 amb valor "configure" i el paràmetre 2 amb el valor installed-version.
  • Quan el fitxer postinst és executat. Es passen els mateixos paràmetres que al cas anterior. Això és necessari per què el paquet pot ser que no ahgui estat preconfigurat, i el config script encara ha de tenir una oportunitat de ser executat.
  • Quan un paquet és reconfigurat amb dpkg-reconfigure, aleshores el paràmetre 1 s'estableix a "reconfigure"
NOTA: Noteu doncs que el fitxer config s'executa dos cops durant una instal·lació típica! És per aquesta raó que debconf permet recordar les preguntes que ja s'han respost i no tornar a preguntar-les
IMPORTANT: En el primer cas config s'executa abans de desempaquetar el paquet, per tant, no podeu utilitzar els fitxer ni els programes del vostre paquet al fitxer config i s'haurien d'utilitzar ordre molt bàsiques que estiguin normalment sempre disponibles (essential packages)

L'script de configuració no hauria de modificar res del sistema de fitxers. El seu objectiu és només examinar el estat del sistema i preguntar qüestions. Aquestes qüestions són emmagatzemades per Debconf i s'utilitzen més endavant a l'script postinst. De la mateixa manera, l'script de postinst casi mai hauria de utilitzat Debconf per a preguntar qüestions i el que ha de fer és actuar segons les qüestions emmagatzemades prèviament pel fitxer config.

Exemples de fitxer config

Paquet moodle

El contingut del fitxer:

/var/lib/dpkg/info/moodle.config

és:

#!/bin/sh -e

# Source debconf library.
. /usr/share/debconf/confmodule

db_version 2.0
db_capb backup

STATE=start
while [ "$STATE"  != 'notconfigured' -a "$STATE" != 'done' ]; do
  case "$STATE" in
      start|db_server)
	  db_input critical moodle/db_server || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/db_server || true
	      if [ -n "$RET" ]; then
		  STATE=local_only
	      fi
	  fi
	  ;;

      local_only)
	  db_input critical moodle/local_only || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/local_only || true
	      if [ -n "$RET" ]; then
		  if [ "$RET" = "true" ]; then
		      STATE=https_only
		  else
		      STATE=fqdn_check
		  fi
	      fi
	  fi
	  ;;

      fqdn_check)
	  db_input critical moodle/fqdn_check || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/fqdn_check || true
	      if [ -n "$RET" ]; then
		  STATE=https_only
	      fi
	  fi
	  ;;

      https_only)
	  db_input critical moodle/https_only || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/https_only || true
	      if [ -n "$RET" ]; then
		  STATE=db_host
	      fi
	  fi
	  ;;

      db_host)
	  db_input low moodle/db_host || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/db_host || true
	      if [ -n "$RET" ]; then
		  STATE=db_create
	      fi
	  fi
	  ;;

      db_create)
          db_get moodle/db_host || true
          if [ "$RET" = "localhost" ]; then
	      db_input critical moodle/db_create || true
	      if ! db_go; then
		  STATE=notconfigured
	      else
		  db_get moodle/db_create || true
		  if [ -n "$RET" ]; then
		      STATE=dba_password
		  fi
	      fi
	  else
	      # We only support DB creation on localhost.
	      # There are too many variables (particularly for
	      # postgresql) to support automated creation of remote
	      # databases.
	      #
	      # Assumption: users who want remote databases don't need
	      # our help creating them.
	      db_set moodle/db_create false || true
	      STATE=dba_password
	  fi
	  ;;

      dba_password)
          db_get moodle/db_create || true
	  db_create="$RET"
	  db_get moodle/db_server || true
	  db_server="$RET"

	  # We don't need a DBA password if the we're using a postgresql DB.
          if [ "$db_server" = "mysql-server" ] && [ "$db_create" = "true" ]; then
	      db_input critical moodle/dba_password || true
	      db_input critical moodle/dba_confirm || true
	      if ! db_go; then
		  STATE=notconfigured
	      else
		  db_get moodle/dba_confirm || true
		  CONFIRM="$RET"
		  db_get moodle/dba_password || true
		  PW="$RET"
		  if [ "$PW" != "$CONFIRM" ]; then
		      STATE=dba_pwmismatch
		  else
		      STATE=dbu_name
		  fi
	      fi
	  else
	      # We don't need the DBA password.
	      STATE=dbu_name
	  fi
	  ;;

      dba_pwmismatch)
	  db_input critical moodle/pwmismatch || true
	  STATE=dba_password
	  ;;

      dbu_name)
	  db_input low moodle/dbu_name || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/dbu_name || true
	      if [ -n "$RET" ]; then
		  STATE=dbu_password
	      fi
	  fi
	  ;;

      dbu_password)
	  db_input critical moodle/dbu_password || true
	  db_input critical moodle/dbu_confirm || true
	  if ! db_go; then
	      STATE=notconfigured
	  else
	      db_get moodle/dbu_confirm || true
	      CONFIRM="$RET"
	      db_get moodle/dbu_password || true
	      PW="$RET"
	      if [ "$PW" != "$CONFIRM" ]; then
		  STATE=dbu_pwmismatch
	      else
		  if [ -z "$PW" ] || [ -z "$CONFIRM" ]; then
		      STATE=dbu_pwempty
		  else
		      case "$PW" in
			  # Don't allow quoting characters at all.
			  # They break stuff and aren't necessary.
			  *"'"*|*'"'*|*\\*)
			      STATE=dbu_pwillegalchar
			      ;;
			  *)
			      db_get moodle/db_create || true
			      if [ "$RET" = "true" ]; then
				  STATE=db_populate
			      else
				  STATE=config_php_created
			      fi
		      esac
		  fi
	      fi
	  fi
	  ;;

      dbu_pwempty)
	  db_input critical moodle/pwempty|| true
	  STATE=dbu_password
	  ;;

      dbu_pwmismatch)
	  db_input critical moodle/pwmismatch || true
	  STATE=dbu_password
	  ;;

      dbu_pwillegalchar)
	  db_input critical moodle/pwillegalchar || true
	  STATE=dbu_password
	  ;;

      db_populate)
	  db_input critical moodle/db_populate || true
	  db_go || true
	  STATE=done
	  ;;

      config_php_created)
	  db_input critical moodle/config_php_created || true
	  db_go || true
	  STATE=done
	  ;;

  esac
done

if [ "$STATE" = 'notconfigured' ]; then
    db_input critical moodle/notconfigured || true
    db_go || true
    exit 1
fi
Paquet slapd

A partir de la versió 11.10 del servidor Ldap:

/var/lib/dpkg/info/moodle.config
#! /bin/sh

set -e

# Load debconf
. /usr/share/debconf/confmodule

# This will be replaced with debian/slapd.scripts-common which includes
# various helper functions and $OLD_VERSION and $SLAPD_CONF
# -*- sh -*-
# This file can be included with #SCRIPTSCOMMON#


# ===== Dumping and reloading using LDIF files =========================  {{{
#
# If incompatible changes are done to the database underlying a LDAP 
# directory we need to dump the contents and reload the data into a newly
# created database after the new server was installed. The following
# functions deal with this functionality.


# ----- Configuration of this component --------------------------------  {{{
#
# Dumping the database can have negative effects on the system we are
# running on. If there is a lot of data dumping it might fill a partition
# for example. Therefore we must give the user exact control over what we
# are doing.

database_dumping_enabled() {						# {{{
# Check if the user has enabled database dumping for the current situation.
# Return success if yes.
# Usage: if database_dumping_enabled; then ... fi

	db_get slapd/dump_database
	case "$RET" in
	always)
		;;
	"when needed")
		database_format_changed || return 1
		;;
	never)
		return 1
		;;
	*)
		echo >&2 "Unknown value for slapd/dump_database: $RET"
		echo >&2 "Please report!"
		exit 1
		;;
	esac
}

# }}}
database_format_changed() {						# {{{
# Check if the database format has changed since the old installed version
# Return success if yes.
# Usage: if database_format_changed; then

	if dpkg --compare-versions "$OLD_VERSION" lt-nl 2.4.23-0ubuntu3; then
		return 0
	else
		return 1
	fi
}

# }}}
database_dumping_destdir() {						# {{{
# Figure out the directory we are dumping the database to and create it
# if it does not exist.
# Usage: destdir=`database_dumping_destdir`

	local dir
	db_get slapd/dump_database_destdir
	dir=`echo "$RET"|sed -e "s/VERSION/$OLD_VERSION/"`
	mkdir -p -m 700 "$dir"
	echo $dir
}

# }}}
create_new_user() { # {{{
	if [ -z "`getent group openldap`" ]; then
		addgroup --quiet --system openldap
	fi
	if [ -z "`getent passwd openldap`" ]; then
		echo -n "  Creating new user openldap... " >&2
		adduser --quiet --system --home /nonexistent --shell /bin/false \
        --ingroup openldap --disabled-password --disabled-login \
        --no-create-home \
        --gecos "OpenLDAP Server Account" openldap
		echo "done." >&2
	fi
}
# }}}
update_permissions() {	# {{{
	dir="$1"
	[ -z "${SLAPD_USER}" ] || chown -R "${SLAPD_USER}" "${dir}"
	[ -z "${SLAPD_GROUP}" ] || chgrp -R "${SLAPD_GROUP}" "${dir}"
	chmod -R u=rwX,g=rX,o-rwx "${dir}"
}
# }}}
update_databases_permissions() {	# {{{
	for suffix in `get_suffix`; do
		dbdir=`get_directory $suffix`
		update_permissions "$dbdir"
	done
}
# }}}
# }}}
# ----- Dumping and loading the data ------------------------------------ {{{

dump_databases() {							# {{{
# If the user wants us to dump the databases they are dumped to the 
# configured directory.
	
	local db suffix file dir failed slapcat_opts

	database_dumping_enabled || return 0

	dir=`database_dumping_destdir`
	echo >&2 "  Dumping to $dir: "
	for suffix in `get_suffix`; do
		file="$dir/$suffix.ldif"
		echo -n "  - directory $suffix... " >&2
		# Need to support slapd.d migration from preinst
		if [ -f "${SLAPD_CONF}" ]; then
			slapcat_opts="-f ${SLAPD_CONF}"
		else
			slapcat_opts="-F ${SLAPD_CONF}"
		fi
		slapcat ${slapcat_opts} -b "$suffix" > "$file" || failed=1
		if [ "$failed" ]; then
			rm -f "$file"
			echo failed. >&2
			exit 1
		fi
		echo "done." >&2
	done
}

# }}}
load_databases() {							# {{{
	local dir file db dbdir backupdir

	dir=`database_dumping_destdir`
	echo >&2 "  Loading from $dir: "
	for suffix in `get_suffix`; do
		dbdir=`get_directory $suffix`
		if ! is_empty_dir "$dbdir"; then
			echo >&2 \
			  "  Directory $dbdir for $suffix not empty, aborting."
			exit 1
		fi

		file="$dir/$suffix.ldif"
		echo -n "  - directory $suffix... " >&2

		# If there is an old DB_CONFIG file, restore it before
		# running slapadd
		backupdir=`compute_backup_path -n "$dbdir" "$suffix"`
		if [ -e "$backupdir"/DB_CONFIG ]; then
			cp -a "$backupdir"/DB_CONFIG "$dbdir"/
		else
			copy_example_DB_CONFIG "$dbdir"/
		fi

		if [ -f "${SLAPD_CONF}" ]; then
			slapadd_opts="-f ${SLAPD_CONF}"
		else
			slapadd_opts="-F ${SLAPD_CONF}"
		fi
		capture_diagnostics slapadd ${slapadd_opts} \
			-q -b "$suffix" -l "$file" || failed=1
		if [ "$failed" ]; then
			rm -f "$dbdir"/*
			echo failed. >&2
			echo >&2
			cat <<-EOF
	Loading the database from the LDIF dump failed with the following
	error while running slapadd:
EOF
			release_diagnostics "    "
			exit 1
		fi
		echo "done." >&2

		if [ -n "$SLAPD_USER" ] || [ -n "$SLAPD_GROUP" ]; then
			echo -n "  - chowning database directory ($SLAPD_USER:$SLAPD_GROUP)... "
			[ -z "$SLAPD_USER" ] || \
				chown -R "$SLAPD_USER" "$dbdir"
			[ -z "$SLAPD_GROUP" ] || \
				chgrp -R "$SLAPD_GROUP" "$dbdir"
			echo "done";
		fi
	done
}

# }}}
move_incompatible_databases_away() {					# {{{
	echo >&2 "  Moving old database directories to /var/backups:"
	for suffix in `get_suffix`; do
		dbdir=`get_directory $suffix`
		move_old_database_away "$dbdir" "$suffix"
	done
}

# }}}
# }}}
 
# {{{
# The following two functions need to support slapd.conf installations 
# as long as upgrading from slapd.conf environment is supported.
# They're used to dump database in preinst which may have a slapd.conf file.
get_suffix() {							
	if [ -f "${SLAPD_CONF}" ]; then
		for f in `get_all_slapd_conf_files`; do
			grep '^suffix ' ${f} | sed 's/^suffix[[:space:]]\+\(.\+\)/\1/' | sed 's/"//g'
		done
	else
		grep -h olcSuffix ${SLAPD_CONF}/cn\=config/olcDatabase* | cut -d: -f 2
	fi
}
# }}}
get_directory() {							# {{{
# Returns the db directory for a given suffix
	if [ -d "${SLAPD_CONF}" ] && echo `get_suffix` | grep -q "$1" ; then
		grep "olcDbDirectory:" `grep -l "olcSuffix: $1" ${SLAPD_CONF}/cn\=config/olcDatabase*` | cut -d: -f 2 | sed 's/^  *//g'
	elif [ -f "${SLAPD_CONF}" ]; then
		# Extract the directory for the given suffix ($1)
		for f in `get_all_slapd_conf_files`; do
		awk  ' BEGIN { DB=0; SUF=""; DIR="" } ;
		       /^database/ { DB=1; SUF=""; DIR="" } ; 
		       DB==1 && /^suffix[ \t]+"?'$1'"?$/ { SUF=$2 ; } ; 
		       DB==1 && /^directory/ { DIR=$2 ;} ; 
		       DB==1 && SUF!="" && DIR!="" { sub(/^"/,"",DIR) ; sub(/"$/,"",DIR) ; print DIR; SUF=""; DIR="" }' "${f}"
		done
	else
		return 1
	fi
}
# }}}
# Returns the list of all the config files: slapd.conf and included files.
get_all_slapd_conf_files() {
	echo ${SLAPD_CONF}
	awk '
BEGIN { I=0 } 
/^include/ {
	sub(/include/," ");
	I=1;
} 
I==1 && /^[ \t]+/ { 
	split($0,F) ;
	for (f in F) 
		if (!match(F[f],/schema/)) { 
			print F[f]
		} ;
	next;
}
I==1 { I=0 }
' ${SLAPD_CONF}
}
# }}}
 
# }}}


compute_backup_path() {							# {{{
# Compute the path to backup a database directory
# Usage: compute_backup_path [-n] <dir> <basedn>

# XXX: should ask the user via debconf

	local dirname basedn ok_exists
	if [ "$1" = "-n" ]; then
		ok_exists=yes
		shift
	fi
	dirname="$1"
	basedn="$2"

	# Computing the name of the backup directory from the old version, 
	# the suffix etc. all makes me feel worried. I'd rather have a 
	# directory name which is not going to exist. So the simple 
	# scheme we are using now is to compute the filename from the 
	# directory name and appending date and time. And we check if it
	# exists to be really sure...  -- Torsten

	local target
	local id
	id="$OLD_VERSION"
	[ -n "$id" ] || id=`date +%Y%m%d-%H%M%S`
	target="/var/backups/$basedn-$id.ldapdb"
	# Configuration via dpkg-reconfigure. 
	# The backup directory already exists when reconfigured 
	# twice or more: append a timestamp.
	if [ -e "${target}" ] && ([ "$MODE" = reconfigure ] || [ "$DEBCONF_RECONFIGURE" ]); then
			 target="$target-`date +%Y%m%d-%H%M%S`"
	fi
	if [ -e "$target" ] && [ -z "$ok_exists" ]; then
		echo >&2
		echo >&2 "  Backup path $target exists. Giving up..."
		exit 1
	fi

	echo "$target"
}

# }}}
move_old_database_away() {						# {{{
# Move the old database away if it is still there
#
# In fact this function makes sure that the database directory is empty
# and can be populated with a new database. If something is in the way
# it is moved to a backup directory if the user accepted the debconf
# option slapd/move_old_database. Otherwise we output a warning and let
# the user fix it himself.
# Usage: move_old_database_away <dbdir> [<basedn>]

	local databasedir backupdir
	databasedir="$1"
	suffix="${2:-unknown}"
	
	if [ ! -e "$databasedir" ] || is_empty_dir "$databasedir"; then
		return 0
	fi

    
	# Note that we can't just move the database dir as it might be
	# a mount point. Instead me move the content which might 
	# include mount points as well anyway, but it's much less likely.
	db_get slapd/move_old_database
	if [ "$RET" = true ]; then
		backupdir=`compute_backup_path "$databasedir" "$suffix"`
		echo -n "  - directory $suffix... " >&2
		mkdir -p "$backupdir"
		find "$databasedir" -mindepth 1 -maxdepth 1	\
			-exec mv {} "$backupdir" \;
		echo done. >&2
	else
		cat >&2 <<EOF
  There are leftover files in $databasedir. This will probably break 
  creating the initial directory. If that's the case please move away
  stuff in there and retry the configuration.
EOF
	fi
}
# }}}
manual_configuration_wanted() {						# {{{
# Check if the user wants to configure everything himself (queries debconf)
# Returns success if yes.

	db_get slapd/no_configuration
	if [ "$RET" = "true" ]; then
		return 0
	else
		return 1
	fi
}
# }}}
copy_example_DB_CONFIG() {						# {{{
# Copy an example DB_CONFIG file
# copy_example_DB_CONFIG <directory>
	local directory srcdir
	
	directory="$1"
	srcdir="/usr/share/slapd"

	if ! [ -f "${directory}/DB_CONFIG" ] && [ -d "$directory" ]; then
		cp $srcdir/DB_CONFIG "${directory}/DB_CONFIG"
	fi
}

# }}}
create_new_configuration() {						# {{{
# Create a new configuration and directory

	if [ ! -d /var/lib/ldap ]; then
		mkdir /var/lib/ldap
	fi
	update_permissions /var/lib/ldap

	if [ ! -d /var/run/slapd ]; then
		mkdir /var/run/slapd
	fi
	update_permissions /var/run/slapd
	# update_permissions doesn't allow a world readable dir.
	# slapd run dir has the slapi socket and thus needs 
	# to be world accessible.
	chmod 0755 /var/run/slapd

	local init_ldif
	init_ldif="/usr/share/slapd/slapd.init.ldif"
	echo -n "  Creating initial slapd configuration... " >&2
	rm -rf "${SLAPD_CONF}"
	mkdir "${SLAPD_CONF}"
	capture_diagnostics slapadd -F "${SLAPD_CONF}" \
		-b "cn=config" -l ${init_ldif} || failed=1
	if [ "$failed" ]; then
		cat <<-EOF
Loading the initial configuration from the ldif file (${init_ldif}) failed with the following
error while running slapadd:
EOF
		release_diagnostics "    "
		exit 1
	fi
	update_permissions "${SLAPD_CONF}"
	echo "done." >&2

}
# }}}
configure_v2_protocol_support() {					# {{{
# Adds the "allow bind_v2" directive to the configuration if the user decided
# he wants to have ldap v2 enabled.

	db_get slapd/allow_ldap_v2
	if [ "$RET" != "true" ]; then return 0; fi

	echo -n "  Enabling LDAPv2 support... " >&2
	
	if [ -d "$SLAPD_CONF" ]; then 
		if ! grep -q -E '^olcAllows:[[:space:]]+bind_v2' "${SLAPD_CONF}/cn=config.ldif"; then
			echo "olcAllows: bind_v2" >> "${SLAPD_CONF}/cn=config.ldif"
		fi
		return 0
	else
		return 1
	fi

	echo . >&2
}
# }}}
backup_config_once() {							# {{{
# Create a backup of the current configuration files. 
# Usage: backup_config_once

	local backupdir

	if [ -z "$FLAG_CONFIG_BACKED_UP" ]; then
		backupdir=`database_dumping_destdir`
		if [ -e "$SLAPD_CONF" ]; then
			cp -a "$SLAPD_CONF" "$backupdir"
		fi
		FLAG_CONFIG_BACKED_UP=yes
	fi
}

# }}}


previous_version_older() {						# {{{
# Check if the previous version is newer than the reference version passed.
# If we are not upgrading the previous version is assumed to be newer than
# any reference version.
# Usage: previous_version_older <package version>
	
	if dpkg --compare-versions "$OLD_VERSION" lt-nl "$1"; then
		return 0
	else
		return 1
	fi
} 

# }}}
previous_version_newer() {						# {{{
# Check if the previous version is newer than the reference version passed.
# If we are not upgrading the previous version is assumed to be newer than
# any reference version.
# Usage: previous_version_newer <package version>
	
	if dpkg --compare-versions "$OLD_VERSION" gt-nl "$1"; then
		return 0
	else
		return 1
	fi
} # }}}
upgrade_supported_from_backend() {					# {{{
# Check if upgrading a database in the named backend is supported by
# our scripts.
# Usage: if upgrade_supported_from_backend "backend"; then ... fi

	case "$1" in bdb|hdb) return 0; esac
	return 1
}

# }}}
is_initial_configuration() {						# {{{
# Check if this is the initial configuration and not an upgrade of an 
# existing configuration
# Usage: if is_initial_configuration "$@"; then ... fi from top level

	# Plain installation
	if [ "$1" = configure ] && [ -z "$2" ]; then
		return 0
  	fi
	# Configuration via dpkg-reconfigure
	if [ "$1" = reconfigure ] || [ "$DEBCONF_RECONFIGURE" ]; then
    		return 0
  	fi
	# Upgrade but slapd.d doesn't exist.  If the user is doing this
	# intentionally because they want to put it somewhere else, they
	# should select manual configuration in debconf.
	if [ "$1" = configure ] && [ ! -e "$SLAPD_CONF" ]; then
		return 0
	fi
  	return 1
}

# }}}
is_empty_dir() {							# {{{
# Check if a path refers to an empty directory
# Usage: if is_empty_dir "$dir"; then ... fi

	output=`find "$1" -type d -maxdepth 0 -empty 2>/dev/null`
  	if [ "$output" ]; then
    		return 0
  	else
    		return 1
  	fi
}

# }}}

# ===== Global variables ================================================ {{{
#
# At some points we need to know which version we are upgrading from if
# any. More precisely we only care about the configuration and data we 
# might have laying around. Some parts also want to know which mode the
# script is running in.

MODE="$1"		# install, upgrade, etc. - see debian-policy
OLD_VERSION="$2"

# Source the init script configuration
# See example file debian/slapd.default for variables defined here
if [ -f "/etc/default/slapd" ]; then
	. /etc/default/slapd
fi

# Load the default location of the slapd config file
if [ -z "$SLAPD_CONF" ]; then
        if previous_version_older 2.4.11-0ubuntu1 \
	   && [ -f "/etc/ldap/slapd.conf" ] \
	   && [ ! -e "/etc/ldap/slapd.d" ] ; then
		SLAPD_CONF="/etc/ldap/slapd.conf"
	else
 		SLAPD_CONF="/etc/ldap/slapd.d/"
	fi
fi

# }}}

# ----- Handling diagnostic output ------------------------------------ {{{
#
# Often you want to run a program while you are showing progress 
# information to the user. If the program you are running outputs some 
# diagnostics it will mess up your screen. 
#
# This is what the following functions are designed for. When running the
# program, use capture_diagnostics to store what the program outputs to 
# stderr and use release_diagnostics to write out the captured output.


capture_diagnostics() {							# {{{
# Run the command passed and capture the diagnostic output in a temporary
# file. You can dump that file using release_diagnostics.

	# Create the temporary file
	local tmpfile
	tmpfile=`mktemp`
	exec 7<>"$tmpfile"
	rm "$tmpfile"

	# Run the program and capture stderr. If the program fails the 
	# function fails with the same status.
	"$@" 2>&7 || return $?
}

# }}}
release_diagnostics() {							# {{{
# Dump the diagnostic output captured via capture_diagnostics, optionally
# prefixing each line.
# Usage: release_diagnostics "prefix"

	local script
	script='
		seek STDIN, 0, 0;
		print "$ARGV[0]$_" while (<STDIN>);';
	perl -e "$script" "$1" <&7
}

# }}}


# }}}

# vim: set sw=8 foldmethod=marker: 



# Check if the user wants to configure slapd manually
want_manual_configuration() {
  db_input medium slapd/no_configuration || true
  db_go || true
  db_get slapd/no_configuration
  no_configuration="$RET"
  
  if [ "$no_configuration" = "true" ]; then
    return 0
  fi
  return 1
}

# Query the information we need to create an initial directory
query_initial_config() {
    db_input low slapd/purge_database || true
    # XXX - should be done more general, but for now this should do
    # the trick
    if [ -e "/var/lib/ldap" ] && ! is_empty_dir /var/lib/ldap; then
      db_input low slapd/move_old_database || true
    fi
    db_go || true
}

configure_allow_v2_binds() {                        # {{{
# Ask if the user would like their package to support LDAPv2..
# This was the default in older versions but we want to ask
# for new installs too in case the user needs it..

    db_input medium slapd/allow_ldap_v2 || true
}
# }}}

# ----- Configuration of LDIF dumping and reloading---------------------  {{{
#
# Dumping the database can have negative effects on the system we are
# running on. If there is a lot of data dumping it might fill a partition
# for example. Therefore we must give the user exact control over what we
# are doing.

configure_dumping() {							# {{{
# Ask the user for the configuration of the dumping component
# Usage: configure_dumping

  # Look if the user wants to migrate to the BDB backend
  if ! database_dumping_enabled; then
    return 0
  fi

	# Configure if and where to dump the LDAP databases
	db_input medium slapd/dump_database || true
	db_go || true
	db_get slapd/dump_database

	# Abort if the user does not want dumping
	if [ "$RET" = never ]; then
		return 0
	fi

	db_input medium slapd/dump_database_destdir || true
	db_go || true

	# If the user entered the empty value, go back to the default
	db_get slapd/dump_database_destdir 
	if [ "$RET" = "" ]; then
		db_reset slapd/dump_database_destdir
	fi
}

# }}}
# }}}

# Create an initial directory on fresh install
if is_initial_configuration "$@"; then
	if ! want_manual_configuration; then
		query_initial_config
		configure_allow_v2_binds
	fi
fi

# Configure the dumping and v2 binds components if we are upgrading some older
# version.
if [ "$1" = configure ] && [ -n "$2" ]; then
	configure_dumping
	configure_allow_v2_binds
fi
   
db_go || true

exit 0

Testing

Es poden provar els fitxers config sense necessitat d'instal·lar el paquet, per exemple per provar el de Moodle:

$ cd /var/lib/dpkg/info
$ DEBCONF_DEBUG='.*' ./moodle.config configure 0

Si esteu fent un paquet propi i el voleu provar només cal que tingueu en compte que es necessari que tingueu les plantilles definides. Anem a veure un exemple de fitxer config que em posat a la carpeta /var/lib/dpkg/info i li hem dit prova.config. Si us fixeu en els missatges de depuració durant la execució de:

$ DEBCONF_DEBUG='.*' ./prova.config configure 0
...
debconf (developer): Trying to find a templates file..
debconf (developer): Trying ./prova.config.templates
debconf (developer): Trying ./prova.templates
debconf (developer): Trying /usr/share/debconf/templates/prova.config.templates
debconf (developer): Couldn't find a templates file.

Com podeu veure mira de trobar els templates en 3 llocs diferents:

./prova.config.templates
./prova.templates
/usr/share/debconf/templates/prova.config.templates

Un altre qüestió important és que si cometeu algun error es pot quedar penjada la terminal on executeu les proves. Podeu despenjar-la buscant:

$ ps aux | grep whiptail
$ sudo kill -9 PID

o

$ ps aux | grep config
..
sergi    13670  0.0  0.3  61480 12400 pts/5    S+   05:53   0:00 /usr/bin/perl -w /usr/share/debconf/frontend ./prova.config configure 0
sergi    13676  0.0  0.0   4148   576 pts/5    S+   05:53   0:00 /bin/sh -e ./prova.config configure 0
$ sudo kill -9 13670 13676

Altres paquets

debconf-doc

$ sudo apt-get install debconf-doc 
$ man 7 debconf-devel

debconf-utils

El podeu instal·lar amb:

$ sudo apt-get install debconf-utils

Les aplicacions o executables són:

$ dpkg -L debconf-utils | grep bin
/usr/bin
/usr/bin/debconf-loadtemplate
/usr/bin/debconf-get-selections
/usr/bin/debconf-mergetemplate
/usr/bin/debconf-getlang


debconf-loadtemplate

Del manual:

$ man debconf-loadtemplate

SYNOPSIS

       debconf-loadtemplate owner file [file ..]

DESCRIPTION

      Loads one or more template files into the debconf database.
      The first parameter specifies the owner of the templates
      (typically, the owner is the name of a debian package). The
      remaining parameters are template files to load.

WARNING

      This program should never be used from a maintainer script
      of a package that uses debconf! It may however, be useful in
      debugging, or to seed the debconf database.

És a dir, que serveix per provar les plantilles quan estem depurant, per exemple:

$ sudo debconf-loadtemplate echod templates 

Carrega el fitxer amb les plantilles del paquet echod. Per exemple us pot servir per tal de provar una plantilla i debconf sense necessitat d'haver de fet tot el paquet.

debconf-get-selections

NOTA: Vegeu també l'ordre debconf-set-selections del paquet debconf-utils

Permet obtenir les seleccions (configuracions per defecte) actuals:

$ sudo debconf-get-selections 
# Choices: CUPS, DNS, IMAPS, POP3S, SSH, CIFS (Samba), SMTP, HTTP, HTTPS
ufw	ufw/allow_known_ports	multiselect	
# xscreensaver and xlockmore must be restarted before upgrading
libpam-modules	libpam-modules/disable-screensaver	error	
# Voleu eliminar l'enllaç simbòlic /usr/dict?
dictionaries-common	dictionaries-common/remove_old_usr_dict_link	boolean	false
# Method for toggling between national and Latin mode:
# Choices: Caps Lock, Right Alt, Right Control, Right Shift, Right Logo key, Menu key, Alt+Shift, Control+Shift, Control+Alt, Alt+Caps Lock, Left Control+Left Shift, Left Alt, Left Control, Left Shift, Left   
Logo key, Scroll Lock key, No toggling
console-setup	console-setup/toggle	select	No toggling
# Password input error
mysql-server-5.1	mysql-server/password_mismatch	error	
....

Es pot combinar amb debconf-set-selections (el format de sortida de debconf-get-selections és compatible amb debconf-set-selections) per tal de fer còpies de seguretat o per preconfigurar les respostes de debconf abans d'instal·lar un paquet i d'aquesta manera poder fer una instal·lació desatesa pre-seeding

debconf-mergetemplate

Segons el manual:

Note: This utility is deprecated. You should switch to using po-debconf's po2debconf program.

debconf-getlang

Permet obtenir les plantilles d'un cert idioma:

$ debconf-getlang it templates > templates.it

Preconfigurant paquets per tal de poder-los instal·lar de forma desatesa

Exemple. Preconfiguració de les fonts de Windows. ttf-mscorefonts

Consulteu Ttf-mscorefonts#Automatitzar_la_instal.C2.B7laci.C3.B3._Preseed

Exemple. Preconfiguració de libnss-ldap

TODO

Apt is a wonderful tool, but it does have its quirks. One of those is that it likes to ask you interactive questions during package installation. This makes total sense when a human is doing apt-get install foobar, but it causes all sorts of consternation when you want to automatically install packages. (You do this all the time with Puppet, which I’ll talk more about at the end of this post.)

The answer to this problem is to pre-seed debconf with the correct answers to it’s questions. To do this, first you need to install the package by hand:

$ apt-get install libnss-ldap

You’ll need to provide answers to the questions it asks, which we’re going to re-use later as the basis for our seed file. Next, make sure you have debconf-utils installed, and grab the answers to your questions:

$ apt-get install debconf-utils # Only if you need it
$ debconf-get-selections | grep libnss-ldap
libnss-ldap     libnss-ldap/rootbindpw  password
libnss-ldap     libnss-ldap/bindpw      password
libnss-ldap     libnss-ldap/dblogin     boolean false
# Automatically update libnss-ldap's configuration file?
libnss-ldap     libnss-ldap/override    boolean false
libnss-ldap     shared/ldapns/base-dn   string   dc=example,dc=com
libnss-ldap     libnss-ldap/rootbinddn  string   cn=admin,dc=example,dc=com
libnss-ldap     shared/ldapns/ldap_version      select   3
libnss-ldap     libnss-ldap/binddn      string   cn=proxyuser,dc=example,dc=net
libnss-ldap     shared/ldapns/ldap-server       string   ldapi:///
libnss-ldap     libnss-ldap/nsswitch    note
libnss-ldap     libnss-ldap/confperm    boolean false
libnss-ldap     libnss-ldap/dbrootlogin boolean true
    

Take the output of that and stick it in a file, say libnss-ldap.seed. You can now use that file to pre-seed a new system with those answers using debconf-set-selections:

$ debconf-get-selections | grep libnss-ldap > /tmp/libnss-ldap.seed
$ debconf-set-selections /tmp/libnss-ldap.seed
   

Or use ssh to pre-seed a new box:

$ cat /tmp/libnss-ldap.seed | ssh somehost debconf-set-selections
   

If you are using Puppet (and if you’re not, you should be) to manage your systems, you can use a recipe like this to automatically install packages that require interaction:

 define seed_package($ensure = latest) {
  $seedpath = "/var/cache/local/preseeding" 
  file { "$seedpath/$name.seed":
    source => "puppet://$puppet_server/seeds/$lsbdistcodename/$name.seed",
    mode => 0600,
    owner => root,
    group => root
  }
  package { $name:
    ensure => $ensure,
    responsefile => "$seedpath/$name.seed",
    require => File["$seedpath/$name.seed"],
  }
 }
 
 class foobar {
  seed_package { "libnss-ldap":
    ensure => latest
  }
 }


TODO:

http://blog.hjksolutions.com/articles/2007/07/27/unattended-package-installation-with-debian-and-ubuntu
dpkg-preconfigure

Eines de traducció de Debconf

TODO

Unattended Package Installation

Del manual (man 7 debconf)

TODO:

      If  you  have many machines to manage you will sometimes find yourself in the position of needing to perform
      an unattended installation or upgrade of packages on many systems, when the default answers to some configu‐
      ration questions are not acceptable. There are many ways to approach this; all involve setting up a database
      and making debconf use it to get the answers you want.
      You should really read debconf.conf(5) before this section, as you need to understand  how  debconf's  data‐
      bases work.
      The  easiest way to set up the database is to install the packages on one machine and answer their questions
      as usual. Or you might just use dpkg-preconfigure(8)  to  configure  a  set  of  packages  without  actually
      installing them. Or you might even decide to write a plain text debconf database by hand or something.
      Once  you  have  the database, you need to figure out how to make the remote systems use it. This depends of
      course on the configuration of those systems and what database types they are set up to use.
      If you are using the LDAP debconf database, an entire network of debian machines can also have  any  or  all
      package installation questions answered automatically by a single LDAP server.
      But  perhaps  you're  using  something a little bit easier to set up like, say, the default debconf database
      configuration, or you just don't want your remote systems to use LDAP all the time. In this  case  the  best
      approach is to temporarily configure the remote systems to stack your database underneath their own existing
      databases, so they pull default values out of it. Debconf offers two environment variables, DEBCONF_DB_FALL‐
      BACK and DEBCONF_DB_OVERRIDE, to make it easy to do this on the fly. Here is a sample use:
         cat /var/cache/debconf/config.dat | \
         ssh root@target "DEBIAN_FRONTEND=noninteractive \
                        DEBCONF_DB_FALLBACK=Pipe apt-get upgrade"
      This  makes  the  debconf  on  the  remote host read in the data that is piped across the ssh connection and
      interpret it as a plain text format debconf database. It then uses that database as a fallback database -- a
      read-only  database  that  is  queried  for answers to questions if the system's main debconf database lacks
      answers.
      Here's another way to use the DEBCONF_DB_FALLBACK environment variable:
        ssh -R 389:ldap:389 root@target \
           "DEBCONF_DB_FALLBACK='LDAP{host:localhost}' apt-get upgrade"
      Here ssh is used to set up a tunneled LDAP connection and run debconf.  Debconf is  told  to  use  the  LDAP
      server  as  the  fallback database. Note the use of "{host:localhost}" to configure how debconf accesses the
      LDAP database by providing the "host" field with a value of "localhost".
      Here's another method:
        scp config.dat root@target:
        ssh root@target "DEBCONF_DB_FALLBACK='File{/root/config.dat}' apt-get upgrade
      Here you copy the database over with scp, and then ssh over and make debconf use the file you  copied  over.
      This  illustrates  a  shorthand you can use in the DEBCONF_DB_FALLBACK parameters -- if a field name is left
      off, it defaults to "filename".
      There is only one problem with these uses of the DEBCONF_DB_FALLBACK parameter: While the fallback  database
      can  provide answers to questions the other debconf databases have never seen, it is only queried as a fall‐
      back; after the other databases. If you need to instead temporarily override an existing value on the remote
      host, you should instead use the DEBCONF_DB_OVERRIDE variable. Like DEBCONF_DB_FALLBACK, it sets up a tempo‐
      rary database, but this database is consulted before any others, and can be used to override  existing  val‐
      ues.

Variables d'entorn

ENVIRONMENT

      DEBIAN_FRONTEND
             Used to temporarily change the frontend debconf uses. See above.
      DEBIAN_PRIORITY
             Used to temporarily change the minimum priority of question debconf will display. See above.
      DEBCONF_DEBUG
             Turns on debugging output on standard error. May be set to a facility name or  a  regular  expression
             which matches a facility name (such as '.*' to output all debug info). The facility names include:
             user   Debugging info of interest to a debconf user.
             developer
                    Debugging info of interest to a package developer.
             db     Debugging info about the backend database.
      DEBCONF_NOWARNINGS
             Set  to  "yes"  to disable some warnings that debconf may display. Does not suppress display of fatal
             errors.
      DEBCONF_TERSE
             Set to "yes" to enable terse mode, in which debconf frontends cut down on the  verbiage  as  much  as
             possible.
      DEBCONF_DB_FALLBACK
             Stack  a database after the normally used databases, so that it is used as a fallback to get configu‐
             ration information from. See "Unattended Package Installation" above. If the value of the variable is
             the  name  of  an existing database in debconf.conf, then that database will be used.  Otherwise, the
             environment variable can be used to configure a database on the fly, by telling the type of database,
             and  optionally  passing field:value settings, inside curly braces after the type. Spaces are used to
             separate fields, so you cannot specify a field value containing whitespace.
      Thus, this uses the fallbackdb in debconf.conf:
        DEBCONF_DB_FALLBACK=fallbackdb
      While this sets up a new database of type File, and tells it a filename to use and turns off backups:
        DEBCONF_DB_FALLBACK=File{Filename:/root/config.dat Backup:no}
      And as a shorthand, this sets up a database of type File with a filename:
        DEBCONF_DB_FALLBACK=File{/root/config.dat}
      Note that if a fallback database is set up on the fly, it will be read-only by default.
      DEBCONF_DB_OVERRIDE
             Stack a database before the normally used databases, so that it can override values  from  them.  The
             value of the variable works the same as does the value of DEBCONF_DB_FALLBACK.
      DEBCONF_DB_REPLACE
             Use  a  given database instead of the normally used databases.  This may be useful for testing with a
             separate database without having to create a separate debconf.conf, or to avoid  locking  the  normal
             databases.
      DEBCONF_SYSTEMRC
             If this environment variable is set, debconf will ignore a user's ~/.debconfrc file, and use the sys‐
             tem one instead.  If it is set to the name of a regular file, debconf will use that file  in  prefer‐
             ence to the system configuration files.
      DEBCONF_FORCE_DIALOG
             If this environment variable is set, debconf will use dialog in preference to whiptail for the dialog
             frontend.
      DEBCONF_FORCE_XDIALOG
             If this environment variable is set, debconf will use Xdialog in preference to whiptail for the  dia‐
             log frontend.
      DEBCONF_NONINTERACTIVE_SEEN
             Set to "true" to cause the seen flag to be set for questions asked in the noninteractive frontend.

Exemples

Exemple pas a pas de Debconf

Seguiu aquest pas a pas per tal de provar el funcionament de Debconf sense necessitat de crear un paquet Debian:

Creeu una carpeta de treball i instal·leu els paquets necessaris:

$ cd
$ mkdir debconf && cd debconf
$ sudo apt-get install debconf debconf-utils

Ara anem a crear les plantilles

$ joe templates

Poseu les següents plantilles:

Template: echod/port
Type: string
Default: 8001
Description: Port Number:
 Please enter the port number for echod.

Template: echod/webserver
Type: multiselect
Choices: apache2, lighttpd
Description: Web server to reconfigure automatically:
 Please choose the web server that should be automatically configured
 to run echod
NOTA: No busqueu gaire sentit als exemples. Són simplement proves. El que si és important és que el nom de les plantilles ha de contenir sempre el nom del paquet, a l'exemple echod

Un cop tingueu el fitxer plantilles cal instal·lar les plantilles a la base de dades de debconf.

$ sudo debconf-loadtemplate echod templates

On echod és el nom del paquet i templates és el fitxer amb les plantilles.

Ara cal crear un fitxer config per utilitzar les plantilles:

$ sudo joe config
#!/bin/bash

#És interessant activar aquesta línia per fer el programa més robust:
# Però caldria fer aquest exemple tonto més robust ;-)
#set -e
 
# Source debconf library.
. /usr/share/debconf/confmodule  
 
db_version 2.0
#Establim que durant la configuració es pugui anar enrere amb botó cancelar
db_capb backup 
#Establim els nostres templates a no vistos per tal que debconf sempre els mostri
 
db_fset echod/port seen false  
db_input critical echod/port
db_go

db_fset echod/webserver seen false  
db_input critical echod/webserver
db_go

db_get echod/port
PORT="$RET"

db_get echod/webserver
WEBSERVER="$RET"

echo "El port escollit és: $PORT"
echo "El servidor escollit és: $WEBSERVER"

Feu el fitxer executable:

$ sudo chmod +x config

I ka el podeu provar:

$ sudo ./config

Com marcar la opció per defecte de un select (desplegable) i no mostrar-lo

Per marcar l'opció per defecte d'un desplegable (camp select de debconf) i no mostrar-lo (i per tant escollir l'opció per defecte)

# Override default frontend to readline, but allow user to select.
       debconf debconf/frontend select readline
       debconf debconf/frontend seen true

Si el que voleu en canvi és només indicar quina és l'opció per defecte però deixar a l'usuari canviar-la:

# Override default frontend to readline, but allow user to select.
       debconf debconf/frontend select readline
       debconf debconf/frontend seen false

Update Configuration File

TODO

$ man ucf
NAME
      ucf  -  Update Configuration File:  preserve user changes in configura‐
      tion files

SYNOPSIS
      ucf [options] <New File> <Destination>

      ucf [options] --purge <Destination>

DESCRIPTION
       This utility provides a means of asking the  user  whether  or  not  to
      accept  new  versions  of  configuration  files provided by the package
      maintainer, with various heuristics designed  to  minimize  interaction
      time.  It uses debconf to interact with the user, as per Debian policy.
      In the SYNOPSIS above, New file is the configuration file  as  provided
      by  the  package  (either shipped with the package, or generated by the
      maintainer scripts on the fly), and Destination is the  location  (usu‐
      ally under /etc) where the real configuration file lives, and is poten‐
      tially modified by the end user.  As far as possible, ucf  attempts  to
      preserve  the  ownership and permission of the New file as it is copied
      to the new location.

Troubleshooting

Depurar un fitxer config

Poseu la següent línia:

set -x

Al executar-se el config del paquet apareixerà la informació de depuració.

La plantilla #1 en templates té un camp «template» duplicat amb el nou valor «echod/webserver». Probablement dos plantilles no estan separades adequadament per un sol retorn de carro.

Si al executar:

$ sudo debconf-loadtemplate echod templates
La plantilla #1 en templates té un camp «template» duplicat amb el nou valor  
«echod/webserver». Probablement dos plantilles no estan separades adequadament per un 
sol retorn de carro.

Assegureu-vos que no hi ha res més que un salt de carro (salt de línia) entre la separació de plantilles (per exemple, no es poden deixar espais.)

A l'executar els scripts de configuració de debconf (config) no es mostren les plantilles

Si a l'executar debconf, de sobte les finestres de configuració deixen d'executar-se podem provar els passos indicats en aquesta secció per mirar de solucionar-ho.

Si configurem debconf en mode debug:

$ export DEBCONF_DEBUG=developer

Si ara executem l'script:

$ sudo debian/config 
debconf (developer): frontend started
debconf (developer): Trying to find a templates file..
debconf (developer): Trying debian/config.templates
debconf (developer): Trying debian/templates
debconf (developer): I guess it is debian/templates
debconf (developer): frontend running, package name is 
debconf (developer): starting debian/config
debconf (developer): <-- VERSION 2.0
debconf (developer): --> 0 2.0
debconf (developer): <-- CAPB backup
debconf (developer): --> 0 multiselect escape backup
debconf (developer): <-- INPUT critical echod/port
debconf (developer): --> 30 question skipped
...........

Veiem com les preguntes són saltades. Per solucionar aquest problema li hem d'indicar a debconf (mitjançant la comanda debconf-communicate) que la plantilla no ha esta vista encara:

$ sudo -i
$ echo fset echod/port seen false | debconf-communicate
$ echo fset echod/notconfigured seen false | debconf-communicate
$ exit

Problemes estranys. Comandes que hem demanat però que finalment no s'han executat

Vigileu amb l'ús de fakeroot per que només sens serveix per crear el paquet amb dpk-buildpackage!!! Si us adoneu que comandes que heu executat no s'han realitzat (per exemple heu esborrat un paquet del sistema amb --purge i els fitxers de configuració encara hi són...) és molt possible que la comanda l'hàgiu executat des de fakeroot.

Debianització de programes

Creació d'un paquet desde zero. Esquelet Makefile + svn-buildpackage

Passos previs. Paquets necessaris per crear paquets Debian

$ sudo apt-get install binutils gcc libc6-dev make fakeroot

Possiblement molt d'aquest paquets ja els trobareu instal.lats al sistema depenent de la seva importància.

Utilitats:

$ sudo apt-get install debmake dpkg-dev devscripts patch

Documentació:

$ sudo apt-get install debian-policy developers-reference

apt i dpkg

Apt/Dpkg: Beyond the basic use of installing programs, apt and dpkg have many features that are useful for packaging.

apt-cache dump - lists every package in the cache. This command is especially helpful in 
combination with a grep pipe such as apt-cache dump | grep foo to search for packages 
whose names or dependencies include foo.

apt-cache policy - lists the repositories (main/restricted/universe/multiverse) in 
which a package exists.

apt-cache show - displays information about a binary package.

apt-cache showsrc - displays information about a source package.

apt-cache rdepends - shows reverse dependencies for a package (which packages require 
the queried one.

dpkg -S - lists the binary package to which a particular file belongs.

dpkg -l - lists currently installed packages. This is similar to apt-cache dump but for 
installed packages.

dpkg -c - lists the contents of a binary package. It is useful for ensuring that files 
are installed to the right places.

dpkg -f - shows the control file for a binary package. It is useful for ensuring that 
the dependencies are correct.

grep-dctrl - searches for specialized information in packages. It is a specific use of 
the grep package (but not installed by default). 


DebHelper. Ajuda en el procés de Build

Instal·lació:

$ sudo apt-­get install debhelper dh­-make
NOTA: dh_make no forma part de debhelper però hi està íntimament lligat

dh_make és l'aplicació que ens ajuda a crear una carpeta debian a partir de la qual debianitzar un codi font

$ dh_make -­e you@example.com -f ../foo­0.1.tar.gz

debhelper ens proporciona una sèrie de guions de shell que ens ajuden en la creació de paquets debian. Podem obtenir la llista de guions de shell executant:

$ dpkg -L debhelper | grep bin
/usr/bin
/usr/bin/dh_builddeb
/usr/bin/dh_clean
/usr/bin/dh_compress
/usr/bin/dh_desktop
/usr/bin/dh_fixperms
/usr/bin/dh_gconf
/usr/bin/dh_gencontrol
/usr/bin/dh_iconcache
/usr/bin/dh_install
/usr/bin/dh_installcatalogs
/usr/bin/dh_installchangelogs
/usr/bin/dh_installcron
/usr/bin/dh_installdeb
/usr/bin/dh_installdebconf
/usr/bin/dh_installdirs
/usr/bin/dh_installdocs
/usr/bin/dh_installemacsen
/usr/bin/dh_installexamples
/usr/bin/dh_installinfo
/usr/bin/dh_installinit
/usr/bin/dh_installlogcheck
/usr/bin/dh_installlogrotate
/usr/bin/dh_installman
/usr/bin/dh_installmanpages
/usr/bin/dh_installmenu
/usr/bin/dh_installmime
/usr/bin/dh_installmodules
/usr/bin/dh_installpam
/usr/bin/dh_installppp
/usr/bin/dh_installudev
/usr/bin/dh_installwm
/usr/bin/dh_installxfonts
/usr/bin/dh_link
/usr/bin/dh_listpackages
/usr/bin/dh_makeshlibs
/usr/bin/dh_md5sums
/usr/bin/dh_movefiles
/usr/bin/dh_perl
/usr/bin/dh_python
/usr/bin/dh_scrollkeeper
/usr/bin/dh_shlibdeps
/usr/bin/dh_strip
/usr/bin/dh_suidregister
/usr/bin/dh_testdir
/usr/bin/dh_testroot
/usr/bin/dh_testversion
/usr/bin/dh_undocumented
/usr/bin/dh_usrlocal

Les següents taules ens mostren els fitxers que utilitzen algunes dels guions debhelper més importants:

Debhelper.png

Debhelper1.png

Recursos

dh_make. Configuració

Configuració:

Cal configurar certes variables d'entorn, per exemple posant a ~/.bashrc:

export DEBFULLNAME="Tu Nombre Completo"
export DEBEMAIL=tuemail@dondesea.com

Vegeu també:

dh_make

Sinopsis i funcionament

dh_make  [-bnlsmiadh]  [-c  license] [-e address] [-f file] [-t directory] [-o 
directory] [-p name] [--copy‐right license] [--email  address]  [--native]  [--file  
file]  [--library]  [--single]  [--indep]  [--multi]
[--kmod] [--kpatch] [--addmissing] [--templates directory] [--defaultless] [--overlay 
directory] [--package‐name name] [--dpatch] [--quilt] [--help] [--version]

TODO:

dh_make és una eina que permet convertir un codi font en un paquet Debian segons les normes de la Debian Policy.

Cal utilitzar dh_make dins d'un directori que contingui el codi font i que tingui el directori tingui el nom en format:

<packagename>-<version>

El <packagename> ha de ser en minúscules i pot contenir digits o guions.

If the directory name does not conform to this scheme, you must rename it before using dh_make. Alternatively, you may be able to use the --packagename option to force the package name.

CDBS (Common Debian Build System)

TODO:

cdbs (CDBS) is the Common Debian Build System. It provides (quoting from the package description) a "sane set of default rules upon which packages can build; any or all rules may be overridden as needed."

dh_make. Especificar la llicència: fitxer de copyright

Es pot fer amb l'opció -c:

$ dh_make -p miproyecto_1.0 -c gpl3 --createorig

dh_gencontrol

Vegeu dpkg-gencontrol

dh_installcron

IMPORTANT: Consulteu abans cron per tal de saber com funciona i també anacron

Del manual:

$ man dh_installcron
DH_INSTALLCRON(1)                                Debhelper                                DH_INSTALLCRON(1)

NAME
      dh_installcron - install cron scripts into etc/cron.*

SYNOPSIS
      dh_installcron [debhelper options] [--name=name]

DESCRIPTION
      dh_installcron is a debhelper program that is responsible for installing cron scripts.

FILES
      debian/package.cron.daily
      debian/package.cron.weekly
      debian/package.cron.monthly
      debian/package.cron.hourly
      debian/package.cron.d
          Installed into the appropriate etc/cron.*/ directory in the package build directory. 

OPTIONS
      --name=name
          Look for files named debian/package.name.cron.* and install them as etc/cron.*/name, instead of
          using the usual files and installing them as the package name.

SEE ALSO
      debhelper(7)

      This program is a part of debhelper.

AUTHOR
      Joey Hess <joeyh@debian.org>

7.4.15ubuntu1                                    2009-11-17                               DH_INSTALLCRON(1)

Per tant si voleu utilitzar anacron creeu els fitxers:

 debian/package.cron.daily
 debian/package.cron.weekly
 debian/package.cron.monthly
 debian/package.cron.hourly

On package és el nom del vostre paquet.

 debian/package.cron.d

On package és el nom del vostre paquet. El contingut dels fitxers s'instal·larà a:

/etc/cron.daily
/etc/cron.hourly
/etc/cron.weekly
/etc/cron.monthly

O per a cron

El contingut del fitxers s'instal·larà a:

/etc/cron.d
NOTA: Potser que en versions Ubuntu 9.10 o prèvies sigues diferent? Diferent manual:
$ man dh_installcron
DH_INSTALLCRON(1)                                                                 Debhelper                                                                DH_INSTALLCRON(1)

NAME
      dh_installcron - install cron scripts into etc/cron.*

SYNOPSIS
      dh_installcron [debhelper options] [--name=name]

DESCRIPTION
      dh_installcron is a debhelper program that is responsible for installing cron scripts into etc/cron.*/ in package build directories. The files
      debian/package.cron.daily, debian/package.cron.weekly, debian/package.cron.monthly, debian/package.cron.hourly, and debian/package.cron.d are installed.

OPTIONS
      --name=name
          Look for files named debian/package.name.cron.* and install them as etc/cron.*/name, instead of using the usual files and installing them as the package name.

dh_installlogrotate

IMPORTANT: Consulteu logrotate

Del manual:

$ man dh_installlogrotate
NAME
      dh_installlogrotate - install logrotate config files

SYNOPSIS
      dh_installlogrotate [debhelper options] [--name=name]

DESCRIPTION
      dh_installlogrotate is a debhelper program that is responsible for installing logrotate config files into etc/logrotate.d in package build directories.  Files named
      debian/package.logrotate are installed.

OPTIONS
      --name=name
          Look for files named debian/package.name.logrotate and install them as etc/logrotate.d/name, instead of using the usual files and installing them as the package
          name.

SEE ALSO
       debhelper(7)

       This program is a part of debhelper. 

AUTHOR
      Joey Hess <joeyh@debian.org>

Es a dir si a la carpeta debian teniu un fitxer:

debian/NOMDELVOSTREPAQUET.NOM.logrotate

Aleshores aquest fitxer serà instal·lat a:

/etc/logrotate.d/NOM

I per tant s'estarà configurant logrotate per al vostre paquet. --acacha 19:58, 21 març 2011 (UTC)

Provant els paquets creats. Lintian i Linda

Vegeu també Lintian i Linda

Devscripts

El paquet devscripts proporciona múltiples utilitats útils pels desenvolupadors.

sudo apt-get install devscripts

Les utilitats o comandes que proporciona són

$ dpkg -L devscripts | grep bin
/usr/bin
/usr/bin/bts
/usr/bin/checkbashisms
/usr/bin/cvs-debuild
/usr/bin/dd-list
/usr/bin/debchange
/usr/bin/debcommit
/usr/bin/debdiff
/usr/bin/debi
/usr/bin/debpkg
/usr/bin/debuild
/usr/bin/dget
/usr/bin/dpkg-depcheck
/usr/bin/dscverify
/usr/bin/grep-excuses
/usr/bin/mass-bug
/usr/bin/plotchangelog
/usr/bin/rc-alert
/usr/bin/rmadison
/usr/bin/svnpath
/usr/bin/annotate-output
/usr/bin/archpath
/usr/bin/cvs-debi
/usr/bin/cvs-debrelease
/usr/bin/deb-reversion
/usr/bin/debclean
/usr/bin/debrelease
/usr/bin/debrsign
/usr/bin/debsign
/usr/bin/dpkg-genbuilddeps
/usr/bin/mergechanges
/usr/bin/nmudiff
/usr/bin/pts-subscribe
/usr/bin/tagpending
/usr/bin/uscan
/usr/bin/uupdate
/usr/bin/whodepends
/usr/bin/who-uploads
/usr/bin/wnpp-alert
/usr/bin/requestsync
/usr/bin/dch
/usr/bin/debc
/usr/bin/cvs-debc   

debuild

Consulteu debuild

debchange (alias dch)

La comanda debchange (també coneguda com a dch) ens permet modificar els fitxers changelog de forma còmoda. Si executem debchange sense paràmetres (sempre des de l'arrel del nostra codi font o el que és el mateix que la carpeta debian estigui dins la carpeta on ens trobem) ens obre el fitxer debian/changelog amb el nostre editor preferit (variable d'entorn $EDITOR).

Però la veritable utilitat de debchange la trobareu en el següent exemple: imagineu-vos que acabeu de soluciona un BUG/error en el vostre codi font. Podeu executar:

$ debchange S'ha modificat la línia x del fitxer y per solucionar l'error 2325

Si ara executeu debchange obtindreu el següent fitxer changelog:

echod (0.1-1) unstable; urgency=low

  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
  *
  *Sha modificat la línia x del fitxer y per solucionar lerror 2325

Com podeu veure alguns caràcters s'han "d'escapar". La forma correcta hagués estat:

$ debchange S\'ha modificat la línia x del fitxer y per solucionar l\'error 2325

Si estem creant una nova versió del paquet podem canviar el fitxer changelog fàcilment amb:

$ debchange -i

echod (0.1-1ubuntu2) feisty; urgency=low

  * Nova versió

 -- Sergi Tur Badenas <sergi@localhost.localdomain>  Wed,  6 Jun 2007 12:58:10 +0200

echod (0.1-1) unstable; urgency=low

  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
  * Sha modificat la línia x del fitxer y per solucionar lerror 2325

-- Sergi Tur Badenas <sergi@localhost.localdomain>  Wed,  6 Jun 2007 12:53:05 +0200

NOTA: També podem utilitzar debchange utilitzant l'aliàs dch:

$ which dch
/usr/bin/dch
$ ls -la /usr/bin/dch
lrwxrwxrwx 1 root root 9 2007-04-21 03:09 /usr/bin/dch -> debchange

Dependències

Es controlen al fitxer debian/control, hi ha dos dependències:

  • Build-Depends: llista els paquets binaris que són necessaris per tal de poder compilar l'aplicació. No cal instal·lar els paquets que siguins també requerits pel paquet build-essential. La llisat d'aplicacions la trobareu a /usr/share/doc/build-essential/list.
  • Depends: La llista de paquets binaris dels que depèn l'aplicació. A l'exemple hello vegeu ${shlibs:Depends}, que és una variable que és modificada per dpkg-shlibdeps

DESTDIR

Vegeu Makefile i DESTDIR

Triggers, activadors, disparadors

Podeu trobar la info a:

$ man deb-triggers

deb-triggers(5)                                                                                                                    dpkg  
utilities                                                                                                                   deb-triggers(5)

NAME
      deb-triggers - package triggers

SYNOPSIS
      triggers

DESCRIPTION
      A package declares its relationship to some trigger(s) by including a triggers file in its control archive (i.e. DEBIAN/triggers during package creation).

      This file contains directives, one per line. Leading and trailing whitespace and everything after the first # on any line will be trimmed, and empty lines will be ignored.

      The trigger control directives currently supported are:

           interest trigger-name

           Specifies that the package is interested in the named trigger. All triggers in which a package is interested must be listed using this directive in the triggers control file.

           activate trigger-name

           Arranges that changes to this package's state will activate the specified trigger. The trigger will be activated at the start of the following operations: unpack, configure, remove (including for the benefit of a conflicting package), purge and deconfigure.

           If  this package disappears during the unpacking of another package the trigger will be activated when the disappearance is noted towards the end of the unpack. Trigger processing, and transition from triggers-awaited to installed, does not cause activations.  In
           the case of unpack, triggers mentioned in both the old and new versions of the package will be activated.

      Unknown directives are an error which will prevent installation of the package.

SEE ALSO
      dpkg-trigger(1), dpkg(1), /usr/share/doc/dpkg-dev/triggers.txt.gz.

i

$ sudo gunzip /usr/share/doc/dpkg-dev/triggers.txt.gz
$ cat /usr/share/doc/dpkg-dev/triggers.txt
 
 TRIGGERS
========

Introduction
------------

A dpkg trigger is a facility that allows events caused by one package
but of interest to another package to be recorded and aggregated, and
processed later by the interested package.  This feature simplifies
various registration and system-update tasks and reduces duplication
of processing.

(NB: Triggers are intended for events that occur during package
installation, not events that occur in general operation.)


Concepts
--------

Each trigger is named, and at any time zero or more packages may be
interested in it.

We currently envisage three kinds of triggers:
 * Explicit triggers.  These can be activated by any program
   by running dpkg-trigger (at any time, but ideally from a maintainer
   script).
 * File triggers.  These are activated automatically by dpkg
   when a matching file is installed, upgraded or removed as part
   of a package.  They may also be explicitly activated by running
   dpkg-trigger.
 * Future kinds of special triggers, which are activated by magic code
   in dpkg itself.  Currently none are defined besides file triggers.

A trigger is always activated by a particular package.

Trigger names contain only printing 7-bit ascii characters (no
whitespace).  Each trigger kind has a distinct subset of the trigger
name space so that the kind can be determined from the name.  After we
run out of straightforward syntaxes, we will use <kind>:<details>.

When a trigger is activated, it becomes pending for every package
which is interested in the trigger at that time.  Each package has a
list of zero or more pending triggers.  Repeated activation of the
same trigger has no additional effect.  Note that in general a trigger
will not be processed immediately when it is activated; processing is
deferred until it is convenient (as described below).

At a trigger activation, the interested packages(s) are added to the
triggering package's list of triggers-awaited packages; the triggering
package is said to await the trigger processing.

A package which has pending triggers, or which awaits triggers, is not
considered properly installed.  There are two new dpkg status values,
`triggers-pending' and `triggers-awaited', which lie between
`config-failed' and `installed'.


Details - Overview table
------------------------

  Status      Pending   Awaited   Satisfies  Remedy
              triggers  triggers  Depends

  unpacked    never      maybe    No    postinst configure
  c.-failed   never      maybe    No    postinst configure (when requested)
  t.-awaited  yes        always   No    postinst triggered + fix awaited pkg(s)
  t.-awaited  no         always   No    fix awaited package(s)
  t.-pending  always     never    Yes   postinst triggered
  installed   never      never    Yes   n/a

Packages in t-awaited and t-pending demand satisfaction of their
dependencies just like packages in installed.


Details - triggering package
----------------------------

When a package T activates a trigger in which a package I is
interested, I is added to the list of packages whose trigger
processing is awaited by T.  Zero or more packages I may be added as a
result of any particular trigger activation, depending on how many
packages were interested.  (If T chooses, explicit trigger activation
using dpkg-trigger of I by T need not make T become triggers-awaited
in this way..)

A package which awaits trigger processing but would otherwise be
`installed' or `triggers-pending' is considered to be in state
`triggers-awaited'.  Packages in `triggers-awaited' do not satisfy
Depends dependencies.

Every triggered package I in T's list of awaited packages either has a
nonempty list of pending triggers, or is in `config-failed' or worse.
When I enters `installed' (or `config-files' or `not-installed'), the
entry in T's list of awaited packages is removed so that T may, if it
no longer awaits any packages, become `installed' or
`triggers-pending'.

Packages in `config-files' or `not-installed' do not await triggers.


Details - triggered package
---------------------------

When one of the triggers in which a package is interested is
activated, the triggered package has the trigger added to its list of
pending triggers.  Packages with a nonempty list of pending triggers
which would otherwise be in state `installed' are in state
`triggers-pending' instead, so if the package was previously
`installed' it becomes `triggers-pending'.

If a package has nonempty lists both of pending and awaited triggers,
then it is in `triggers-awaited'.  Nevertheless efforts will still be
made to process its triggers so as to make the list of pending
triggers empty.

To restore a package in state `triggers-pending' to `installed', or to
process pending triggers of a package with both pending and awaited
triggers, dpkg will run the postinst script:
   postinst triggered "<trigger-name> <trigger-name> ..."

This will be attempted for each relevant package at the end of each
dpkg run; so, normally, in the same dpkg run as the event which made
the package go to `triggers-pending'.  This leaves packages in
reasonable states by default.

If the `postinst triggered' run fails the package goes to
`config-failed', so that the trigger processing will not be attempted
again until explictly requested.


             |
             V
       ,------------.
       |  unpacked  |
       `------------'
             |
             |
  (automatic)|     ,----------.
             |     | config-  |
             |     |  failed  |
             |     `----------'
             |       |      ^
             |       |      |
             |,---<--'      |       ,------------------------------.
             |  (user       |       |    triggers-pending          |
    postinst |   request)   |       |            or                |
 "configure" |              |       | t.-awaited with some pending |
             |              |       `------------------------------'
             |              |                  |    ^
             |`----->------'|                  |    |
             |    error     |        postinst  |    |
             |              |      "triggered" |    | trigger(s)
             |              |      (automatic) |    |  activated
             |              |                  |    |
             |              `-----<-----------'|    |
             |                  error          |    |
             |                                 |    |
             V                                 V    |
       ,--------------------------------------------------.
       |   installed  or  t.-awaited with none pending    |
       `--------------------------------------------------'

Packages in `config-failed' or worse are never considered to have
lists of pending triggers.  A package whose postinst is being run
can however acquire pending triggers during that run (ie, a package
can trigger itself).

This means that if a triggering package T awaits trigger processing by
an interested package I, and I goes to `config-failed' or worse (eg,
during unpack for upgrade), then when I is reconfigured (goes to
`installed') or removed, T will no longer await processing by I, so
that T may automatically go from `triggers-awaited' to `installed'.

Or to put it another way, triggered actions are considered irrelevant
if the interested package I is not configured.  When I's postinst is
called with `configure', it must do whatever actions are necessary to
deal with any trigger activations which might have occured while it
was not configured, just as if the package was being configured for
the first time.

Trigger processing should be idempotent.  The list of triggers being
processed is provided to the postinst only so that it can optimise
away redundant processing.

In that case, where an interested package has more than one trigger
and wants to process them differently, the list of triggers can be can
be examined in a shell script like this:
   case " $3 " in
   *" trigger-name-a "*)  process-trigger-a ;;
   esac
Generally each trigger name should be tested for separately, as the
postinst will often be called for several triggers at once.

Note that if a package both activates triggers in other packages, and
is interested in triggers of its own, its postinst may run for trigger
processing before the postinst(s) of the package(s) it has triggered.


Timing guarantees, races, etc.
------------------------------

Activating a trigger will not have any immediate effect, although
putative resulting status changes will show up in dpkg --status etc.
(Putative because the actual status changes may depend on the state of
trigger interests when dpkg processes the trigger activation into
the status database, rather than that when dpkg --status is run.)

A package is only guaranteed to become notified of a trigger
activation if it is continuously interested in the trigger, and never
in `config-failed' or worse, during the period from when the trigger
is activated until dpkg runs the package postinst (either due to
--configure --pending, or at the end of the relevant run, as described
above).  Subsequent to activation and before notification, the
interested package will not be considered in state `installed', so
long as the package remains interested, and the triggering package
will not be considered `installed'.

If the package is not in state `installed', `triggers-pending' or
`triggers-awaited' then pending triggers are not accumulated.
However, if such a package (between `half-installed' and
`config-failed' inclusive) declares some trigger interests then the
triggering packages *will* await their configuration (which implies
completion of any necessary trigger processing) or removal.

It is not defined in what order triggers will run.  dpkg will make
some effort to minimise redundant work in the case where many packages
have postinst trigger processing activating another package's triggers
(for example, by processing triggers in fifo order during a single
dpkg run).  Cycles in the triggering graph are prohibited and will
eventually, perhaps after some looping, be detected by dpkg and cause
trigger processing to fail; when this happens one of the packages
involved will be put in state `config-failed' so that the trigger loop
will not be reattempted.  See `Cycle detection' below.


Explicit triggers
-----------------

Explicit triggers have names with the same syntax as package names,
*but* should *not* normally be named identically to a package.

When choosing an explicit trigger name it is usually good to include a
relevant package name or some other useful identifier to help make the
trigger name unique.  On the other hand, explicit triggers should
generally not be renamed just because the interested or triggering
packages' names change.

Explicit trigger names form part of the interface between packages.
Therefore in case of wider use of any trigger the name and purpose
should be discussed in the usual way and documented in the appropriate
packaging guidelines (eg, in policy).


File triggers
-------------

File triggers have names of the form
  /path/to/directory/or/file
and are activated when the specified filesystem object, or any object
under the specified subdirectory, is created, updated or deleted by
dpkg during package unpack or removal.  The pathname must be absolute.

File triggers should not generally be used without mutual consent.
The use of a file trigger, and the name of the trigger used, should be
stated in policy, so that a package which creates a relevant file in a
maintainer script can activate the trigger explictly.

File triggers must definitely not be used as an escalation tool in
disagreements between different packages as to the desired contents of
the filesystem.  Trigger activation due to a particular file should
not generally modify that file again.

Configuration files (whether dpkg-handled conffiles or not), or any
other files which are modified at times other than package management,
should not rely on file triggers detecting all modifications; dpkg
triggers are not a general mechanism for filesystem monitoring.

If there are or might be directory symlinks which result in packages
referring to files by different names, then to be sure of activation
all of the paths which might be included in packages should be listed.
The path specified by the interested package is matched against the
path included in the triggering package, not against the truename of
the file as installed.  Only textually identical filenames (or
filenames where the interest is a directory prefix of the installed
file) are guaranteed to match.

A file trigger is guaranteed to be activated before the file in
question is modified by dpkg; on the other hand, a file trigger might
be activated even though no file was actually modified.  Changes made
by dpkg to the link count of a file, or to solely the inode number
(ie, if dpkg atomically replaces it with another identical file), are
not guaranteed to cause trigger activation.

Because of the restriction on trigger names, it is not possible to
declare a file trigger for a directory whose name contains whitespace,
i18n characters, etc.  Such a trigger should not be necessary.


Package declarations regarding triggers
---------------------------------------

See deb-triggers(5).

Support future extension of the trigger name syntax with additional
dpkg-generated triggers is as follows: a package which is interested
in any unsupported trigger kinds cannot be configured (since such a
package cannot be guaranteed to have these triggers properly activated
by dpkg).  Therefore no package can be interested in any unsupported
trigger kinds and they can be freely activated (both by `activate' and
by dpkg-trigger).  dpkg-deb will be changed to warn about unrecognised
trigger names syntaxes and unrecognised trigger control directives.


New command-line interfaces to dpkg tools
-----------------------------------------

See dpkg(1).

Here is a summary of the behaviours:

 Command line		Trigproc	Trigproc	Configure
			these		any triggered
 ----------------------+---------------+---------------+-----------------
 --unpack		no		usually[1]	none
 --remove		n/a		usually[1]	none
 --install		n/a		usually[1]	these
 --configure -a		any needed	usually[1]	any needed
 --configure <some>	if needed	usually[1]	must, or trigproc
 --triggers-only -a	any needed	usually[1]	none
 --triggers-only <some>	must		usually not[1]	none

 [1] can be specified explicitly by --triggers or --no-triggers


See dpkg-trigger(1).

A trigger may be activated explicitly with:
   dpkg-trigger [--by-package <package>] <name-of-trigger>
   dpkg-trigger --no-await <name-of-trigger>

The --verbose and --query options will show which packages were
interested and what the current activation state is, on stdout in
human- and machine-readable (untranslated) format.  Without any
options there will be no output to stdout, and none to stderr unless
dpkg-trigger is unable to make a record of the trigger activation.
With --query no trigger is activated.

NB that in the case of a file trigger the name of the trigger is
needed, not the name of a file which would match the trigger.


apt and aptitude
----------------

These must be taught about the new `triggers-awaited' and
`triggers-pending' states.  Packages in these states should be treated
roughly like those in `unpacked': the remedy is to run dpkg
--configure.

Normally apt and aptitude will not see packages in `triggers-pending'
since dpkg will generally attempt to run the triggers thus leaving the
package in `config-failed' or `installed'.

Note that automatic package management tools which call dpkg (like apt
and aptitude) should not attempt to configure individual packages in
state `triggers-pending' (or indeed `triggers-awaited') with dpkg
--triggers-only <package>... or dpkg --no-triggers --configure <package>...,
or similar approaches. This might defeat dpkg's trigger cycle detection.

A package management tool which will run dpkg --configure --pending at
the end may use --no-triggers on its other dpkg runs.  This would be
more efficient as it allows more aggressive deferral (and hence more
unification) of trigger processing.


Error handling
--------------

Packages should be written so that they DO NOT BREAK just because
their pending triggers have not yet been run.  It is allowed for the
functionality relating to the unprocessed trigger to fail (ie, the
package which is awaiting the trigger processing may be broken), but
the remainder of the interested package must work normally.

For example, a package which uses file triggers to register addons
must cope with (a) an addon being dropped into the filesystem but not
yet registered and (b) an addon being removed but not yet
deregistered.  In both of these cases the package's main functionality
must continue to work normally; failure of the addon in question is
expected, warning messages are tolerable, but complete failure of the
whole package, or failures of other addons, are not acceptable.

dpkg cannot ensure that triggers are run in a timely enough manner for
pathological error behaviours to be tolerable.


Where a trigger script finds bad data provided by a triggering
package, it should generally report to stderr the problem with the bad
data and exit nonzero, leaving the interested package in config-failed
and the triggering package in triggers-awaited and thus signalling the
problem to the user.

Alternatively, in some situations it may be more desirable to allow
the interested package to be configured even though it can only
provide partial service.  In this case clear information will have to
be given in appropriate places about the missing functionality, and a
record should be made of the cause of the errors.  This option is
recommended for situations where the coupling between the interested
and triggering package is particularly loose; an example of such a
loose coupling would be Python modules.



WORKED EXAMPLE - SCROLLKEEPER
=============================

Currently, every Gnome program which comes with some help installs the
help files in /usr/share/gnome/help and then in the postinst runs
scrollkeeper-update.  scrollkeeper-update reads, parses and rewrites
some large xml files in /var/lib/scrollkeeper; currently this
occurs at every relevant package installation, upgrade or removal.

When triggers are available, this will work as follows:

 * gnome-foobar will ship its `omf' file in /usr/share/omf as
   normal, but will not contain any special machinery to invoke
   scrollkeeper.

 * scrollkeeper will in its triggers control file say:
       interest /usr/share/omf
   and in its postinst say:
       scrollkeeper-update-now -q

   dpkg will arrange that this is run once at the end of each run
   where any documentation was updated.

   Note that it is not necessary to execute this only on particular
   postinst "$1" values; however, at the time of writing, scrollkeeper
   does this:

       if [ "$1" = "configure" ]; then
         printf "Rebuilding the database. This may take some time.\n"
         scrollkeeper-rebuilddb -q
       fi

   and to retain this behaviour, something along the following lines
   would be sensible:

       if [ "$1" = "configure" ]; then
         printf "Rebuilding the database. This may take some time.\n"
         scrollkeeper-rebuilddb -q
       else
         printf "Updating GNOME help database.\n"
         scrollkeeper-update-now -q
       fi

 * dh_scrollkeeper will only adjust the DTD declarations and no longer
   edit maintainer scripts.


Full implementation of the transition plan defined below, for
scrollkeeper, goes like this:

 1. Update scrollkeeper:
     - Add a `triggers' control archive file containing
           interest /usr/share/omf
     - Make the postinst modifications as described above.
     - Rename scrollkeeper-update to scrollkeeper-update-now
     - Provide a new wrapper script as scrollkeeper-update:
	   #!/bin/sh -e
	   if type dpkg-trigger >/dev/null 2>&1 && \
	      dpkg-trigger /usr/share/omf; then
		 exit 0
	   fi
	   exec scrollkeeper-update-now "$@"

 2. In gnome-policy chapter 2, `Use of scrollkeeper',
     - delete the requirement that the package must depend on
       scrollkeeper
     - delete the requirement that the package must invoke
       scrollkeeper in the postinst and postrm
     - instead say:

         OMF files should be installed under /usr/share/omf in the
         usual way.  A dpkg trigger is used to arrange to update the
         scrollkeeper documentation index automatically and no special
         care need be taken in packages which supply OMFs.

         If an OMF file is placed, modified or removed other than as
         an file installed in the ordinary way by dpkg, the dpkg file
         trigger `/usr/share/omf' should be activated; see the dpkg
         triggers specification for details.

         Existing packages which Depend on scrollkeeper (>= 3.8)
         because of dh_scrollkeeper or explicit calls to
         scrollkeeper-update should be modified not to Depend on
         scrollkeeper.

 3. Update debhelper's dh_scrollkeeper not to edit maintainer
    scripts.  One of dh_scrollkeeper or lintian should be changed to
    issue a warning for packages with scrollkeeper (>= 3.8) in the
    Depends control file line.

 4. Remove the spurious dependencies on scrollkeeper, at our leisure.
    As a bonus, after this is complete it will be possible to remove
    scrollkeeper while keeping all of the documentation-supplying
    gnome packages installed.

 5. If there are any packages which do by hand what dh_scrollkeeper
    does, change them not to call scrollkeeper-update and drop
    their dependency on scrollkeeper.

This is not 100% in keeping with the full transition plan defined
below: if a new gnome package is used with an old scrollkeeper, there
is some possibility that the help will not properly be available.

Unfortunately, dh_scrollkeeper doesn't generate the scrollkeeper
dependency in the control file, which makes it excessively hard to get
the dependency up to date.  The bad consequences of the inaccurate
dependencies are less severe than the contortions which would be
required to deal with the problem.


TRANSITION PLAN
===============


Old dpkg to new dpkg
--------------------

The first time a trigger-supporting dpkg is run on any system, it will
activate all triggers in which anyone is interested, immediately.

These trigger activations will not be processed in the same dpkg run,
to avoid unexpectedly processing triggers while attempting an
unrelated operation.  dpkg --configure --pending (and not other dpkg
operations) will run the triggers, and the dpkg postinst will warn the
user about the need to run it (if this deferred triggers condition
exists).  (Any triggers activated or reactivated *after* this
mass-activation will be processed in the normal way.)

To use this correctly:
 * Packages which are interested in triggers, or which want to
    explicitly activate triggers, should Depend on the
    triggers-supporting version of dpkg.
 * Update instructions and tools should arrange to run
    dpkg --configure --pending
   after the install; this will process the pending triggers.

dpkg's prerm will check for attempts to downgrade while triggers are
pending and refuse.  (Since the new dpkg would be installed but then
refuse to read the status file.)  In case this is necessary a separate
tool will be provided which will:
  * Put all packages with any pending triggers into state
    `config-failed' and remove the list of pending triggers.
  * Remove the list of awaited triggers from every package.  This
    may cause packages to go from `triggers-awaited' to `installed'
    which is not 100% accurate but the best that can be done.
  * Remove /var/lib/dpkg/triggers (to put the situation to that which
    we would have seen if the trigger-supporting dpkg had never been
    installed).


Higher-level programs
---------------------

The new dpkg will declare versioned Conflicts against apt and aptitude
and other critical package management tools which will be broken by
the new Status field values.  Therefore, the new higher-level tools
will have to be deployed first.

The new dpkg will declare versioned Breaks against any known
noncritical package management tools which will be broken by the new
Status field value.


Transition hints for existing packages
--------------------------------------

When a central (consumer) package defines a directory where other leaf
(producer) packages may place files and/or directories, and currently
the producer packages are required to run an `update-consumer' script
in their postinst:
 1. In the relevant policy, define a trigger name which is the name of
    the directory where the individual files are placed by producer
    packages.
 2. Update the consumer package:
    * Declare an interest in the trigger.
    * Edit update-consumer so that if it is called without --real
      it does the following:
	  if type dpkg-trigger >/dev/null 2>&1 && \
	     dpkg-trigger name-of-trigger; then
		exit 0
	  fi
      If this fails to cause update-consumer to exit, it should do
      its normal update processing.  Alternatively, if it is more
      convenient, update-consumer could be renamed and supplanted with
      a wrapper script which conditionally runs the real
      update-consumer.
    * In the postinst, arrange for the new `triggered' invocation to
      run update-consumer --real.  The consumer package's postinst
      will already run update-consumer during configuration, and this
      should be retained and supplemented with the --real option (or
      changed to call the real script rather than the wrapper).
 3. Update the producer packages:
    * In the postinst, remove the call to update-consumer
    * Change the dependency on consumer to be versioned, specifying a
      trigger-interested consumer.
    This can be done at our leisure.  Ideally for loosely coupled
    packages this would be done only in the release after the one
    containing the triggers-interested consumer, to facilitate partial
    upgrades and backports.
 4. After all producer packages have been updated according to step 3,
    `update-consumer' has become an interface internal to the consumer
    and need no longer be kept stable.  If un-updated producers are
    still of interest, incompatible changes to `update-consumer' imply
    a versioned Breaks against the old producers.
(See also `Transition plan', below.)

If there are several consumer packages all of which are interested in
the features provided by producer packages, the current arrangements
usually involve an additional central switchboard package (eg,
emacsen-common).  In this case:

 -- NOTE - this part of the transition plan is still a proof of
           concept and we might yet improve on it

 1. Define the trigger name.
 2. Update the switchboard to have any new functionality needed by the
    consumers in step 3 (2nd bullet).
 3. Update the consumer packages:
    * Declare an interest in the trigger.
    * In the postinst, arrange for the new `trigger' invocation to run
      the compilation/registration process.  This may involve scanning
      for new or removed producers, and may involve new common
      functionality from the switchboard (in which case a versioned
      Depends is needed).
    * The old interface allowing the switchboard to run
      compilation/registration should be preserved, including
      calls to the switchboard to register this consumer.
 4. When all consumers have been updated, update the switchboard:
    * Make the registration scripts called by producers try to
      activate the trigger and if that succeeds quit without
      doing any work (as for bullet 2 in the simple case above).
    * Versioned Breaks, against the old (pre-step-3) consumers.
 5. After the switchboard has been updated, producers can be updated:
    * Remove the calls to the switchboard registration/compilation
      functions.
    * Change the dependency on the switchboard to a versioned one,
      specifying the one which Breaks old consumers.  Alternatively,
      it may be the case that the switchboard is no longer needed (or
      not needed for this producer), in which case the dependency on
      the switchboard can be removed in favour of an appropriate
      versioned Breaks (probably, identical to that in the new
      switchboard).
 6. After all the producers have been updated, the cruft in the
    consumers can go away:
    * Remove the calls to the switchboard's registration system.
    * Versioned Breaks against old switchboards, or versioned Depends
      on new switchboards, depending on whether the switchboard is
      still needed for other common functionality.
 7. After all of the producers and consumers have been updated, the
    cruft in the switchboard can go away:
    * Remove the switchboard's registration system (but not obviously
      the common functionality from step 3, discussed above).
    * Versioned Breaks against pre-step-6 consumers and pre-step-5
      producers.


DISCUSSION
==========

The activation of a trigger does not record details of the activating
event.  For example, file triggers do not inform the package of the
filename.  In the future this might be added as an additional feature,
but there are some problems with this.


Broken producer packages, and error reporting
---------------------------------------------

Often trigger processing will involve a central package registering,
compiling or generally parsing some data provided by a leaf package.

If the central package finds problems with the leaf package data it is
usually more correct for only the individual leaf package to be
recorded as not properly installed.  There is not currently any way to
do this and there are no plans to provide one.

The naive approach of giving the postinst a list of the triggering
packages does not work because this information is not recorded in the
right way (it might suffer from lacunae); enhancing the bookkeeping
for this to work would be possible but it is far better simply to make
the system more idempotent.  See above for the recommended approach.




INTERNALS
=========

On-disk state
-------------

A single file /var/lib/dpkg/triggers/File lists all of the filename
trigger interests in the form
   /path/to/directory/or/file package

For each explicit trigger in which any package is interested,
a file /var/lib/dpkg/triggers/<name-of-trigger> is a list of
the interested packages, one per line.

These interest files are not updated to remove a package just because
a state change causes it not to be interested in any triggers any more
- they are updated when we remove or unpack.

For each package which has pending triggers, the status file contains
a Triggers-Pending field which contains the space-separated names of
the pending triggers.  For each package which awaits triggers the
status file contains a Triggers-Awaited field which contains the
*package* names of the packages whose trigger processing is awaited.
See `Details - Overview table' above for the invariants which relate
Triggers-Pending, Triggers-Awaited, and Status.

During dpkg's execution, /var/lib/dpkg/triggers/Unincorp is a list of
the triggers which have been requested by dpkg-trigger but not yet
incorporated in the status file.  Each line is a trigger name followed
by one or more triggering package names.  The triggering package name
"-" is used to indicate one or more package(s) which did not need to
await the trigger.

/var/lib/dpkg/triggers/Lock is the fcntl lockfile for the trigger
system.  Processes hang onto this lock only briefly: dpkg-trigger
to add new activations, or dpkg to incorporate activations (and
perhaps when it updates interests).  Therefore this lock is always
acquired with F_GETLKW so as to serialise rather than fail on
contention.


Processing
----------

dpkg-trigger updates triggers/Unincorp, and does not read or write the
status file or take out the dpkg status lock.  dpkg (and dpkg-query)
reads triggers/Unincorp after reading /var/lib/dpkg/status, and after
running a maintainer script.  If the status database is opened for
writing then the data from Unincorp is moved to updates as
Triggers-Pending and Triggers-Awaited entries and corresponding Status
changes.

This means that dpkg is guaranteed to reincorporate pending trigger
information into the status file only 1. when a maintainer script has
finished, or 2. when dpkg starts up with a view to performing some
operation.

When a package is unpacked or removed, its triggers control file will
be parsed and /var/lib/dpkg/triggers/* updated accordingly.

Triggers are run as part of configuration.  dpkg will try to first
configure all packages which do not depend on packages which are
awaiting triggers, and then run triggers one package at a time in the
hope of making useful progress.  (This will involve a new `dependtry'
level in configure.c's algorithm.)  The only constraint on the
ordering of postinsts is only the normal Depends constraint, so the
usual Depends cycle breaking will function properly.  See `Cycle
detection' below regarding cycles in the `A triggers B' relation.


Processing - Transitional
-------------------------

The case where a triggers-supporting dpkg is run for the first time is
detected by the absence of /var/lib/dpkg/triggers/Unincorp.  When the
triggers-supporting dpkg starts up without this it will set each
package's list of pending triggers equal to its interests (obviously
only for packages which are in `installed' or `triggers-pending').
This may result in a package going from `installed' to
`triggers-pending' but it will not create the directory at this time.
Packages marked as triggers-pending in this way will not be scheduled
for trigger processing in this dpkg run.

dpkg will also at this time create /var/lib/dpkg/triggers if
necessary, triggers/File, triggers/Unincorp, and the per-trigger
package lists in /var/lib/dpkg/triggers/<trigger-name>, so that future
trigger activations will be processed properly.

Only dpkg may create /var/lib/dpkg/triggers and only when it is
holding the overall dpkg status lock.

dpkg and/or dpkg-deb will be made to reject packages containing
Triggers-Pending and Triggers-Awaited control file fields, to prevent
accidents.


Cycle detection
---------------

In addition to dependency cycles, triggers raise the possibility of
mutually triggering packages - a cycle detectable only dynamically,
which we will call a `trigger cycle'.

Trigger cycles are detected using the usual hare-and-tortoise
approach.  Each time after dpkg runs a postinst for triggers, dpkg
records the set of pending triggers (ie, the set of activated <pending
package, trigger name> tuples).  If the hare set is a superset of the
tortoise set, a cycle has been found.

For guaranteed termination, it would be sufficient to declare a cycle
only when the two sets are identical, but because of the requirement
to make progress we can cut this short.  Formally, there is supposed
to be a complete ordering of pending trigger sets satisfying the
condition that any set of pending triggers is (strictly) greater than
all its (strict) subsets.  Trigger processing is supposed to
monotonically decrease the set in this ordering.  (The set elements
are <package, trigger name> tuples.)

(See `Processing' above for discussion of dependency cycles.)

--

Es pot executar un trigger de forma explícita amb dpkg-trigger:

IMPORTANT: només deixa utilitzar dpkg-trigger des de scripts de manteniment.
$ dpkg-trigger update-gosa
dpkg-trigger: s'ha d'executar dpkg-trigger des d'un script de mantenidor (o amb una opció --by-package)

Els paquets poden ser activats/disparats/triggered, per exemple el paquet gosa té el següent script de postinstal·lació

$ cat /var/lib/dpkg/info/gosa.postinst
case "$1" in
  configure)
      ;;

  abort-upgrade|abort-remove|abort-deconfigure)
     ;;

 triggered)
     /usr/sbin/update-gosa
     exit 0
     ;;

 *)
     echo "postinst called with unknown argument \`$1'" >&2
     exit 1
     ;;
esac

Troubleshooting. Resol·lució de problemes

Error 29 executing dpkg-buildpackage -rfakeroot -D -us -uc failedbuildpackage

Si al construir el paquet us dona l'error:

cd ../ubuntucustom-0.1;export DEBFULLNAME="Sergi Tur Badenas";export DEBEMAIL="sergi.tur@upc.edu";/usr/bin/debuild
 dpkg-source -b ubuntucustom-0.1
dpkg-source: info: using source format `3.0 (quilt)'
dpkg-source: info: building ubuntucustom using existing ./ubuntucustom_0.1.orig.tar.gz
dpkg-source: error: cannot read ubuntucustom-0.1/.pc/applied-patches: El fitxer o directori no existeix
dpkg-buildpackage: error: dpkg-source -b ubuntucustom-0.1 gave error exit status 2
debuild: fatal error at line 1337:
dpkg-buildpackage -rfakeroot -D -us -uc failed
make: *** [create_package] Error 29

El curiós és que en el meu cas si executo només:

$ cd ../ubuntucustom-0.1;export DEBFULLNAME="Sergi Tur Badenas";export DEBEMAIL="sergi.tur@upc.edu";/usr/bin/debuild
...
dpkg-source -b ubuntucustom-0.1
dpkg-source: info: using source format `3.0 (quilt)'
dpkg-source: info: building ubuntucustom using existing ./ubuntucustom_0.1.orig.tar.gz
dpkg-source: info: building ubuntucustom in ubuntucustom_0.1-1.debian.tar.gz
dpkg-source: info: building ubuntucustom in ubuntucustom_0.1-1.dsc
...

Tot funciona correctament. En canvi si executo el mateix des de un makefile dona l'error indicat.

dpkg-source: error: can't build with source format '3.0 (quilt)': no orig.tar file found

Aquest error passa al executar svn-buildpackage:

$ svn-buildpackage
...
 dpkg-source -b openfpnet-common-0.1
dpkg-source: error: can't build with source format '3.0 (quilt)': no s'ha trobat el fitxer orig.tar
dpkg-buildpackage: error: dpkg-source -b openfpnet-common-0.1 gave error exit status 255
Command 'dpkg-buildpackage' failed in '/home/sergi/SVN/openfpnet-common/build-area/openfpnet-common-0.1', how to continue now?   
[Qri?]: 

Em toca posar Q i sortir. EL problema és que la carpeta:

../tarballs/

Està buida.

Cal crear els orig.tar.gz. Hi ha una tasca make (createorig) al Makefile:

http://www.iesebre.com/subversion/projectes/openfpnet-common/openfpnet-common/trunk/Makefile

Per tant cal que feu:

$ make createorig

O millor encara realment no utilitzeu svn-buildpackage directament. Utilitzeu la tasca:

$ make create-package

Que depèn de createorig i així us eviteu poder tenir aquest problema.

######################

Antiga documentació...

Versió quilt (a partir de Ubuntu 10.10?)

$ mkdir nom_paquet
$ cd nom_paquet
$ svn export ~/workspace/paquet-0.1
$ tar cvzf paquet-0.1.tar.gz paquet-0.1
$ cd nom_paquet-0.1
$ dh_make -f ../paquet.tar.gz -c gpl3 -e creador@exemple.com --createorig
$ sudo dpkg-buildpackage

running debsign failed

L'ordre svn-buildpackage intenta firmar els paquets.. Si al executar:

$ make create_package

o

$ svn-buildpackage --svn-builder="debuild"
NOTA: L'eina debuild és similar a dpkg-buildpackage però fa altres tasques extres com comprovar el paquet debian amb lintian o signar el paquet amb debsign.

Us dona l'error:

Could not find a signing program (pgp or gpg)!
debuild: fatal error at line 1269:
running debsign failed

Command '/bin/sh -c debuild ' failed in '/home/sergi/SVN/openfpnet-common/build-area/openfpnet-common-0.1', how to continue now?  [Qri?]: 

Fixeu-vos la línia en negreta, us falta el paquet gpg:

$ sudo apt-get install gnupg

Si l'error persisteix és que no teniu les claus adequades, tingueu en compte que realment heu executat del següent Makefile o similar:

http://www.iesebre.com/subversion/projectes/debianesqueleton/trunk/Makefile

La tasca:

$ make create_package

Que realment executa:

create_package: createorig
	#create_package
	export DEBFULLNAME="$(DEBIAN_PACKAGE_CREATOR_FULLNAME)";export DEBEMAIL="$(DEBIAN_PACKAGE_CREATOR_EMAIL)";svn-buildpackage --svn-builder="debuild"

És important que les variables DEBFULLNAME i DEBEMAIL siguin coherents amb les claus que teniu. En el meu cas els valors són:

DEBIAN_PACKAGE_CREATOR_FULLNAME=Sergi Tur Badenas
DEBIAN_PACKAGE_CREATOR_EMAIL=sergi.tur@upc.edu

Aquí hi ha dos opcions, o no teniu les claus i les heu de crear noves o ja les teniu en algun altre ordinador:

Per a crear les claus:

Consulteu Gnupg#Creaci.C3.B3_de_claus

Per a exporta-les:

Consulteu Gnupg#Exportar.2FImportar

NOTA: Una opció més expeditiva és copia la carpeta oculta ~/.gnupg de la home d'una màquina a un altre. Això és factible si a la màquina de destinació no hi havien claus

Consulteu:

Abusing dh_installdirs .dirs Files

TODO

Many packages wrongly use dh_installdirs and .dirs files to create directories. 99% of those cases are not necessary, since dh_install and .install files will automatically take care of creating directories. You only need to use dh_installdirs if your package needs to ship empty nonstandard directories, e. g. /etc/mypackage/plugins.d/.

Creació d'un paquet Debian. Servidor d'echos (echod)

NOTA: TODO Cal mirar http://www.debian.org/doc/maint-guide/ch-dreq.en.html per veure com customitzar el fitxer rules...
IMPORTANT: Recordeu que tots els fitxers tipus Makefile esperen un tabulador a l'inici de línia de cada comanda

En aquest apartat veurem els passos a seguir per convertir en un paquet Debian el Servidor d'ecos de l'article Programació de dimonis Linux. Podeu obtenir els fitxers a:

$ svn checkout https://svn.projectes.lafarga.cat/svn/iceupc/plinux/sessio10/
  • Usuari: anonymous
  • Contrasenya: anonymous

Trobareu una carpeta echoDimoni. El primer pas és copiar aquest carpeta a una de nova que segueixi els convenis de Debian:

$ cd sessio10
$ cp -r echoDimoni echod-0.1

Ara cal obtenir les eines necessàries per crear el paquet Debian:

$ sudo apt-get install dh-make fakeroot build-essential devscripts debhelper
  • dh-make: Serà la utilitat que ens crearà la carpeta debian a partir de la qual podrem crear el paquet debian.
  • fakeroot: Per crear el paquet necessitem permisos de superusuari. Aquesta comanda és útil per aquells desenvolupadors que han de crear paquets en sistemes on no tenen permisos de superusuari
  • build-essential: Build essential és un paquet "tonto" (dummy package) que instal·la totes les eines necessàries per a construir aplicacions a partir del codi font:
    • libc6-dev: llibreries de C per a desenvolupadors.
    • gcc: el compilador GNU.
    • g++: el compilador GNU de C++.
    • make: la eina make.
    • dpkg-dev: ens proporciona eines com dpkg-buildpackage que ens ajudaran en la construcció del paquet.
  • devscripts: devscripts ens proporciona guions de shell útils per als desenvolupadors de paquets Debian com per exemple debchange.
  • debhelper: Ens proporciona totes les comandes dh_xxx que ens ajudaran a construir el paquet Debian.

Per crear un paquet Debian, cal crear una carpeta debian dins del nostre codi. Aquesta carpeta una sèrie d'informació necessària per crear un paquet debian a partir del codi font. La forma més senzilla de crear aquesta carpeta és utilitzar una eina com dh_make del paquet deb-helper:

NOTA: Poseu el vostre propi correu en comptes de creador.del.paquet@exemple.com.

$ cd echod-0.1
$ export DEBFULLNAME="Nom complet del mantenidor del paquet"
$ dh_make -e creador.del.paquet@exemple.com --createorig
NOTA: Podeu executar dh_make amb l'opció -c per crear ja els fitxers de copyright: dh_make -c gpl3 --createorig. Si ho feu així aleshores no cal que feu l'exemple de copia la llicència que hi ha més endavant

Us preguntaran pel tipus de paquet. En aquest document només tractarem la opció single binary (s), escolliu doncs s:

Type of package: single binary, multiple binary, library, kernel module or cdbs?
 [s/m/l/k/b] s

I es mostraran les dades de control inicials del nostre paquet (més endavant les veurem amb més detall i les adequarem a les nostres necessitats):

Maintainer name : Sergi Tur Badenas
Email-Address   : sergi.tur@upc.edu 
Date            : Fri,  8 Jun 2007 13:15:56 +0200
Package Name    : echod
Version         : 0.1
License         : blank
Type of Package : Single
Hit <enter> to confirm:  

Pressionem enter i ja tenim creada la carpeta Debian.

La opció --createorig ens crearà una carpeta anomenada echod-0.1.orig:

$ ls -la ..
total 32
............. 
drwxr-xr-x 5 sergi sergi 4096 2007-06-08 13:18 echod-0.1
drwxr-xr-x 4 sergi sergi 4096 2007-06-08 13:12 echod-0.1.orig
drwxr-xr-x 4 sergi sergi 4096 2007-06-08 12:59 echoDimoni
......

Aquesta carpeta serà utilitzada més endavant per crear els fitxers fonts Debian.

Un cop tenim la carpeta Debian, ja estem en condicions de crear un paquet Debian mitjançant la comanda dpkg-buildpackage. Per crear el paquet cal "simular" ser superusuari o encara millor, utilitzar la comanda fakeroot:

$ fakeroot
# dpkg-buildpackage
.............
.............
 dpkg-genchanges
dpkg-genchanges: including full source code in upload
 signfile echod_0.1-1_i386.changes

dpkg-buildpackage: full upload (original source is included)
IMPORTANT: Sembla ser que en versions modernes de dpkg-buildpackage si utilitzeu directament l'ordre dpkg-buildpackage sense fakeroot ja us funcionarà correctament - fa el fakeroot quan cal -

Si us dona l'avís:

dpkg-deb: s'està construint el paquet «echod» en «../echod_0.1-1_i386.deb».
 signfile echod_0.1-1.dsc
gpg: skipped "Sergi Tur <sergi.tur@upc.edu>": la clau secreta no està disponible
gpg: [stdin]: clearsign failed: la clau secreta no està disponible

Aleshores és que cal tenir una clau secreta GPG per al nostre usuari:

$ gpg --gen-key 

Consulteu també GPG.

Un cop creat el paquet és MOLT IMPORTANT per evitar errors i altres complicacions, sortir de fakeroot amb la comanda exit:

# exit
$

Si executem la comanda:

$ ls -l ..
..............................
drwxr-xr-x 5 sergi sergi  4096 2007-06-08 13:22 echod-0.1
-rw-r--r-- 1 sergi sergi  7474 2007-06-08 13:22 echod_0.1-1.diff.gz
-rw-r--r-- 1 sergi sergi   546 2007-06-08 13:23 echod_0.1-1.dsc
-rw-r--r-- 1 sergi sergi   980 2007-06-08 13:23 echod_0.1-1_i386.changes
-rw-r--r-- 1 sergi sergi  6550 2007-06-08 13:23 echod_0.1-1_i386.deb
-rw-r--r-- 1 sergi sergi 18471 2007-06-08 13:22 echod_0.1.orig.tar.gz
drwxr-xr-x 4 sergi sergi  4096 2007-06-08 12:59 echoDimoni
..................... 

S'han creat tant el paquet debian binari, com els paquets debian font el fitxer de canvis (.changes).

Però no tot és tant simple, realment si ara obriu el paquet debian amb la comanda:

$ nautilus ..

I obriu el paquet amb l'aplicació "Gestor d'arxius":

ObreAmbGestorArxius.png

a KDE teniu una aplicació anomenada ARK:

ObreAmbArk.png

Des de la línia de comandes, la comanda equivalent és:

$ file-roller ../echod_0.1-1_i386.deb

Si navegueu pels continguts del paquet veureu que hi ha molta informació incompleta (descripció del fitxer, fitxer README, etc...) i que encara queden alguns detalls per millorar. Això es degut a que dh_make no pot fer tota la feina del programador, però si facilita-la proporcionant-nos una sèrie d'eines i plantilles que precisament es troben a la carpeta debian.

De fet, si utilitzem alguna de les eines de comprovació de paquets com per exemple lintian:

$ lintian ../echod_0.1-1_i386.debW: echod: binary-without-manpage echod
E: echod: helper-templates-in-copyright
E: echod: description-is-dh_make-template
W: echod: wrong-bug-number-in-closes l3:#nnnn
E: echod: section-is-dh_make-template

Veurem que el paquet té errors i que encara no compleix completament amb les polítiques de Debian.

Cal dir també, que per tal de poder utilitzar dpkg-buildpackage el Makefile del codi font original ha de tenir com a mínim les normes clean i install. Veiem els fitxers debian/rules i Makefile per tal de conèixer millor la relació entre tots dos. Executeu les comandes:

$ gedit debian/rules &
$ gedit Makefile &

Fitxer debian/rules:

IMPORTANT: En la versió 7 de debhelper (per exemple a Ubuntu 10.04 ja tenim aquests canvis...) el fitxer de rules ha estat molt simplificat i no hi trobareu tantes línies
clean:
	dh_testdir
	dh_testroot
	rm -f build-stamp configure-stamp

	# Add here commands to clean up after the build process.
	-$(MAKE) clean 

	dh_clean 

................ 

install: build
	dh_testdir
	dh_testroot
	dh_clean -k  
	dh_installdirs

	# Add here commands to install the package into debian/echod.
	$(MAKE) DESTDIR=$(CURDIR)/debian/echod install

L'altre opció (a partir de la versió 7):

#!/usr/bin/make -f
%:
	dh $@

Fitxer Makefile del echod:

OWNER=root
GROUP=root
PROGRAM=echod
INSTALL=/usr/bin/install
BINDIR=$(DESTDIR)/usr/sbin
INITDIR=$(DESTDIR)/etc/init.d
ETCDIR=$(DESTDIR)/etc/$(PROGRAM)

all: echod

echod: echod.c
	gcc -o echod echod.c

clean: 
	rm -f echod

install: all install_portfile install_initd
	mkdir -p $(BINDIR)
	$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 755 $(PROGRAM) $(BINDIR)

install_initd: all
	mkdir -p $(INITDIR)
	$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 755 etc/init.d/$(PROGRAM) $(INITDIR)

install_portfile: all
	mkdir -p $(ETCDIR)
	$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 644 etc/$(PROGRAM)/port $(ETCDIR)

uninstall:
	rm -f $(INITDIR)/echod
	rm -f $(BINDIR)/echod

Fixeu-vos que el truc d'utilitzar la variable $(DESTDIR) ens permet instal·lar l'aplicació allà on vulguem. El fitxer debian/rules no és res més que un script Makefile (per això la primera línia #!/usr/bin/make -f).

La comanda dpkg-buildpackage executa les normes de Debian necessàries per tal de crear el paquet. Algunes d'aquestes normes contenen crides a normes del fitxer Makefile original, com pot ser el cas de les normes install i clean:

$(MAKE) clean 
$(MAKE) DESTDIR=$(CURDIR)/debian/echod install

Fixeu-vos que tots els fitxers que formaran part del paquet s'instal·lan abans temporalment a la carpeta debian/nom_paquet (en el nostre cas: debian/echod). Tot comença a lligar!

Podeu trobar més informació sobre el fitxer debian/rules a la Debian Policy.

La resta del fitxer debian/rules són crides a guions de shell de debhelper. Durant els següents apartats veurem alguns exemples d'ús d'aquests guions:

Ara anem a modificar les plantilles que ens proporciona dh_make per tal de configurar el nostre paquet i acabar de crear un "perfecte" Paquet Debian. Seguirem els següents passos:

  • Modificar el fitxer debian/control per introduir la secció del paquet i la descripció (si el paquet tingues alguna dependència també l'hauríem d'especificar en aquest fitxer)

Fitxer original:

Source: echod
Section: unknown
Priority: extra
Maintainer: Sergi Tur Badenas <sergi.tur@upc.edu>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.7.2

Package: echod
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description>
<insert long description, indented with spaces>   

Fitxer modificat:

Source: echod
Section: web
Priority: extra
Maintainer: Sergi Tur Badenas <sergi.tur@upc.edu>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.7.2  

Package: echod
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Servidor d'ecos del curs de programació en Linux
 Aquest servidor és un dimoni que esta a l'espera de rebre missatges d'un client
 Els missatges rebuts pel client són retornats sense cap canvi al client 
IMPORTANT: Compte al fer un Cut&Paste de la wiki, pot ser que us afegeixi un salt de línia extra que caldrà eliminar.
  • Podem/hauríem de modificar el fitxer de registre de canvis (debian/changelog) amb la comanda debchange. Si executem:
$ debchange Aquesta és la versió inicial del nostre paquet

i després executem:

$ debchange

Veiem com s'ha modificat el fitxer de canvis:

echod (0.1-1) unstable; urgency=low

 * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
 * Aquesta és la versió inicial del nostre paquet
 *

-- Sergi Tur Badenas <sergi@localhost.localdomain>  Sun, 10 Jun 2007 11:27:06 +0200

Veurem com hem afegit un comentari al registre de canvis. Consulteu la secció debchange per obtenir més detalls sobre debchange.

  • El següent pas és modificar el fitxer debian/copyright per tal d'especificar la nostra licència. La comanda dh_make ens ha creat la següent plantilla:
$ cat debian/copyright
This package was debianized by Sergi Tur Badenas <sergi.tur@upc.edu> on
Tue,  5 Jun 2007 13:01:02 +0200.

It was downloaded from <fill in http/ftp site>  

Upstream Author: <put author(s) name and email here> 

Copyright: <put the year(s) of the copyright, and the names of the
            copyright holder(s) here>

License:

<Put the license of the package here>
 
The Debian packaging is (C) 2007, Sergi Tur Badenas <sergi.tur@upc.edu> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
  
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.

Podeu trobar fitxers exemple de llicències a la vostra pròpia màquina executant la comanda:

$ sudo updatedb
$ locate copyright

Per exemple la llicència d'emacs la trobareu a:

$ cat $(dpkg -L emacs | grep copyright)

o apache2:

$ cat $(dpkg -L apache2 | grep copyright)

Podeu copiar la llicència lliure que us sembli més adecuada al vostra fitxer de copyright.

*El següent pas és modificar el fitxer debian/dirs per tal què només inclogui les carpetes que realment utilitzarem (al tractar-se d'un dimoni només necessitem la carpeta /usr/sbin)

$ gedit debian/dirs
usr/sbin

Lo anterior (tatxat) no és del tot cert. Llegiu:

5.5 dirs file This file specifies the directories which we need but the normal installation procedure ("make install DESTDIR=..." invoked by "dh_auto_install") somehow doesn't create. This generally means there is a problem with the Makefile. Files listed in the install file doesn't need the directories created first. See install file, Section 5.11. It is best to first try to run the installation first and only use this if you run into trouble. There is no preceding slash on the directory names. Extret de http://www.debian.org/doc/maint-guide/ch-dother.en.html
NOTA: Es a dir el fitxer dirs només cal si el nostre makefile és incorrecte i no crea les carpetes necessàries per a la instal·lació. Fixeu-vos en els mkdir -p que trobareu al fitxer Makefile just davant de les ordres install
  • El següent pas és preparar els fitxers debian/README.Debian i debian/TODO.Debian:
$ cat debian/README.Debian 
echod for Debian
---------------------

<possible notes regarding this package - if none, delete this file> 

-- Sergi Tur Badenas <sergi.tur@upc.edu>  Tue,  5 Jun 2007 13:01:02 +0200

Al fitxer README podem posar les notes que creiem convenients sobre l'aplicació. Un altre fitxer típic és el fitxer TODO (things to do), on com diu el seu nom, es mostren les tasques que hi ha pendents per fer. Podem crear un fitxer anomenat debian/TODO.Debian.

Tots dos fitxers acabaran a la carpeta de documentació, que seguint l' estàndard FHS ha de ser la carpeta /usr/share/doc/nompaquet.

El fitxer ja s'instal·la a la carpeta adecuada durant la crida a la norma install, pero a més deb_helper ens proporciona la comanda dh_installinit.

Només ens cal descomentar la línia adecuada al fitxer debian/rules i com el fitxer init ja s'instal·la posar l'opció --onlyscripts:

.........
#	dh_installemacsen
#	dh_installpam
#	dh_installmime
#	dh_python 
	dh_installinit --onlyscripts
#	dh_installcron
#	dh_installinfo
NOTA: Amb debhelper 7 hi ha un fitxer rules molt simplificat! No cal descomentar res!, l'ordre dh_installinit ja s'executa, però no fa res si no hi ha un fitxer debian/nompaquet.init

En aquest punt és on hem d'introduir el nostre primer hack (canvi) del fitxer debian/rules.

La comanda dh_install no farà res si no troba un fitxer anomenat:

debian/nompaquet.init 
NOTA: Consulteu a Exemple obsolet de modificació fitxers rules, com es feia abans quan el fitxer rules no estava tan simplificat

Hi ha dos opcions al instal·lar el fitxer init:

  • El codi original (upstream) us proporciona un fitxer init
  • El fitxer init el feu vosaltres com a part de les millores que incorpora el paquet

En el segon cas haureu de crear un fitxer init amb el nom

debian/NOM_DEL_PAQUET.init
NOTA: Teniu una plantilla que té una plantilla (esquelet) típic de fitxer init (init.ex)

El servidor d'ecos que estem fent en aquest exemple és del tipus primer cas, ja que el codi font ja proporciona i instal·la amb una tasca específica del Makefile (install_initd) un fitxer init. En aquest cas l'únic que us interessa és que s'executi el servidor després d'instal·lar i també que s'arrenqui el servei automàticament al arrancar l'ordinador. En aquest cas el que hem de fer és sobreescriure la tasca dh_installinit. Afegiu al fitxer debian/rules:

override_dh_installinit:
	dh_installinit --onlyscripts
NOTA: No cal sobrescriure la norma si ja teniu un fitxer debian/rules complet i heu descomentat dh_installinit i heu afegir l'opció --onlyscripts
NOTA: Extret de http://www.debian.org/doc/maint-guide/ch-dother.en.html secció 5.10

És un bon punt per fer notar com tot el fitxer debian/rules està ple de crides a les ordres del paquet deb-helper (comandes dh_*). Cadascuna d'aquestes comandes té el seu corresponent manual on podem obtenir informació detallada del que fan.

La comanda dh_installinit crearà els fitxers:

  • echod.postinst.debhelper
  • echod.postrm.debhelper
  • echod.prerm.debhelper

Aquest fitxers són els que conjuntament amb els fitxers (en el cas que existeixin):

Conformaran els Scripts de manteniment finals postinst, postrm i prerm que trobarem al fitxer control.tar.gz del paquet debian final.

Si veiem el codi d'un dells echod.postinst.debhelper:

 # Automatically added by dh_installinit
if [ -x "/etc/init.d/echod" ]; then
	 update-rc.d echod defaults >/dev/null
	 if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
		 invoke-rc.d echod start || exit $?
	else
		/etc/init.d/echod start || exit $?
	fi
fi

# End automatically added section

Veurem que l'script postinst s'encarregarà de configurar el nostre sistema per tal d'iniciar el dimoni automàticament a l'iniciar el sistema. Simplement Genial! La resta d'scripts fan feines similars (com per exemple treure de l'inici el dimoni si el desinstal·lem).

NOTA: Cal fer notar que els scripts echod.*.debhelper no reescrieun els nostre fitxers postinst, postrm, etc sinó que deb_helper s'encarrega d'afegir aquest codi (operació merge) al nostre fitxer.

  • Ara és el torn de crear els manuals del programa. dh_make ens crea diferents plantilles per si encara no tenim els nostre propis manuals.

Les plantilles són:

  • manpage.1.ex
  • manpage.sgml.ex
  • manpage.xml.ex

Són els tres formats suportats pels fitxers man. Com podeu veure les plantilles sempre acaben amb la extensió .ex.

El guió de shell de debhelper que instal·la els manuals és dh_installman i està activat per defecte al fitxer debian/rules. Els únics passos que hem de seguir són editar alguna de les plantilles, posar un nom adequat al fitxer (típicament 'nomcomanda.seccio) i crear un fitxer debian/manpages amb la llista de fitxers manual. Les passes a seguir:

Copiem la plantilla:

$ cp debian/manpage.1.ex debian/echod.1

I editem el manual per afegir la documentació al nostre gust:

$ gedit debian/echod.1 &

I editem el manual. Un cop editat executem:

$ gedit debian/manpages &

Afegir la línia:

debian/echod.1
NOTA: Un mateix paquet pot tindre diversos manuals. Cal indicar-los tots al fitxer manpages

Si no toquem la plantilla el resultat final serà:

$ man echod

ECHOD(SECTION)                                                                                                                             ECHOD(SECTION)

NAME
       echod - program to do something

SYNOPSIS
       echod [options] files...
       bar [options] files... 

DESCRIPTION
       This manual page documents briefly the echod and bar commands.

       echod is a program that...

OPTIONS
       These  programs  follow  the  usual  GNU  command line syntax, with long options starting with two dashes (‘-’).  A summary of options is included
       below.  For a complete description, see the Info files.  

       -h, --help
              Show summary of options.

       -v, --version
              Show version of program.

SEE ALSO
       bar(1), baz(1).
       The programs are documented fully by The Rise and Fall of a Fooish Bar, available via the Info system.

AUTHOR
       echod was written by <upstream author>.

       This manual page was written by Sergi Tur Badenas <sergi.tur@upc.edu>, for the Debian project (but may be used by others).
                                                                     juny  8, 2007                                                        ECHOD(SECTION)
IMPORTANT: podeu utilitzar l'ordre groff per veure com queden els fitxer man sense necessitat d'instal·lar-los
  • Finalment i per il·lustrar l'ús de Debconf anem a crear els fitxers necessaris per demanar a l'usuari que instal·la el nostre dimoni, quin port vol utilitzar i guardarem aquest port al fitxer /etc/echod/port.

El primer que hem de fer es crear el fitxer debian/templates. Aquest fitxer conté les plantilles d'interfície amb l'usuari.

$ gedit debian/templates &

Un plantilla sencilla pot ser la següent:

Template: echod/port
Type: string
Default: 8001
Description: Port Number:
 Please enter the port number for echod.
Description-es.UTF-8: 
 por favor introducir el puerto del servidor echod
Description-ca.UTF-8: 
 Per favor introduiu el port del servidor echod

Template: echod/notconfigured
Type: note
Description: Warning - echod is not configured
 Please note that you have not completed the echod configuration.
Description-es.UTF-8: Aviso - echod no se ha configurado correctamente
 Hay que tener en cuenta que si no se escoge un número de puerto echod no se configurarà correctamente.
Description-ca.UTF-8: Avis - echod no s'ha configurat correctament
 Tingueu en compte que si no escolliu un número de port echod no es configurarà correctament.
NOTA: Compte amb possibles salts de línia que puguin aparèixer al copiar i enganxar

Aquesta plantilla s'encarrega de preguntar als usuaris el número de port. Si esteu interessats en fer plantilles més complexes haurien de consultar l'apartat Templates de l'especificació de Debconf i consultar el manual debconf-devel.

El segon pas es crear el fitxer debian/config:

$ gedit debian/config

# Source debconf library.
. /usr/share/debconf/confmodule  

db_version 2.0
#Establim que durant la configuració es pugui anar enrere amb botó cancelar
db_capb backup 

#Establim els nostres templates a no vistos per tal que debconf sempre els mostri
db_fset echod/port seen false
db_fset echod/notconfigured seen false

STATE=1
while [ "$STATE"  != 0 -a "$STATE" != 2 ]
  do
  case "$STATE" in
      1)
        # Preparem el template echod/port 
	db_input critical echod/port || true
        #El mostrem
 	if db_go; then
		#Controlem si el valor del port és buit
		db_get echod/port || true
		      if [ ! -z "$RET" ]; then
			  STATE=2
		      fi
		  else
		      STATE=0
		  fi
		  ;;
  esac
done

#Si el port és buit mostrem un missatge d'error: template echod/notconfigured
if [ "$STATE" = 0 ]; then
    db_input critical echod/notconfigured || true
    db_go
    exit 1
fi

El fitxer config només s'encarrega del flux de la interfície amb l'usuari. Per aquest menester, utilitzem les funcions de shell proporcionades pel fitxer /usr/share/debconf/confmodule per comunicar-nos amb debconf mitjançant les comandes del protocol debconf. Si us fixeu, l'script nomes s'encarrega de cridar a la plantilla echod/port:

DebconfDialog2.png

i en cas de que cancel·lem mostra un missatge d'avis echod/notconfigured:

DebconfDialog3.png

El manual de confmodule (man confmodule) us dona informació sobra la llibreria de debconf per a Shell (/usr/share/debconf/confmodule).

Ara be la part més complicada: la lògica de la configuració. En el nostre cas modificarem el script de manteniment postint. dh-make ens ha creat una plantilla per aquest fitxer (debian/postinst.ex) i l'aprofitarem:

La plantilla té el següent contingut:

 #!/bin/sh
 # postinst script for bashdebianesqueleton
 #
 # see: dh_installdeb(1)
 
 set -e
 
 # summary of how this script can be called:
 #        * <postinst> `configure' <most-recently-configured-version>
 #        * <old-postinst> `abort-upgrade' <new version>
 #        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
 #          <new-version>
 #        * <postinst> `abort-remove'
 #        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
 #          <failed-install-package> <version> `removing'
 #          <conflicting-package> <version>
 # for details, see http://www.debian.org/doc/debian-policy/ or
 # the debian-policy package
 
 
 case "$1" in
     configure)
     ;;
 
     abort-upgrade|abort-remove|abort-deconfigure)
     ;;
 
     *)
         echo "postinst called with unknown argument \`$1'" >&2
         exit 1
     ;;
 esac
 
 # dh_installdeb will replace this with shell code automatically
 # generated by other debhelper scripts.
 
 #DEBHELPER#
 
 exit 0

Per tal d'utilitzar-la li canviem el nom i la editem:

$ mv debian/postinst.ex debian/postinst
$ geany debian/postinst & 

Un cop hem copiat la plantilla li afegirem les funcions get_config() i handle_config() just abans del case:

 
. /usr/share/debconf/confmodule  
get_config() {
    db_get echod/port
    port="$RET"
}
 
handle_config() {

    cfile=/etc/echod/port
    tempcfile=`tempfile`
    cat > $tempcfile <<EOF
${port}
EOF
    ucf --debconf-ok $tempcfile $cfile
    chmod 644 $cfile
}
NOTA: Todo: surt un warning que diu de posar el paràmetre --debconf-ok a ucf... TODO, no està clar que sol·lucioni el problema

I omplirem el case configure amb el següent codi:

db_version 2.0
 
# Read debconf 
get_config
handle_config
db_stop

El fitxer ha de quedar igual que aquest:

#!/bin/sh
# postinst script for bashdebianesqueleton
#
# see: dh_installdeb(1)

set -e

# summary of how this script can be called:
#        * <postinst> `configure' <most-recently-configured-version>
#        * <old-postinst> `abort-upgrade' <new version>
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
#          <new-version>
#        * <postinst> `abort-remove'
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
#          <failed-install-package> <version> `removing'
#          <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package

. /usr/share/debconf/confmodule  

get_config() {
    db_get echod/port
    port="$RET"
}
 
handle_config() {

    cfile=/etc/echod/port
    tempcfile=`tempfile`
    cat > $tempcfile <<EOF
${port}
EOF
    ucf --debconf-ok $tempcfile $cfile
    chmod 644 $cfile
}

case "$1" in
    configure)
    
    db_version 2.0
	
	# Read debconf 
	get_config
	handle_config
	db_stop
    
    ;;

    abort-upgrade|abort-remove|abort-deconfigure)
    ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.

#DEBHELPER#

exit 0


Resumint, el codi llegeix el port que em introduït, i el guarda al fitxer /etc/echod/port.

L'últim pas que ens queda és descomentar la línia dh_installdebconf del fitxer debian/rules:

# Build architecture-dependent files here.
binary-arch: build install
       ..... 
	dh_installdocs
	dh_installexamples
#	dh_install
#	dh_installmenu 
	dh_installdebconf
#	dh_installlogrotate
#	dh_installemacsen

Ara ja està tot preparat i podem crear el nostre paquet Debian:

$ fakeroot
# dpkg-buildpackage
# exit

No oblideu l'exit si no voleu pensar-vos que esteu fent coses com a root però en veritat no (fake root ;-))

Per instal·lar-lo executem:

$ sudo dpkg -i ../echod_0.1-1_i386.deb

Si volem reconfigurar:

$ sudo dpkg-reconfigure echod

Si fem algun canvi i volem tornar a crear el paquet primer l'haurem de desinstal·lar amb:

$ sudo apt-get remove --yes --purge echod

Ara llegiu Com provar el sistema client-servidor d'ecos per comprovar que tot funciona correctament

Modificació d'un paquet Ubuntu

Els passos a seguir són similars al cas anterior, però en aquest cas el codi font l'obtenim dels repositoris d'Ubuntu. El següent pot ser un exemple de com modificar un paquet Debian/Ubuntu dels repositoris. L'exemple el realitzem amb el paquet:

$ cd
$ mkdir hello-debhelper
$ cd hello-debhelper
$ apt-get source hello-debhelper
S'està llegint la llista de paquets... Fet 
S'està construint l'arbre de dependències       
S'està llegint la informació de l'estat... Fet
Es necessita baixar 506kB d'arxius font.
Bai:1 http://es.archive.ubuntu.com/ubuntu/ lucid/main hello-debhelper 2.4-3 (dsc) [1286B]
Bai:2 http://es.archive.ubuntu.com/ubuntu/ lucid/main hello-debhelper 2.4-3 (tar) [500kB]
Bai:3 http://es.archive.ubuntu.com/ubuntu/ lucid/main hello-debhelper 2.4-3 (diff) [5308B]
506kB baixats en 5s (88,3kB/s)         
gpgv: Signature made dg 30 ago 2009 13:14:00 CEST using RSA key ID 9F1B8B32
gpgv: No s'ha pogut comprovar la signatura: no s'ha trobat la clau pública
dpkg-source: warning: failed to verify signature on ./hello-debhelper_2.4-3.dsc
dpkg-source: info: extracting hello-debhelper in hello-debhelper-2.4
dpkg-source: info: s'està desempaquetant hello-debhelper_2.4.orig.tar.gz
dpkg-source: info: s'està aplicant hello-debhelper_2.4-3.diff.gz
dpkg-source: info: upstream files that have been modified: 
hello-debhelper-2.4/doc/Makefile.in

Ara tindreu els següents fitxers:

$ ls
hello-debhelper-2.4  hello-debhelper_2.4-3.diff.gz  hello-debhelper_2.4-3.dsc  hello-debhelper_2.4.orig.tar.gz

Com sabeu:

hello-debhelper_2.4.orig.tar.gz: és el codi font de l'aplicació original (p.ex. no inclou la carpeta Debian ni cap informació especifica de 
com construir el paquet)
hello-debhelper_2.4-3.diff.gz: contés les diferències que permeten aconseguir el codi font del paquet a partir del codi font de l'aplicació 
original (conté entre d'altres la carpeta Debian)
hello-debhelper_2.4-3.dsc: Conté informació bàsica del paquet font i també els hashes dels fitxers descarregats. Permet comprovar que els fitxers s'ha descarregat completament. A més el fitxer està firmat pel desenvolupador fet que permet comprovar l'autenticitat.

Un exemple:

$ cat hello-debhelper_2.4-3.dsc 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256  

Format: 1.0
Source: hello-debhelper
Binary: hello-debhelper
Architecture: any
Version: 2.4-3
Maintainer: Santiago Vila <sanvila@debian.org>
Standards-Version: 3.8.3
Build-Depends: debhelper (>= 7)
Checksums-Sha1: 
 fcbf0264928900adf03a7797474375e1a6fa3836 499638 hello-debhelper_2.4.orig.tar.gz
 0ea70eb46b4c90a8dbefbe60bebe4b9f9abb2733 5308 hello-debhelper_2.4-3.diff.gz
Checksums-Sha256: 
 534745c4b7e063f5eb5f984609caf0f7c06d46df03e4d404f20996d28b6df1f7 499638 hello-debhelper_2.4.orig.tar.gz
 7523406f7245ebdba5cb94e0890abfbdb7c7d72a319cc3d6af747b9373ecb54f 5308 hello-debhelper_2.4-3.diff.gz
Files: 
1691faa758ca41c70b6da5501bdf230a 499638 hello-debhelper_2.4.orig.tar.gz
e2b37a62f6243f30258c5a9979911a06 5308 hello-debhelper_2.4-3.diff.gz

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQEcBAEBCAAGBQJKml74AAoJEEHOfwufG4sysC4H/26EikyIgIqRuSXMiykc1hmd
97id9nWl+QzgCpUEg/+uDqEW+Bl6291FstGvzTFCwmB5JjH9ErH1LsyG1OLXbFUb
H89Em7qkl4o2ACTh255oM7FhVweof3UEaLCZMH+HZVVpHXNpEnhrfDvpTBbPGjUi
niiu/7QcGPdWeQITRl6DvfSE7Y6HLGm477uataLPq7RXsRhL2L2/LTk0jKyZtbB4
vdnnYBOzw6U9gAqBNQF5dHr1TmyqFmPqMUtarpNgY2M9LWcna1lZb6vIggbSj2fG
54dFJ9Vgg9Tt6s13w/vD9Vxsa2XYjI7WN7hChf2+wOcWIcj+9z8GnlBEjKbJz4Y=
=B3rj
-----END PGP SIGNATURE-----

A la carpeta:

hello-debhelper-2.4

Es troba el codi font del paquet (creat a partir d'aplicar - vegeu [[diff] - el fitxer diff al codi font original]).

Abans de modificar el codi font del paquet podeu construir el paquet (obtindreu el .deb que podríeu haver descarregat directament dels repositoris! )

$ cd hello-debhelper-2.4
$ dpkg-buildpackage

Ara anem a fer una modificació un pel tonta (si voleu fer modificacions més importants vegeu els exemples de la secció anterior). Modifiqueu el fitxer control:

$ joe debian/control

Canvieu el mantenidor del paquet ;-). Per exemple poseu:

Maintainer: Sergi Tur <correusergitur@upc.edu>     

Anoteu-ho al changelog al mateix temps que creem una nova versió del paquet:

$ dch -i

I torneu a construir el paquet:

$ dpkg-buildpackage

Ara veureu que el paquet és la nova versió.

NOTA: Com l'exemple l'hem fet amb Ubuntu el nom del paquet és: hello-debhelper_2.4-3ubuntu1_i386.deb. Consulteu: Nota sobre paquets Ubuntu per saber més detalls sobre els noms dels paquets a Ubuntu

Crear una nova versió del paquet

Es tant sencill com fer els cavis que vulguem i canviar de versió amb:

$ dch -i 

I notifiquem els canvis:

debchange "Segona Versió"

El changelog es modificarà a quelcom similar a:

echod (0.1-1ubuntu1) feisty; urgency=low

 * Segona Versió 

-- Sergi Tur Badenas <sergi@localhost.localdomain>  Wed, 13 Jun 2007 12:13:34 +0200

echod (0.1-1) unstable; urgency=low

 * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
 * Primera Versio

-- Sergi Tur Badenas <sergi@localhost.localdomain>  Fri,  8 Jun 2007 17:11:24 +0200

I ara ja podem crear el nou paquet amb:

$ fakeroot
# dpkg-buildpackage
# exit

Com que la prova la he fet a una Ubuntu, ara el nou paquet s'anomena echod_0.1-1ubuntu1_i386.deb:

$ ls -la ..
.......
-rw-r--r-- 1 sergi sergi 10883 2007-06-13 12:14 echod_0.1-1ubuntu1.diff.gz
-rw-r--r-- 1 sergi sergi   324 2007-06-13 12:14 echod_0.1-1ubuntu1.dsc
-rw-r--r-- 1 sergi sergi   673 2007-06-13 12:15 echod_0.1-1ubuntu1_i386.changes
-rw-r--r-- 1 sergi sergi  9566 2007-06-13 12:15 echod_0.1-1ubuntu1_i386.deb

Paquet esquelet amb Makefile

Vegeu també:

Crear repositoris Debian

Creació de paquets de 32 bits en entorns de 64 bits

linux32

Crear paquets de 32 bits des de una plataforma de 64 bits es possible utilitzant l'ordre linux32 i les opcions dels paquets debuild i dpkg-buildpackage

$ linux32 debuild -ai386

o

$ linux32 dpkg-buildpackage -ai386

Un exemple amb Makefile:

create_package: createorig
	#create_package
	export DEBFULLNAME="$(DEBIAN_PACKAGE_CREATOR_FULLNAME)";export DEBEMAIL="$(DEBIAN_PACKAGE_CREATOR_EMAIL)";svn-buildpackage --svn-builder="debuild"
	
create_package_32: createorig
	#create_package
	export DEBFULLNAME="$(DEBIAN_PACKAGE_CREATOR_FULLNAME)";export DEBEMAIL="$(DEBIAN_PACKAGE_CREATOR_EMAIL)";/usr/bin/linux32 svn-buildpackage --svn-builder="debuild -ai386"
	
create_package_all: create_package create_package_32

pbuilder

TODO


Utilitzar pbuilder

Building an i386 pbuilder on AMD64

One of the things a pbuilder is useful for is building i386 packages on an AMD64 machine. You can create an i386 chroot with the command:

sudo pbuilder create --debootstrapopts --arch --debootstrapopts i386

If you're interested in using pbuilder to build on other architectures, you should read the next section on multiple pbuilders.


TODO

Q: How do I build i386 debs on AMD64?

A: use the linux32 command to fake uname and limit memory size inside your i386 chroot. Package is linux32.

The following solution is based on the Debian-AMD64 Howto 'Running applications inside the chroot' Section:

Simplest way to build i386 packages out of the box on AMD64 is to use dchroot and a simple wrapper script 
such as the following example for dpkg-buildpackage:
  #!/bin/sh
  rpath=`pwd`
  dchroot -c i386 "cd $rpath && linux32 dpkg-buildpackage -ai386 $@"
Save it under /usr/local/bin/ia32-dpkg-buildpackage, make it executable and change the chroot name
according to your environment.
You will need to have your home directory available under the chroot.
Now you can build i386 packages using ia32-dpkg-buildpackage like dpkg-buildpackage. for example:
  $ ia32-dpkg-buildpackage -rfakeroot
Remember to install the build-depends for the package inside the chroot.

Better approach: use -vserver kernel and create 32-bit vserver; build anything you want instide it.

Paquets de referència

De:

https://wiki.ubuntu.com/PackagingGuide/Complete#Reference_Packages

Són paquets que poden servir com exemple per crear altres paquets similars:

Instal·lació simple de fitxers:

ubuntu-artwork
example-content

PHP

gallery2
roundcube

debconf

wvdial

Subversion

Vegeu també Subversion

svn-buildpackage

Consulteu Creació d'un paquet Debian des de zero. Makefile + svn-buildpackage

Per a instal·lar aquesta eina:

$ sudo apt-get install svn-buildpackage

Un cop instal·lat es pot publicar un paquet ja existent amb svn-inject:

Tenim dos modes de treballar:

  • Mantenint només els fitxers específics del paquet debian. S'activa aquesta opció amb el paràmetre -o de l'ordre svn-inject o activant una propietat especial del repositori subversion anomenada mergeWithStream. Això és sovint el més habitual al empaquetar aplicacions ja existents per a Debian. En aquest mode els fitxers originats es mantenen a la carpeta tarballs.
  • Mantenint al repositori subversion que acabem de crear tant els fitxers específics de l'empaquetatge Debian (bàsicament la carpeta debian) com els fitxers originals (el que es coneix com - aka - upstream). És l'opció per defecte al utilitzar svn-inject. Cal utilitzar aquesta opció quan estem fent un paquet Debian natiu, és a dir, el mantenidor del paquet i el mantenidor de l'aplicació original són la mateixa persona o simplement l'aplicació des de un origen a estat creada per funcionar com a paquet Debian.

Els dos modes s'expliquen en els apartats següents d'aquesta wiki.

Subversion amb els fitxers upstream

Executeu svn-inject sense l'opció -o:

$ svn-inject -c 2 ../ubuntucustom/ubuntucustom_0.1-1.dsc http://www.iesebre.com/subversion/projectes/ubuntucustom_debian

Checking if the default $TMPDIR allows execution...
Default $TMPDIR allows execution.
cp -l /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1.orig.tar.gz /sdb1/sergi/SVN/ubuntucustom_debian1/tarballs/ubuntucustom_0.1.orig.tar.gz
mkdir -p ubuntucustom/branches/upstream
tar -z -x -f /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1.orig.tar.gz
mv ubuntucustom-0.1 current
 svn -q import -m [svn-inject] Installing original source of ubuntucustom (0.1) ubuntucustom/branches/upstream http://www.iesebre.com/subversion /projectes/ubuntucustom_debian/ubuntucustom/branches/upstream
svn -m [svn-inject] Tagging upstream source version of ubuntucustom (0.1) copy http://www.iesebre.com/subversion/projectes/ubuntucustom_debian/ubuntucustom/branches/upstream/current <2 more arguments>
svn -m [svn-inject] Forking ubuntucustom source to Trunk copy http://www.iesebre.com/subversion/projectes/ubuntucustom_debian/ubuntucustom/branches/upstream/current <2 more arguments>
dpkg-source --no-copy --skip-patches -x /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1-1.dsc
gpgv: Signature made dg 20 nov 2011 12:21:20 CET using RSA key ID 11538851
gpgv: No s'ha pogut comprovar la signatura: no s'ha trobat la clau pública
dpkg-source: warning: failed to verify signature on /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1-1.dsc
dpkg-source: info: extracting ubuntucustom in ubuntucustom-0.1
dpkg-source: info: s'està desempaquetant ubuntucustom_0.1.orig.tar.gz
dpkg-source: info: s'està desempaquetant ubuntucustom_0.1-1.debian.tar.gz
fakeroot debian/rules clean || debian/rules clean
dh clean 
   dh_testdir
   dh_auto_clean
   dh_clean
svn co http://www.iesebre.com/subversion/projectes/ubuntucustom_debian/ubuntucustom/trunk /tmp/tmp.iyNWw1Wuge/trunk
A    /tmp/tmp.iyNWw1Wuge/trunk/current
A    /tmp/tmp.iyNWw1Wuge/trunk/current/FOOTER.html
A    /tmp/tmp.iyNWw1Wuge/trunk/current/apache2
A    /tmp/tmp.iyNWw1Wuge/trunk/current/apache2/conf.d
A    /tmp/tmp.iyNWw1Wuge/trunk/current/apache2/conf.d/ubuntucustomreleases.conf
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/sbin
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/sbin/openfpnetusers
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/sbin/openfpnet_postinstall
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/sbin/detectnetworkinterface.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_serveisAmposta_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_example.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_natty.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/ttf-mscorefonts.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/ldap_auth.preseed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_nodomain.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_openfpnet.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_insebre.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/custom2.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid.seed
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/installjava.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/addopenfpnetusers.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/addusers.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/postinstall.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/sbin
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/sbin/installrestrictedextras.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/sbin/openfpnetusers
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/sbin/openfpnet_postinstall
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/doc/ubuntucustom/examples/scripts/sbin/detectnetworkinterface.sh
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/share/ubuntucustom
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/bin
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/bin/createPreseedFiles
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/customcd
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/create_repository
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/installrestrictedextras
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/installLdapClientAuth
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/installjava
A    /tmp/tmp.iyNWw1Wuge/trunk/current/usr/sbin/modifyNsswitch
A    /tmp/tmp.iyNWw1Wuge/trunk/current/HEADER.html
A    /tmp/tmp.iyNWw1Wuge/trunk/current/etc
A    /tmp/tmp.iyNWw1Wuge/trunk/current/etc/default
A    /tmp/tmp.iyNWw1Wuge/trunk/current/etc/default/ubuntucustom
A    /tmp/tmp.iyNWw1Wuge/trunk/current/etc/ubuntucustom
A    /tmp/tmp.iyNWw1Wuge/trunk/current/etc/ubuntucustom/ubuntureleases.txt
A    /tmp/tmp.iyNWw1Wuge/trunk/current/MD5SUMS
A    /tmp/tmp.iyNWw1Wuge/trunk/current/Makefile
A    /tmp/tmp.iyNWw1Wuge/trunk/current/README
A    /tmp/tmp.iyNWw1Wuge/trunk/current/favicon.ico
A    /tmp/tmp.iyNWw1Wuge/trunk/debian
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/control
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/customcd.1
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/source
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/source/format
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/create_repository.1
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/compat
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/changelog
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/patches
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/copyright
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/docs
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/rules
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/manpages
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/README.source
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/createPreseedFiles.1
A    /tmp/tmp.iyNWw1Wuge/trunk/debian/README.Debian
Checked out revision 2371.
cp -a /tmp/tmp.iyNWw1Wuge/unpdir/ubuntucustom-0.1/. /tmp/tmp.iyNWw1Wuge/trunk/.
svn commit -m [svn-inject] Applying Debian modifications (0.1-1) to trunk /tmp/tmp.iyNWw1Wuge/trunk
Adding         trunk/FOOTER.html
Adding         trunk/HEADER.html
Adding         trunk/MD5SUMS
Adding         trunk/Makefile
Adding         trunk/README
Adding         trunk/apache2
Adding         trunk/apache2/conf.d
Adding         trunk/apache2/conf.d/ubuntucustomreleases.conf
Deleting       trunk/current
Adding         trunk/etc
Adding         trunk/etc/default
Adding         trunk/etc/default/ubuntucustom
Adding         trunk/etc/ubuntucustom
Adding         trunk/etc/ubuntucustom/ubuntureleases.txt
Adding  (bin)  trunk/favicon.ico
Adding         trunk/usr
Adding         trunk/usr/bin
Adding         trunk/usr/bin/createPreseedFiles
Adding         trunk/usr/sbin
Adding         trunk/usr/sbin/create_repository
Adding         trunk/usr/sbin/customcd
Adding         trunk/usr/sbin/installLdapClientAuth
Adding         trunk/usr/sbin/installjava
Adding         trunk/usr/sbin/installrestrictedextras
Adding         trunk/usr/sbin/modifyNsswitch
Adding         trunk/usr/share
Adding         trunk/usr/share/doc
Adding         trunk/usr/share/doc/ubuntucustom
Adding         trunk/usr/share/doc/ubuntucustom/examples
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_lucid_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_natty_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom1_oneiric_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_lucid_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_natty_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom2_oneiric_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_example.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_lucid_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_natty.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_natty_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/custom_oneiric_serveisAmposta_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/ldap_auth.preseed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_lucid_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_natty_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_insebre.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_nodomain.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/networkconsole_oneiric_openfpnet.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/preseed/ttf-mscorefonts.seed
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/addopenfpnetusers.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/addusers.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/installjava.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/postinstall.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/sbin
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/sbin/detectnetworkinterface.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/sbin/installrestrictedextras.sh
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/sbin/openfpnet_postinstall
Adding         trunk/usr/share/doc/ubuntucustom/examples/scripts/sbin/openfpnetusers
Adding         trunk/usr/share/doc/ubuntucustom/sbin
Adding         trunk/usr/share/doc/ubuntucustom/sbin/detectnetworkinterface.sh
Adding         trunk/usr/share/doc/ubuntucustom/sbin/openfpnet_postinstall
Adding         trunk/usr/share/doc/ubuntucustom/sbin/openfpnetusers
Adding         trunk/usr/share/ubuntucustom
Transmitting file data ...................................................................................
Committed revision 2372.
Storing copy of your repository tree in /sdb1/sergi/SVN/ubuntucustom_debian1/ubuntucustom.
svn checkout http://www.iesebre.com/subversion/projectes/ubuntucustom_debian/ubuntucustom /sdb1/sergi/SVN/ubuntucustom_debian1/ubuntucustom -q
Done!
Checked out source is in /sdb1/sergi/SVN/ubuntucustom_debian1/ubuntucustom/trunk - have fun!
Removing tempdir /tmp/tmp.iyNWw1Wuge.

On segons el manual:

$ man svn-inject
...
      -c number
          Checkout nothing (0), trunk directory (1) or everything (2) when the work is done.

          Default: 1
...

Subversion sense els fitxers upstream

$ mkdir ubuntucustom_debian && cd ubuntucustom_debian
$ svn-inject -o -c 2 ../ubuntucustom/ubuntucustom_0.1-1.dsc http://www.iesebre.com/subversion/projectes/ubuntucustom_debian
Checking if the default $TMPDIR allows execution...
Default $TMPDIR allows execution.
cp -l /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1.orig.tar.gz /sdb1/sergi/SVN/ubuntucustom/tarballs/ubuntucustom_0.1.orig.tar.gz
ourfile: debian/
ourfile: debian/compat
ourfile: debian/manpages
ourfile: debian/create_repository.1
ourfile: debian/rules
ourfile: debian/copyright
ourfile: debian/README.Debian
ourfile: debian/docs
ourfile: debian/createPreseedFiles.1
ourfile: debian/README.source
ourfile: debian/control
ourfile: debian/customcd.1
ourfile: debian/source/
ourfile: debian/source/format
ourfile: debian/changelog
mkdir -p ubuntucustom/branches/upstream
tar -z -x -f /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1.orig.tar.gz
mv ubuntucustom-0.1 current
 cd /tmp/tmp.enLehRsgNQ/ubuntucustom/branches/upstream/current ; tar  -c debian/create_repository.1 debian/README.source debian/control  debian/createPreseedFiles.1 debian/manpages debian/docs debian/customcd.1 debian/ debian/copyright debian/changelog debian/source/format  debian/README.Debian debian/rules debian/compat debian/source/ 2>/dev/null | tar x  -C /tmp/tmp.xD3Ot4ZBp8
rm -rf /tmp/tmp.enLehRsgNQ/ubuntucustom/branches/upstream/current
mv /tmp/tmp.xD3Ot4ZBp8 /tmp/tmp.enLehRsgNQ/ubuntucustom/branches/upstream/current
svn import /tmp/tmp.Byn27RSn6N http://www.iesebre.com/subversion/projectes -m [svn-inject] Creating ubuntucustom_svn/ubuntucustom/tags/ directory.
Adding         /tmp/tmp.Byn27RSn6N/ubuntucustom_svn
Adding         /tmp/tmp.Byn27RSn6N/ubuntucustom_svn/ubuntucustom
Adding         /tmp/tmp.Byn27RSn6N/ubuntucustom_svn/ubuntucustom/tags

Committed revision 2359.
dpkg-source --no-copy --skip-patches -x /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1-1.dsc
gpgv: Signature made dg 20 nov 2011 11:42:11 CET using RSA key ID 11538851
gpgv: No s'ha pogut comprovar la signatura: no s'ha trobat la clau pública
dpkg-source: warning: failed to verify signature on /sdb1/sergi/SVN/ubuntucustom/ubuntucustom_0.1-1.dsc
dpkg-source: info: extracting ubuntucustom in ubuntucustom-0.1
dpkg-source: info: s'està desempaquetant ubuntucustom_0.1.orig.tar.gz
dpkg-source: info: s'està desempaquetant ubuntucustom_0.1-1.debian.tar.gz
fakeroot debian/rules clean || debian/rules clean
dh clean 
   dh_testdir
   dh_auto_clean
   dh_clean
 cd /tmp/tmp.enLehRsgNQ/unpdir/ubuntucustom-0.1 ; tar  -c debian/create_repository.1 debian/README.source debian/control debian/createPreseedFiles.1  debian/manpages debian/docs debian/customcd.1 debian/ debian/copyright debian/changelog debian/source/format debian/README.Debian debian/rules   debian/compat debian/source/ 2>/dev/null | tar x  -C /tmp/tmp.BGcXolGf9F 
rm -rf /tmp/tmp.enLehRsgNQ/unpdir/ubuntucustom-0.1
mv /tmp/tmp.BGcXolGf9F /tmp/tmp.enLehRsgNQ/unpdir/ubuntucustom-0.1
svn co http://www.iesebre.com/subversion/projectes/ubuntucustom_svn/ubuntucustom/trunk /tmp/tmp.enLehRsgNQ/trunk
svn: URL 'http://www.iesebre.com/subversion/projectes/ubuntucustom_svn/ubuntucustom/trunk' doesn't exist
mkdir -p /tmp/tmp.enLehRsgNQ/trunk
svn -m Creating trunk directory import /tmp/tmp.enLehRsgNQ/trunk http://www.iesebre.com/subversion/projectes/ubuntucustom_svn/ubuntucustom/trunk 

Committed revision 2360.
svn co http://www.iesebre.com/subversion/projectes/ubuntucustom_svn/ubuntucustom/trunk /tmp/tmp.enLehRsgNQ/trunk
Checked out revision 2360.
cp -a /tmp/tmp.enLehRsgNQ/unpdir/ubuntucustom-0.1/. /tmp/tmp.enLehRsgNQ/trunk/.
svn propset mergeWithUpstream 1 /tmp/tmp.enLehRsgNQ/trunk/debian
property 'mergeWithUpstream' set on '/tmp/tmp.enLehRsgNQ/trunk/debian'
svn commit -m [svn-inject] Applying Debian modifications (0.1-1) to trunk /tmp/tmp.enLehRsgNQ/trunk
Adding         tmp/tmp.enLehRsgNQ/trunk/debian
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/README.Debian
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/README.source
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/changelog
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/compat
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/control
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/copyright
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/createPreseedFiles.1
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/create_repository.1
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/customcd.1
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/docs
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/manpages
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/rules
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/source
Adding         tmp/tmp.enLehRsgNQ/trunk/debian/source/format
Transmitting file data .............
Committed revision 2361.
Storing copy of your repository tree in /sdb1/sergi/SVN/ubuntucustom/ubuntucustom.
svn checkout http://www.iesebre.com/subversion/projectes/ubuntucustom_svn/ubuntucustom /sdb1/sergi/SVN/ubuntucustom/ubuntucustom -q
Done!
Checked out source is in /sdb1/sergi/SVN/ubuntucustom/ubuntucustom/trunk - have fun!
Removing tempdir /tmp/tmp.enLehRsgNQ.

En local queden els fitxers:

$ tree
.
|-- tarballs
|   `-- ubuntucustom_0.1.orig.tar.gz
`-- ubuntucustom
    |-- tags
    `-- trunk
        `-- debian
            |-- changelog
            |-- compat
            |-- control
            |-- copyright
            |-- createPreseedFiles.1
            |-- create_repository.1
            |-- customcd.1
            |-- docs
            |-- manpages
            |-- patches
            |-- README.Debian
            |-- README.source
            |-- rules
            `-- source
                `-- format

7 directories, 14 files

I al repositori:

http://www.iesebre.com/subversion/projectes/ubuntucustom_debian/ubuntucustom/

Trobareu les carpetes:

tags/
trunk/

A trunk només hi ha la carpeta debian

Crear el paquet

Teniu diverses opcions però la clau sempre està en substituir dpkg-builpackage per svn-buildpackage:

Cal anar a la carpeta trunk i executar:

$ svn-buildpackage -us -uc -rfakeroot

Si a més voleu executar Lintian:

$ svn-buildpackage -us -uc --svn-lintian -rfakeroot

O també podeu utilitzar debuild

$ svn-buildpackage --svn-builder="debuild -sa"

Els paquets els trobareu a la carpeta build-area.

IMPORTANT: Tots els fitxers han d'estar pujats al repositori de subversion si no no us deixarà crear el paquet:
$ svn-buildpackage --svn-builder="debuild"
...
make[1]: Entering directory `/sdb1/sergi/SVN/ubuntucustom/trunk'
dh clean 
  dh_testdir
  dh_auto_clean
  dh_clean
make[1]: Leaving directory `/sdb1/sergi/SVN/ubuntucustom/trunk'
E: Found unresolved issues: 

M       Makefile

E: Resolve them manually before continuing

A l'exemple falta fer un commit del Makefile:

$ svn ci Makefile

O també podeu utilitzar l'opció:

--svn-ignore

Crear un tag per a una revisió (l'equivalent a dch -i)

Per crear una nova revisió en compte d'executar dch -i. A la carpeta trunk executeu:

$ svn-buildpackage --svn-tag-only
Complete layout information:
	buildArea=/sdb1/sergi/SVN/ubuntucustom/build-area
	origDir=/sdb1/sergi/SVN/ubuntucustom/tarballs
	tagsDir=/sdb1/sergi/SVN/ubuntucustom/tags
	tagsUrl=http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/tags
	trunkDir=/sdb1/sergi/SVN/ubuntucustom/trunk
	trunkUrl=http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/trunk
	upsCurrentDir=/sdb1/sergi/SVN/ubuntucustom/branches/upstream/current
	upsCurrentUrl=http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/branches/upstream/current
	upsTagDir=/sdb1/sergi/SVN/ubuntucustom/branches/upstream
	upsTagUrl=http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/branches/upstream
fakeroot debian/rules clean || die
dh clean 
  dh_testdir
  dh_auto_clean
  dh_clean
Repository lookup, probing 'http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/tags/0.1-1' ...
Tagging ubuntucustom (0.1-1)
svn -m [svn-buildpackage] Tagging ubuntucustom 0.1-1 cp . http://www.iesebre.com/subversion/projectes/ubuntucustom/ubuntucustom/tags/0.1-1

Committed revision 2399.
dch -D UNRELEASED -i NOT RELEASED YET

I: Done! Created the next changelog entry, please commit later or revert.

El fitxer de changelog haurà canviat:

$ svn status
M       debian/changelog

Si el visualitzeu:

$ cat debian/changelog

ubuntucustom (0.1-1ubuntu1) UNRELEASED; urgency=low

 * NOT RELEASED YET

-- Sergi Tur Badenas <sergi.tur@upc.edu>  Sun, 20 Nov 2011 18:01:48 +0100

ubuntucustom (0.1-1) unstable; urgency=low

 * Initial release
 * Resolved all lintian errors and warnings
 * Test

-- Sergi Tur Badenas <sergi.tur@upc.edu>  Sat, 12 Nov 2011 18:29:43 +0100

Modifiqueu-lo per indicar els canvis i pujeu-lo al subversion:

$ svn ci 

Ara ja podeu crear el paquet de la nova versió:

export DEBFULLNAME="Sergi Tur Badenas";export DEBEMAIL="sergi.tur@upc.edu";svn-buildpackage --svn-builder="debuild"

Actualitzar a una nova versió de upstream

TODO

Cal anar a la carpeta trunk i executar:

$ svn-upgrade /tmp/filepp-2.0.tar.gz
cp /tmp/filepp-2.0.tar.gz ../../tarballs/filepp_2.0.orig.tar.gz
cp /tmp/filepp-2.0.tar.gz ../build-area/filepp_2.0.orig.tar.gz

Vegeu també

Enllaços externs

OpenFPnet
IES Nicolau Copèrnic