Pacchetti e Repository

La distribuzione FUSS comprende un repository di pacchetti aggiuntivi rispetto alla base (Debian), disponibile all’indirizzo https://archive.fuss.bz.it/ ed ospitato su isolda.fuss.bz.it nella directory /iso/repo.

Build dei pacchetti

Nei repository del software sviluppato per FUSS è presente la directory debian contenente i file necessari per la generazione dei pacchetti .deb.

In alcuni progetti, tale directory è presente solo in un branch dedicato, con un nome tipo fuss/<versione>; per questi casi vedere anche la sezione Pacchettizazione gestita con git .

Setup

Per effettuare build locali dei pacchetti è necessario installare alcuni strumenti di sviluppo:

# apt install devscripts dput-ng dh-systemd

Nota

Assicurarsi di aver installato anche i Recommends dei pacchetti (questo è il comportamento di default di apt, a meno che non lo si sia disabilitato manualmente), in particolare nel caso di dput-ng.

Inoltre è necessario impostare le variabili di ambiente DEBEMAIL e DEBFULLNAME, contenenti rispettivamente il nome completo e l’email dello sviluppatore, che verranno usate per aggiornare alcuni metadati.

Per usare dput-ng per effettuare gli upload serve configurarlo creando il file ~/.dput.d/profiles/fuss-<versione>.json contenente:

{
    "method": "sftp",
    "fqdn": "archive.fuss.bz.it",
    "incoming": "/iso/incoming/<versione>",
    "allow_dcut": false,
    "allowed-distribution": {},
    "codenames": null,
    "post_upload_command": "ssh -S none isolda.fuss.bz.it 'sudo /iso/bin/post-upload'",
    "hooks": [
        "allowed-distribution",
        "checksum",
        "suite-mismatch"
    ]
}

dove <versione> è jessie per FUSS server, stretch per FUSS client, e buster e buster-proposed-updates per la prossima versione di FUSS sia server che client.

Assicurarsi inoltre di poter accedere via ssh ad archive.fuss.bz.it senza ulteriori opzioni; ad esempio potrebbe essere necessario aggiungere quanto segue a ~/.ssh/config:

Host archive.fuss.bz.it
    User root

Nota

dput-ng usa paramiko per effettuare le connessioni ssh; questo implica che le opzioni impostate direttamente in ~/.ssh/config vengono lette correttamente, ma non c’è supporto per l’uso di Include per suddividere la configurazione su più file.

Inoltre non verrà salvato il fingerprint dei server, ma verrà chiesto ogni volta di verificarlo.

A marzo 2019i fingerprint di isolda sono:

256 SHA256:aLTgA+Trj5iYo0dl0i8Q82aigs3K/dPwDbazrvG95YY root@isolda (ECDSA)
256 SHA256:7i6j0jXPWRrW6LXDGbR+HWr3AFJi6gGSmdW41uBRJV4 root@isolda (ED25519)
2048 SHA256:OkP1maDf0pSIGCdq1mph8oI8CTADMrFXfe3aty608SA root@isolda (RSA)

256 MD5:b1:a1:ec:cb:a5:39:c8:8d:39:f1:dd:ba:aa:be:38:11 root@isolda (ECDSA)
256 MD5:21:41:8b:19:1b:25:b5:9c:f2:5c:e8:b9:8b:08:07:f8 root@isolda (ED25519)
2048 MD5:bd:88:bd:5f:bc:52:03:0b:88:d9:0c:2b:86:59:dc:92 root@isolda (RSA)

Cowbuilder

Nota

cowbuilder e pbuilder sono degli strumenti per gestire delle chroot all’interno delle quali effettuare build di pacchetti in un ambiente pulito e abbastanza isolato dal sistema base.

Buildare pacchetti all’interno di un sistema isolato è utile per evitare influenze da parte del proprio sistema (con librerie ed altre dipendenze già installate, magari in versioni non standard), ma è anche comodo nel caso si vogliano generare pacchetti per distribuzioni diverse da quelle in uso (ad esempio buildare per jessie o stretch su un sistema buster)

Oltre a quanto indicato sopra, installare cowbuilder, pbuilder e git-buildpackage:

# apt install pbuilder cowbuilder git-buildpackage

ed assicurarsi che l’utente che si vuole usare per lanciare le build faccia parte del gruppo sudo.

Quindi creare le chroot base per le distribuzioni attualmente (giugno 2019) in uso buster, stretch e jessie:

# cowbuilder --create --distribution buster --debootstrap debootstrap \
  --basepath /var/cache/pbuilder/base-fuss-buster.cow
# cowbuilder --create --distribution stretch --debootstrap debootstrap \
  --basepath /var/cache/pbuilder/base-fuss-stretch.cow
# cowbuilder --create --distribution jessie --debootstrap debootstrap \
  --basepath /var/cache/pbuilder/base-fuss-jessie.cow

Suggerimento

cowbuilder può essere usato anche sotto distribuzioni derivate da debian, come ubuntu; in questo caso è necessario però specificare esplicitamente l’uso di un mirror debian aggiungendo ai comandi sopra le opzioni:

--mirror <un mirror debian valido> --components main

Aggiungere i repository di backports e fuss alle chroot base appena create: fare login nella chroot:

# cowbuilder --login --save-after-login \
  --basepath /var/cache/pbuilder/base-fuss-buster.cow

ed effettuare le modifiche a /etc/apt/sources.list e l’aggiunta della chiave (sostituendo <mirror> con un mirror debian opportuno, ad esempio quello già presente in /etc/apt/sources.list:

# echo 'deb <mirror> buster-backports main' >> /etc/apt/sources.list
# echo 'deb http://archive.fuss.bz.it/ buster main contrib' \
  >> /etc/apt/sources.list
# apt install gnupg
# apt-key add - # incollare i contenuti di
                # https://archive.fuss.bz.it/apt.key seguiti da ctrl-d
# apt remove gnupg
# apt autoremove
# apt update
# exit

Nota

nella chroot minimale da stretch in poi non è presente gnupg, che è necessario per l’uso di apt-key add: lo installiamo per l’operazione e rimuoviamo subito dopo per essere certi che l’immagine sia sempre minimale e continuare ad accorgersi di eventuali dipendenze non esplicitate nei pacchetti che generiamo.

Ripetere la stessa cosa per le altre chroot (jessie e stretch).

Nota

dato che jessie-backports non è più supportato, quando si configura la chroot per jessie con cowbuilder --login è necessario configurarlo puntando agli archivi e disabilitare il controllo della data di validità della firma di tutti i repository.:

# echo 'deb http://archive.debian.org/debian jessie-backports main' >> /etc/apt/sources.list
# echo 'Acquire::Check-Valid-Until no;' >> /etc/apt/apt.conf.d/99no-check-valid-until

Purtroppo in jessie non era ancora disponibile la possibilità di disattivare tale controllo per una sola fonte.

Nel caso in cui le chroot siano state create da un po” di tempo è opportuno aggiornarle, coi seguenti comandi:

# cowbuilder --update --basepath /var/cache/pbuilder/base-fuss-buster.cow/
# cowbuilder --update --basepath /var/cache/pbuilder/base-fuss-stretch.cow/
# cowbuilder --update --basepath /var/cache/pbuilder/base-fuss-jessie.cow/

Clone del repository

Clonare il repository del progetto desiderato:

$ git clone https://work.fuss.bz.it/git/<progetto>

Nei vecchi progetti il branch da buildare per l’upload è master, in quelli recenti fuss/master, entrambi da aggiornare nel caso in cui si abbia già un clone locale del repository:

$ git checkout [fuss/]master
$ git pull

Versionamento

Per poter pubblicare il pacchetto, è necessario incrementare il numero di versione nel file debian/changelog.

Il numero di versione da dare dipende dal tipo di pacchetto, come descritto nella sezione Policy di versionamento e nelle guide di sviluppo degli specifici pacchetti, ma nella maggior parte dei casi sarà da incrementare il patch level (es. da 9.0.5-1 a 9.0.6-1).

Nota

Nei pacchetti contenenti programmi in python è generalmente necessario mantenere aggiornato il numero di versione anche in setup.py; come per debsrc sopra questo dovrebbe essere citato nel README dei pacchetti.

Il programma dch, permette di automatizzare l’editing del file debian/changelog che contiene la versione del pacchetto.

  • Quando si iniziano a fare modifiche usare il comando dch -v <nuova_versione> per creare una nuova stanza ed aprire il changelog nell’editor di default.

    Verrà impostato il numero di versione richiesto e la release speciale UNRELEASED che indica che le modifiche sono ancora in lavorazione.

    Si può anche usare dch senza opzioni: in questo modo se l’ultima stanza risulta UNRELEASED il file verrà aperto così com’è, mentre se l’ultima stanza riporta una release come unstable ne viene creata una nuova incrementando il numero di versione.

    Attenzione che in quest’ultimo caso dch potrebbe non essere in grado di indovinare la versione corretta: verificare e nel caso correggere. Inoltre, nel caso in cui non si sia elencati tra i Maintainer e Uploaders in debian/control verrà aggiunta una riga Non Maintainer Upload che per noi non è rilevante e va tolta.

    Nel caso in cui più persone facciano modifiche, dch provvederà a suddividerle in sezioni intestate con il nome della persona che ha effettuato la modifica.

  • Descrivere le modifiche effettuate, possibilmente indicando i ticket di riferimento da cui nascono le richieste di modifica.

  • Man mano che si fanno modifiche, descriverle se necessario nel changelog, usando dch senza opzioni, come descritto sopra.

  • Quando si è pronti a pubblicare il pacchetto, modificare UNRELEASED con unstable nella prima riga; questo si può fare anche con il comando dch -r.

Verifica dello stato del repository e push

Prima di effettuare la build, accertarsi di aver committato tutte le modifiche effettuate, di non avere file spuri e di essere sul branch corretto (master o fuss/master a seconda dell’età del progetto), ad esempio con il comando:

$ git status

Committare quindi eventuali modifiche rimanenti, indicando se possibile nel commit log il numero di ticket associato alla modifica, con la dicitura «refs #NUMERO»:

$ git add -p <file modificati>
$ git add <file aggiunti>
$ git commit -m "<modifiche effettuate>. refs #NumeroTicket"

Inoltre o subito prima o subito dopo la build, ma prima dell’upload, è importante pushare tali commit, in modo da essere sicuri che nel frattempo non avvengano conflitti con commit altrui:

$ git push

Build

Alcuni pacchetti, come octofussd necessitano della preventiva creazione del tar dei sorgenti originali, come specificato nel README dei rispettivi repository; in tal caso prima di eseguire il comando precedente è necessario eseguire, nella directory principale del repository:

$ debian/rules debsrc

A questo punto si può usare pdebuild per eseguire la build del pacchetto all’interno di una chroot opportuna gestita da cowbuilder (sostituendo buster con stretch o jessie nei casi opportuni):

$ DIST=buster pdebuild --use-pdebuild-internal --pbuilder cowbuilder -- --basepath /var/cache/pbuilder/base-fuss-buster.cow/

pdebuild provvederà autonomamente ad installare le dipendenze necessarie all’interno della chroot e ad effettuare la build.

Generalmente, l’infrastruttura di build [1] è in grado di capire dal numero di versione ed altri indizi se sia necessario o meno includere la tarball .orig tra ciò che va uploadato. Nel caso in cui però si stia effettuando un backport questo non è automatico: per il primo backport di una certa versione upstream è necessario prevedere l’inclusione della tarball sorgente con l’opzione --debbuildopts "-sa", ovvero:

$ DIST=buster pdebuild --buildresult ../build/ --use-pdebuild-internal --pbuilder cowbuilder --debbuildopts "-sa" -- --basepath /var/cache/pbuilder/base-fuss-buster.cow/

Nota

Alla fine della build si riceverà un warning cannot create regular file /var/cache/pbuilder/result/<nomepacchetto>_<versione>.dsc; questo è irrilevante e i file necessari che sono stati generati si trovano nella directory superiore a quella da cui è stato lanciato pdebuild.

[1]

In particolare, l’inclusione o meno della tarball sorgente è decisa ed effettuata da dpkg-genchanges, richiamato da dpkg-buildpackage al quale pdebuild passa le opzioni specificate con il parametro --debbuildopts.

Generalmente questo avviene in automatico, senza bisogno di preoccuparsi di chi faccia cosa.

Build con git-buildpackage

In alternativa all’uso diretto di pdebuild, ma solo per i progetti il cui repository lo supporti tramite l’uso di un branch separato per la pacchettizzazione, è possibile usare git-buildpackage (o gbp): oltre ad effettuare la build in una chroot minimale questo si assicura anche che non ci siano differenze tra quanto committato (localmente) e quanto viene usato per la build.

Il comando da usare nel caso generale è:

gbp buildpackage --git-pbuilder --git-debian-branch=fuss/master \
   --git-dist=fuss-buster --git-no-pristine-tar

Test

Tramite dpkg -i <nomefile>.deb si puo” installare e testare il pacchetto. Si ricorda che dpkg non risolve le dipendenze, quindi darà un errore nel caso si sia aggiunta una nuova dipendenza.

Per installare le dipendenze mancanti si può usare il comando:

# apt -f install

Un altro comando utile è dpkg -c <nomefile>.deb per verificare i file presenti nel pacchetto.

lintian

Uno strumento di diagnostica molto dettagliato è lintian, che analizza i pacchetti generati alla ricerca di problemi di vario tipo e si lancia con:

lintian --pedantic -Iiv <pacchetto>.changes

Un limite di questo strumento è che è basato sugli standard di Debian e in alcuni casi gli errori potrebbero essere falsi positivi per gli standard fuss.

In particolare si possono ignorare i seguenti tag.

  • changelog-should-mention-nmu
  • source-nmu-has-incorrect-version-number

ed altri che verranno successivamente aggiunti a questo elenco.

Upload

Per uploadare il pacchetto buildato con dput-ng è sufficiente usare il comando:

$ dput fuss-<versione> nomepacchetto_versione_arch.changes

Nel caso si voglia procedere manualmente invece si possono copiare i file generati su isolda nella directory /iso/incoming/<versione> ed aggiornare il repository con il comando:

# /iso/bin/post-upload

Verificare poi che in /iso/incoming/<versione> non siano rimasti file spuri, e nel caso cancellarli a mano.

Tagging

Nel momento in cui tutto è pronto per un upload, taggare il commit corrispondente a quanto verrà uploadato con il comando:

$ git tag -s -m 'Fuss release <versione>' fuss/<versione>

in questo modo il tag verrà firmato con la propria chiave gpg di default; per non firmare il tag:

$ git tag -a -m 'Fuss release <versione>' fuss/<versione>

Ricordarsi di effettuare il push dei tag verso il server:

$ git push --tags

Build dei pacchetti in chroot

Nel caso ci siano problemi con l’uso di cowbuilder, è anche possibile usare una semplice chroot all’interno della quale installare gli strumenti di build e clonare il pacchetto.

Setup

Per creare una chroot ed installare gli strumenti di base:

# mkdir <versione>_build
# debootstrap <versione> <versione>_build (<mirror>)
# chroot <versione>_build
# apt install debhelper devscripts dpkg-dev

dove <versione> è al momento (marzo 2019) jessie per il FUSS server, stretch per il FUSS client e buster per le versioni future di server e client.

Build

Una volta clonato il repository (dentro la chroot), incrementato il numero di versione come sopra ed eventualmente generato il tar sorgente, per eseguire il build del pacchetto eseguire, nella directory principale del repository:

# dpkg-buildpackage -us -uc

Se la procedura va a buon fine, nella directory superiore si troveranno i pacchetti .deb generati, e anche i file .changes, .dsc e .tar.gz con il sorgente del pacchetto.

La procedura potrebbe fallire con un errore contenente:

Unmet build dependencies: <pacchetto1> <pacchetto2>

in tal caso installare semplicemente i pacchetti e riprovare. Tali dipendenze sono elencate nel campo Build-Depends del file debian/control, nel caso ci si voglia assicurare di averle già installate prima di buildare.

A questo punto si può procedere con test, commit+push ed upload come nel caso generale.

Policy di versionamento

Software sviluppato per FUSS

Per i pacchetti sviluppati specificatamente per FUSS possono esserci policy specifiche indicate nella relativa guida sviluppatori e/o nei README dei progetti.

In generale, lo schema usato prevede che la major version corrisponda alla versione di fuss per cui è rilasciato il pacchetto (che a sua volta corrisponde alla versione di debian su cui è basta). Un pacchetto per FUSS 8 avrà quindi versione tipo 8.X.Y, uno per FUSS 9 9.X.Y eccetera.

I pacchetti possono essere nativi o meno: nel primo caso il numero di versione è del tipo 9.X.Y sia per il pacchetto che in setup.py, mentre nel secondo si aggiunge un numero di revisione, es. 9.X.Y-Z; quest’ultimo va incrementato quando la nuova versione presenta modifiche nella pacchettizzazione (ovvero nella directory debian), ma non nel codice.

I pacchetti nativi devono anche avere 3.0 (native) nel file debian/source/format, mentre i pacchetti non-nativi devono avere 3.0 (quilt) e per buildarli è necessario generare una tarball sorgente (<nome>_<9.X.Z>.orig.tar.gz), ad esempio tramite debsrc.

Rebuild di pacchetti di debian

Per i pacchetti presi da debian e ribuildati da noi seguiamo una convenzione simile a quella usata dai backports aggiungendo ~fussN-X al numero di versione, dove N è la versione di FUSS per la quale stiamo preparando il pacchetto e X la revisione del backport.

Se si fa una rebuild di un pacchetto che ad esempio ha versione 1.2.3-4 la nostra versione sarà 1.2.3-4~fuss9+1 (+2 per una rebuild successiva con modifiche alla sola pacchettizzazione, eccetera).

Configurazione del repository

Il file /iso/repo/conf/distributions definisce le distribuzioni utilizzate nel repository, con snippet di configurazione come:

Origin: FUSS
Label: FUSS
Suite: jessie
Codename: jessie
Version: 8.0
Architectures: i386 amd64 source
Components: main contrib
Description: FUSS 8.0
SignWith: C00D47EF47AA6DE72DFE1033229CF7A871C7C823

inoltre nello stesso file sono definite le versioni precedenti e future della distribuzione. Al momento attuale la configurazione riguarda fino alla versione 10 di Debian (codename buster).

Le varie distribuzioni sono raggiungibili da apt usando, in /etc/apt/sources.list:

deb http://archive.fuss.bz.it CODENAME_DISTRIBUZIONE main contrib

e la chiave con la quale viene firmato il repository si può installare su una macchina debian o derivate eseguendo, da root:

# wget -qO - https://archive.fuss.bz.it/apt.key | apt-key add -

Aggiunta di nuova distribuzione e/o nuovo repository

Oltre al file /iso/repo/conf/distributions per indicare la nuova distribuzione e/o nuovo repository, è necessario:

  • Creare una cartella per lo spool di incoming dei pacchetti in /iso/incoming/<nuova distribuzione>
  • Aggiungere la descrizione e il path relativo al punto precedente nel file /iso/repo/conf/incoming
  • Aggiungere allo script /iso/bin/post-upload l’esecuzione del processing del nuovo path di incoming. In questo script vanno tolte quelle non più usate quando è certo che non ci saranno più nuovi pacchetti per una specifica distribuzione.

Pacchettizazione gestita con git

Nei progetti più recenti si è adottata una delle convenzioni in uso in Debian per la pacchettizzazione basata su git.

  • I branch di sviluppo del progetto, incluso master non contengono la directory debian, come da raccomandazione della UpstreamGuide di Debian.
  • I branch il cui nome inizia per fuss/ contengono la directory debian; generalmente il branch usato per gli upload della versione corrente sarà fuss/master.
  • Ad ogni rilascio, il branch master viene mergiato in fuss/master (ma mai il contrario) e il pacchetto può essere generato con i metodi descritti sopra.

Nel caso si voglia effettuare la build con gbp (pacchetto git-buildpackage il comando da usare sarà:

gbp buildpackage \
--git-pbuilder \
--git-no-pristine-tar \
--git-debian-branch=fuss/<versione> \
--git-dist=fuss-buster

aggiungendo --git-export=WC per fare build di prova dello stato attuale della working directory (anziché dello stato all’ultimo commit) oppure --git-ignore-new per fare una build corrispondente all’ultimo commit, ignorando le modifiche eventualmente presenti.

Pacchetti particolari

coova-chilli

Il pacchetto coova-chilli presente su archive.fuss.bz.it è generato da un nostro repository https://work.fuss.bz.it/git/coova-chilli copia del repository upstream https://github.com/coova/coova-chilli.git alla quale abbiamo aggiunto alcune modifiche di pacchettizzazione.

In particolare, per la release 1.4 è presente un branch 1.4-patched con dei bugfix alla pacchettizzazione che sono stati nel frattempo accettati upstream per le versioni successive.

Per effettuare nuove build della versione 1.4 è quindi necessario usare il branch 1.4-patched, mergiandovi eventuali modifiche upstream desiderate; usando git-buildpackage si dovrà usare:

$ gbp buildpackage --git-debian-branch=1.4-patched [--git-pbuilder]

Per versioni successive si possono invece usare i tag pubblicati da upstream.

Altri branch presenti sul nostro repository contengono la pacchettizzazione per versioni precedenti di FUSS, di utilità solo storica.