summaryrefslogtreecommitdiffstats
path: root/Crear_Paquetes_Debian_y_Mirror
blob: 722e6d54fdd0c13d89fd3daea77b1563479f078e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
##########################################################

    Howto crear paquetes .deb y mirror debian

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


A muchos de los participantes del Concurso de Software libre
puede que aún no les interese el tema de empaquetar sus 
aplicaciones sobre algunas distribuciones Linux. Pero una vez
llegue el final del concurso será un tema bastante interesante.

1.- Introducción

El fin de realizar un programa es para que alguien lo use
y una forma de multiplicar por muchos esto, es creando paquetes
para las distribuciones más usuales:

 * Debian
 * Ubuntu
 * Fedora
 * SuSe
 * Mandriva
 * Slackware
 * Gentoo
 .....

Cada distribución tiene su propio sistema de empaquetado y
distribución de paquetes, siendo los más usuales:

 * Paquetes .deb
 * Paquetes .rpm
 * Paquetes .tgz
 * ebuilds de gentoo

En este howto me voy a encargar de explicar como hacer que nuestro
software se pueda empaquetar para distribuciones basadas en debian
ya que hoy cumplen un gran espectro del total y entre las que están:

 * Debian (padre y madre de muchas distribuciones)
 * Ubuntu hijo de Debian y con gran aceptación entre usuarios nuevos
   de escritorio, y equipos nuevos.

  (Las autonómicas)

 * Linex, basado en Debian, distribución autonómica de Castilla la Mancha
 * Guadalinex, basado en Ubuntu, distribución de Anadalucía
 * MaX, basado en Ubuntu, distribución de Madrid.
 * Lliurex, basado en Ubuntu, distribución de Valencia.

 (Otras conocidas)
 
 * Knoppix, distribución live, basada en debian
 * Morphix, más de lo mismo, con un sistema de módulos muy interesante
 * Elive, basada en debian con el escritorio Enlightment.
 ...


El motivo de empaquetar en .deb creo que queda claro. Ahora vamos al método.

2.- Preparar nuestras fuentes para hacer un paquete deb

Seguramente tenemos un directorio donde tenemos código fuente (en cualquier 
lenguaje) y lo compilamos con ayuda de un script o Makefile.

Nuestro código tiene dependencias de compilación es decir, aquellas librerías
o programas que necesitamos tener instaladas para que la compilación funcione
y genere el código binario, por ejemplo si nuestro programa está escrito en C
las dependencias serán el compilador gcc, la librería libc6 y quizás las 
cabeceras del kernel. Si además usamos Makefiles, necesitaremos make y quizás
autoconf, automake, etc... Estas son las dependencias que se llaman 
"Build-Depends", ya veremos luego para que sirven.

Una vez el código está compilado si generamos el paquete y lo instalamos en 
una máquina distinta a donde lo hemos desarrollado quizás tenga dependencias de 
ejecución, es decir, si lo hemos enlazado a libc6, y al toolkit gráfico de 
KDE: qt, necesitaremos al menos que ese equipo disponga de libc6 (que se 
instala siempre y el toolkit de ejecución qt (kdelibs). 
A estas se les llama "Depends".

Hay muchos más casos, por ejemplo, nuestro código no se compila porque hemos 
usado un lenguaje interpretado (python, perl, bash), las dependencias de 
compilación ya no se necesitan pero si las de ejecución.

Cada distribución ha resuelto esta gran papeleta con un gestor de paquetes, en
debian y todas las derivadas tenemos dpkg y por encima apt-get.

3.- Estructura del directorio debian en nuestro código fuente

El primer paso para crear un paquete deb es crear un directorio llamado 
debian en la raiz del código fuente donde se situarán una serie de archivos 
que serán usados para la construcción del paquetes y para su posterior 
clasificación en los repositorios.

La forma más sencilla es copiarnos nuestro código fuente a un directorio 
nuevo con el siguiente nombre:

   mi-proyecto-0.0.1

Muy importante:
 * no usar mayúsculas
 * no usar caracteres especiales en el nombre (se pueden usar guiones, 
   letras y numeros)
 * usar una nomenclatura de versiones lo más estandar posible 
   (con 3 números sirve)
 * separar el nombre del proyecto de la versión con un guión medio.

Instalaremos ciertos paquetes de desarrollador de debian que nos ayudarán en 
el proceso de empaquetar:

 # apt-get install devscripts build-essential dpkg-dev \
   dh-make debhelper fakeroot

Entramos al directorio de las fuentes y generamos el directorio debian 
con ayuda de dh-make:

 $ cd mi-proyecto-0.0.1
 $ dh_make --createorig

  (nos va a preguntar por el tipo de paquete, diremos "s" )

Tipos de paquetes:
  s = single (las fuentes generan un paquete
  m = multimple (las fuentes generan varios paquetes quizás un programa
                 y una librería)
  l = librería (las fuentes generan una librería)
  k = módulo kernel (las fuentes generan un módulo del kernel)
  c = paquete cdbs (nueva forma de crear paquetes que ya veremos)

(
  sería recomendable tener las siguientes variables de entorno declaradas:
  DEBNAME=Nombre Apellidos (nick)
  DEBEMAIL=correo@electronico.com
  DEBFULLNAME=Nombre Apellidos (nick)

  así como tambíen tener una clave GPG con los mismos datos:

  gpg --create
)

Esto creará un tar.gz de las fuentes (nuestro código) y entonces añadirá
el directorio debian con todas las herramientas que luego comentaremos.

Dentro de ese directorio pueden encontrarse:

 * changelog (archivo del control de cambios del empaquetador)
   Este archivo es muy importante a la hora de empaquetar porque
   la versión, rama y prioridad se indican aquí así como el empaquetador.

 * control
   Este archivo describe el paquete del código fuente y los paquetes bianrios
   generados a partir de él. En la descripción de los fuentes es donde indicamos
   las dependencias de compilación "Build-Depends", en los binarios el propio
   constructor del paquete incluirá las dependencias de ejecución por nosotros.

 * rules (archivo de compilación Makefile)
   Este archivo es el que configurará compilará e instalará los binarios
   en un directorio temporal que luego se convertirá en el paquete deb.
   Tiene reglas como config.status, build, install, clean, etc...

 * copyright (información de licencia/licencias del código de ese paquete)

 * README.Debian (información de interés para el usuario debian de ese paquete)

 * docs (archivo donde se lista los archivos de documentación que acompañan al
         programa)

 * install (archivo que indica que archivos estan en el paquete)

 * post|pre int|rm ( scripts que se ejecutan antes|después de la 
                     instalación|desinstalación )

 * manpages (páginas man)
   En debian todos los bianrios que se encuentren en el PATH deben tener 
   página man.

....

Hay muchos más pero con saber estos nos vale de momento.

4.- Compilando....

Si nuestro paquete usa autotools ( ./configure && make && make install )
dh_make lo habrá detectado y seguramente no haya que tocar nada más que el 
archivo changelog (se edita con el comando debchange) y el archivo control
(se edita con cualquier editor) "debchange -i" añadirá una nueva revisión
al changelog, completando por nosotros, la fecha, hora y autor (los datos los
toma de las variables de entorno DEB***** que hemos visto antes).

Si nuestro paquete no usa autotools y compila cosas tendremos que editar el
archivo rules y llamar a lo que se compila desde allí.

Para generar nuestro primer paquete deb ejecutamos lo siguiente:

  $ dpkg-buildpackage -rfakeroot 

IMPORTANTE: la compilación de paquetes hay que hacerla como usuario (como root
podemos cargarnos algo si tenemos un Makefile mal diseñado!!!!)

NOTA: Se puede usar debuild (que es más corto y se recuerda mejor, además que 
ejecuta una serie de herramientas extra)

Este comando llama secuencialmente a lo siguiente:

  - make clean
  - dpkg-source (genera el tar.gz de las fuentes y el diff.gz de debian)
  - configure
  - make
  - make install DESTDIR=$(CURDIR)/debian/mi-proyecto
  - builddeb

Es decir, se limpian las fuentes, se crea un archivo comprimido con nuestro
código fuente y los parches que aplica debian (una de las políticas de debian
es distribuir el código funete original y parchearlo en el momento de la 
compilación)

Después el proceso es el de siempre, configurar, compilar y para instalar se
usa la variable DESTDIR que será / en caso de no indicarse pero que aquí es un
subdirectorio del directorio debian.

Luego se copian la documentación, el changelog, se generan las dependencias de 
ejecución mirando el linkado dinámico de nuestros binarios 
(ldd nuestro_programa) y se mete todo en uno (o varios) archivos deb.



Si tenemos clave GPG nos pedirá firmar dos archivos.

5.- Ejemplo de paquete deb

Tenemos nuestro super programa adios-mundo-0.0.1:

#include <stdio.h>
int main(){
  print "Adios Mundo.\n";
  return(0);
}

y un Makefile:

all:
	gcc adios-mundo.c -o adios-mundo

clean:
	rm -f *~ adios-mundo

install:
	install -m 755 adios-mundo $DESTDIR/usr/bin/adios-mundo

Como no tenemos configure, dh_make no va a llamarlo, una vez generado
el directorio debian editamos el archivo debian/control para indicar
el empaquetador, la sección, y una descripción (corta y larga).

Los archivos terminados en ex o EX (example) se pueden borrar.

ejecutamos dpkg-buildpackage -rfakeroot 

y obtenemos estos archivos:
  adios-mundo_0.0.1-1.diff.gz
  adios-mundo_0.0.1-1.dsc
  adios-mundo_0.0.1-1.build
  adios-mundo_0.0.1.orig.tar.gz
  adios-mundo_0.0.1-1_i386.deb

El archivo dsc contiene la información del paquete fuente y los hash 
(md5, sha1) de los archivos diff.gz y orig.tar.gz)

El archivo build es una copia de lo que vemos es consola cuando se compila
o también llamado log de construcción.

El "-1" extra que aparece añadido a nuestra versión es la versión del paquete
en debian, ya que el empaquetador puede añadir parches o empaquetarlo de
otra manera antes de que nosotros publiquemos la próxima versión 0.0.2 

Por último el paquete deb, se puede instalar con un simple:
 # dpkg -i adios-mundo_0.0.1-1_i386.deb


Este paquete tiene muchos fallos, uno de ellos es que no tiene página
man y otro es que no hemos indicado dependencias de compilación, que a 
groso modo serían: libc6-dev, gcc, make

Para ver la "calidad" de los paquetes deb se usa lintian y linda, si 
instalamos estos paquetes se ejecutarán justo antes de terminar el proceso
de empaquetado y nos dirán que cosas tenemos mal.


6.- Ahora le toca al mirror

Ahora bien, tenemos un paquete y lo queremos redistribuir, la forma más 
sencilla es colgar el paquete en nuestra página web, enlazarlo y que la gente 
lo descargue e instale por medio de "dpkg -i".

Esto no es buena idea ya que para cuando publiquemos una actualización 
nuestros usuarios no podrán instalarla hasta que vuelvan a entrar a la web. 
Otro problema es que dpkg no resuelve dependencias, sino apt, por lo que puede 
quedar el paquete roto hasta que no se ejecute "apt-get -f install".

Quizás sea mejor idea mantener un pequeño repositorio y que los usuarios lo
añadan a su sources.list para que el proceso sea más automático.
  
Hay dos tipos de mirror, los simples y los complejos, vamos a ver los dos:

6.1.- Mirror simple

Es básicamente un directorio (con subdirectorios) que no tiene que cumplir
ningún estándar y en el que se copian los archivos deb o todos los archivos
de compilación (deb, diff.gz, ,tar.gz, dsc, changes) y se ejecuta algo como 
esto:

  $ apt-ftparchive packages . | gzip > Packages.gz
  $ apt-ftparchive sources  . | gzip > Sources.gz

Se copia a un directorio accesible por ftp o http y se añade al sources.list
algo como esto:

   deb http://nuestrositio/directorio/ ./

Ventajas:
  * muy rápido de hacer y mantener
  * admite varias versiones del mismo paquete

Inconvenietes:
  * Dificil de mantener réplicas (mirrors)
  * No se puede firmar con gpg (al menos de forma sencilla)


6.2.- Mirror completo y complejo

Hay varias herramientas para hacer un mirror completo la que yo he usado se 
llama "reprepro" y básicamente el mirror tendrá esta estructura:

  .
  |-- conf
  |-- dists
  `-- pool

En el directorio dists tendremos un directorio por cada versión de la 
distribución por ejemplo (sarge, etch, sid, unstable, dapper, etc...)

En el directorio pool es donde se encuentran los paquetes clasificados 
por sección (main, contrib, non-free, universe, multiverse) y luego por su 
primera letra (o 4 primeras para librerías).

No tenemos que crear directorios a mano ya que reprepro se encargará de todo.

Lo primero es hacer un archivo conf/distributions que tenga bloques como este:

Origin: Tcos-Packages
Label: Tcos-Packages
Suite: unstable
Codename: unstable
Architectures: i386 source
Components: main
Description: Tcos Debian unstable packages mirror
SignWith: Nombre Apellidos (nick) <correo@electronico.com>

Creo que las etiquetas se autoexplican todas, salvo arquitecturas y 
componentes.

Arquitecturas corresponde a las arquitecturas para las que vayamos a compilar
nuestro paquete y si vamos a incluir el código fuente y componentes es la 
sección del repositorio donde se guardará al paquete 
(main, contrib, non-free, universe, multiverse)

SignWith es con lo que se firmará (GPG) nuestro repositorio.

Haremos tantos bloques como este, como secciones y suites queramos tener.

para añadir paquetes al repositorio ejecutamos lo siguiente:

 $ reprepro --ask-passphrase -b . -V -C [COMPONENT]\
  include [SUITE] archivo_0.0.1-1.dsc

Para añadir un archivo deb sólo:

 $ reprepro --ask-passphrase -b . -V -C [COMPONENT]\
  includedeb [SUITE] archivo_0.0.1-1_i386.deb

Cuando vayamos a añadir la versión 0.0.2 reprepo borrará la versión 0.0.1

Si vamos a añadir una revisión de debian 0.0.1-2 reprepro sólo actualiza 
el fichero diff.gz ya que el orig.tar.gz no cambia entre versiones de debian.

Para borrar un paquete del repositorio:

 $ reprepro --ask-passphrase -b . -V -C [COMPONENT] remove [SUITE] archivo

Si el paquete tiene varios deb hay que borrarles también:

 $ reprepro --ask-passphrase -b . -V -C [COMPONENT]\
  remove [SUITE] archivo-dev libarchivo archivo-doc

Por último para poder acceder a este mirror con apt-get añadimos al 
sources.list:

 deb http://servidor/directorio/ SUITE COMPONENTE

Ejemplo:

 deb http://servidor/directorio/ unstable main
 
Podemos añadir otra línea para poder bajarnos el código fuente:

 deb-src http://servidor/directorio/ unstable main 
 
El código fuente se puede bajar así:

 $ mkdir sources
 $ cd sources 
 $ apt-get source mi-proyecto
 
Esto se descarga el archivo dsc, el orig.tar.gz y el diff.gz reconstruyendo
el directorio de las fuentes al que podemos añadir algun parche y volver a 
compilar con:

 $ dpkg-buildpackage -rfakeroot

Si hemos firmado el repositorio cuando nuestros usuarios ejecuten 
"apt-get update" les avisará de que no conoce nuestra clave, para que ellos 
la importen tenemos que generar un archivo con ella:

  $ gpg --armor --export CLAVE > nuestra-clave-pub.key

Y que ellos lo descargen y añadan así:

 # wget http://servidor/nuestra-clave-pub.key -O- | apt-key add

O bien si la hemos publicado en un servidor de claves:

 # gpg --keyserver wwwkeys.eu.pgp.net --recv-keys CLAVE
 # gpg --armor --export CLAVE | apt-key add -
 
 
7.- Enlaces
 Debian:
   http://www.debian.org
   http://www.debian.org/doc/manuals/maint-guide/index.es.html
   http://www.es.debian.org/devel/
   http://www.es.debian.org/devel/join/
   http://www.us.debian.org/devel/wnpp/index.es.html
 
 Reprepro:
   http://mirrorer.alioth.debian.org/reprepro.1.html
 
 AutoTools:
   http://sources.redhat.com/autobook/

 GPG:
   http://www.linuca.org/body.phtml?nIdNoticia=88