I repository ed il loro utilizzo: differenze tra le versioni

Riga 160: Riga 160:
</pre>
</pre>
Bisogna specificare obbligatoriamente il percorso completo del file se questo non si trova nella directory <code>/etc/apt/sources.list.d</code>
Bisogna specificare obbligatoriamente il percorso completo del file se questo non si trova nella directory <code>/etc/apt/sources.list.d</code>
= Pinning =
== Introduzione ==
Come molti sapranno, esistono tre distribuzioni di Debian (chiamate anche release):
# Debian stable, attualmente ''Wheezy'';
# Debian testing, attualmente ''Jessie'';
# Debian unstable, attualmente (e sempre,  un nome fisso) ''Sid''.
Il software della stable non viene aggiornato, eccezion fatta per gli aggiornamenti della sicurezza; il software della testing e della unstable viene al contrario aggiornato frequentemente, con una maggiore frequenza per la unstable. Oltre queste tre, ci sarebbero anche la ''oldstable'' (la vecchia stable, precedente all’attuale stable) e la ''experimental'' che non è una versione completa e funzionante di Debian, ma solo un repository contenente vario software in fase di progettazione, da sperimentare o altamente instabile, dal quale si può attingere dalle altre versioni ma a proprio rischio.
Spesso accade che utilizzando la testing o ancor di più la stable si voglia del software più nuovo rispetto a quello in dotazione; o che al contrario, utilizzando la testing o ancor di più la unstable si voglia del software più stabile rispetto a quello in dotazione. Qui entra in gioco il pinning dei repository, o meglio “tra i repository”, che permette di installare con semplicità del software appartenente a una distribuzione di Debian diversa da quella in uso o anche solo appartenente alla stessa distribuzione, ma proveniente da un altro repository.Tutto ciò riducendo al minimo (posto di sapere quel che si fa) il rischio di creare problemi nel sistema e nel gestore dei pacchetti.
{{Warningbox|Installare pacchetti provenienti da distribuzioni e/o fonti differenti è sempre e comunque fonte di possibili rischi, anche se piccoli}}
Prima di procedere nella descrizione operativa del pinning è '''fondamentale''' capire come gestisce la priorità dei pacchetti APT e sapere che:
* Col termine distribuzione si intendono stable, testing e unstable. Ciascuna distribuzione ha un suo singolo repository (fonte) principale (due se si conteggia anche l'eventuale repository dedicato agli aggiornamenti di sicurezza) che è quello automaticamente dichiarato dall'installer di debian, ma si tenga presente che ogni distribuzione può avere più fonti sia ufficiali che non ufficiali.
* Col termine fonti si intendono genericamente i repository, ufficiali (es. stable, testing, unstable e backports) o meno (es. deb-multimedia), che forniscono pacchetti relativi ad una o più distribuzioni. Ogni fonte può avere più copie di se stesso (mirrors).
{{Box|Importante|Il pinning è uno strumento per regolare la priorità in base al numero di versione dei pacchetti, e non alla fonte di provenienza. Questo significa che non è possibile discriminare tra due pacchetti aventi lo stesso numero di versione e provenienti da due repository differenti, ovvero in caso di pari versione ad essere installato sarà la versione proveniente dal repository elencato per primo nel file <code>sources.list</code>.}}
== Priorità come punteggio ==
Il concetto di priorità viene gestito attraverso l'assegnazione di un punteggio ai vari pacchetti, sia installati che ancora da installare. Valgono le seguenti regole:
* priorità '''100''' alla versione dei pacchetti già installati.
* priorità '''500''' alle versioni che non sono installate e non appartengono alla distribuzione obiettivo, dove con quest'ultimo termine si deve intendere "Default Release", "Target Release". Si noti per alcuni repository (come backports) in realtà la priorità predefinita di tali pacchetti risulta essere 100 e non 500 (vedasi manuale per maggiori informazioni).
* priorità '''990''' alle versioni che non sono installate e appartengono alla distribuzione obiettivo.
Piccolo esempio teorico. Si supponga quanto segue:
* si desidera installare il pacchetto "vattelapesca" appartenente alla propria distribuzione obiettivo, cioè quella che si è installata (si supponga testing);
* il suddetto pacchetto è presente in tre fonti, repoA, repoB, repoC tutte correttamente specificante nel file <code>source.list</code>;
* tutti i pacchetti presenti in repoA appartengono alla distribuzione obiettivo (testing in questo esempio), in repoB e repoC sono contenuti pacchetti appartenenti ad un'altra distribuzione (ad esempio unstable e stable rispettivamente);
* la versione di "vattelapesca" in repoA è la 1.4, in repoB la 2.0 e in in repoC la 1.1;
* nel sistema è installata la versione 1.3 di "vattelapesca";
* non esiste un file <code>preferences</code> o comunque non è stata specificata una priorità per nessuna delle tre distribuzioni considerate;
* non è stato dichiarato il parametro ''Default Release'' in un eventuale file <code>apt.conf</code>, ovvero non è stata esplicitamente definita una distribuzione obiettivo.
Nel momento in cui l'utente esegue il comando <code>apt-get install vattelapesca</code> saranno assegnati i seguenti punteggi:
* 500 a "vattelapesca" presente in repoC;
* 500 a "vattelapesca" presente in repoB;
* 500 a "vattelapesca" presente in repoA;
Tutti e tre i pacchetti hanno lo stesso punteggio, ma il pacchetto proveniente da C viene immediatamente scartato perché implicherebbe retrocessione dello stesso (downgrade, il significato delle varie fascie di punteggio sarà spiegato poco più avanti). A questo punto APT sceglierà tra repoA e repoB in base ad un altro criterio, la versione, quindi ad essere installato sarà il pacchetto proveniente da repoB e non da repoA come desiderato.
Il problema evidentemente non può che esplodere quando si esegue il comando <code>apt-get upgrade</code> (o peggio <code>apt-get dist-upgrade</code>), cioè quando si tenta di aggiornare tutti i pacchetti di sistema.
La soluzione è, come facilmente intuibile, quella di assegnare manualmente un punteggio ai vari pacchetti, singolarmente o raggruppandoli. Prima però è necessario capire il significato dei vari punteggi (pin). Nel seguito si indicherà col termine "candidato" il pacchetto o gruppo di pacchetti proveniente dalla generica fonte dichiarata nel file <code>sources.list</code>.
* Pin '''minore di 0''' (negativo), l’installazione del candidato è impedita a priori (salvo apposito comando).
* Pin compreso tra '''1 e 99''', il candidato sarà installato solo se sono verificate entrambe le seguenti due condizioni: primo non esistono candidati appartenenti ad altre distribuzioni, secondo nel sistema non è già installata una versione (anche inferiore) del candidato.
* Pin compreso tra '''100 e 499''', il candidato sarà installato solo se non esistono candidati appartenenti ad altre distribuzioni e se la versione eventualmente già installata non è superiore a quella del candidato. Se per esempio il pacchetto "vattelapesca" ha pin 400 ed è presente su due fonti (posto ovviamente di aver dichiarato entrambe nel solito <code>sources.list</code>) e ciascuna fonte appartiene ad una distribuzione differente, come stable e testing, allora sarà impossibile installare il suddetto pacchetto, a prescindere dal numero di versione; diversamente se le due fonti appartenessero alla stessa distribuzione allora il pacchetto potrebbe teoricamente essere installato. (NOTA, l'esempio fatto è strettamente teorico e non verificato praticamente).
* Pin compreso tra '''500 e 989''', il candidato sarà installato solo se non esistono candidati appartenenti alla distribuzione obiettivo e se la versione eventualmente già installata non è superiore a quella del candidato. Si noti che il semplice fatto di aver installato una certa distribuzione, per esempio testing, non significa aver definito la distribuzione obiettivo, che può essere solo definita manualmente dall'utente (il come sarà spiegato nella discussione del file <code>apt.conf</code>).
* Pin compreso tra '''990 e 999''', il candidato sarà installato solo se non esistono altri candidati con pin maggiore e se la versione eventualmente già installata non è superiore a quella del candidato.
* Pin '''1000''' o superiore, il candidato sarà installato se non esistono altri candidati con pin maggiore, è quindi possibile la retrocessione di versione (downgrade) se la versione eventualmente già installata è superiore a quella del candidato. Es. è possibile installare la versione 1.1 di un pacchetto anche se ad essere già installata è la 1.2 o superiore.
{{Box|Nota|
* Gli intervalli sopra citati sono presi tali e quali dal manuale di ''apt_preferences'', tuttavia a volte si è osservato che i limiti funzionano come dovrebbero se traslati in alto di una unità, ad esempio l'ultimo intervallo potrebbe partire da 1001 invece che da 1000.
* APT può derogare alle regole generali sopra esposte in casi particolari per soddisfare le varie dipendenze dei pacchetti.}}
== /etc/apt/apt.conf ==
Questo file insieme ad altri permette di definire le opzioni di APT e relativi strumenti senza bisogno di digitarli sempre da riga di comando. Si vedano le guide dedicate ad [[Apt-get | Apt-Get]] e [[Aptitude]] per alcuni brevi esempi contenenti alcui dei parametri più comuni.
Per quanto riguarda il pinning l'unico parametro strettamente di rilievo è:
<pre>APT::Default-Release "distribuzione_voluta";</pre>
che equivale alla dichiarazione in riga di comando dell'opzione '''-t distribuzione_voluta''' sia in [[Apt-get | Apt-Get]] che [[Aptitude]]. Tale dichiarazione attribuisce priorità 990 a tutti i pacchetti appartenenti alla distribuzione specificata.
{{Warningbox|Tale priorità si applica alla distribuzione e non alla fonte, quindi ad ottenere la suddetta priorità non saranno solo i pacchetti appartenenti al repository principale (o ai due repository principali), ma anche quelli provenienti da altre fonti se il gestore di tale repository usa lo stesso valore per i parametri suite e codename di quelli principali, ad esempio ''stable'' e ''wheezy''. Per esempio ''backports'' non comporta problemi poiché i precedenti due parametri valgono ''nome_suite-backports'' e ''nome_codename-backports'', viceversa quello di ''deb-multimedia'' usa gli stessi identici valori di quelli principali.}}
Si noti inoltre che:
* Le dichiarazioni di parametri da riga di comando hanno sempre la precedenza su quelli definiti in un file di configurazione, quindi usare un comando del tipo <code>apt-get install pacchetto -t distribuzione_taldeitali</code> sorpassa qualunque distribuzione obiettivo (''Default-Release'') dichiarata nel file <code>apt.conf</code>.
* Comandi del tipo <code>apt-get install pacchetto/distribuzione_taldeitali</code> non cambiano la ''target release'', ma si limitano a dire di prelevare lo specifico pacchetto dalla distribuzione indicata invece che da quella predefinita. Questo implica che le dipendenze continueranno ad essere risolte in base alla distribuzione obiettivo eventualmente specificata in <code>apt.conf</code> e/o in base al file preferences e/o in accordo all'algoritmo predefinito.
* Definire una distribuzione obiettivo in <code>apt.conf</code> è equivalente a dichiarare in <code>preferences</code> (si veda la prossima sezione) quanto segue
<pre>
Package: *
Pin: release a=distribuzione_voluta
Pin-Priority: 990
</pre>
* Qualora si sia definita una distribuzione obiettivo in <code>apt.conf</code> allora quasiasi dichiarazione in <code>preferences</code> riguardante tutti i pacchetti di una certa distribuzione sarà ignorata, ad esempio definire
<pre>
Package: *
Pin: release a=testing
Pin-Priority: 1000
</pre>
: è del tutto inutile se poi si usa l'opzione '''-t testing'''. Non è invece inutile una dichiarazione del seguente tipo:
<pre>
Package: specifico pacchetto o espressione regolare
Pin: release a=testing
Pin-Priority: 1000
</pre>
== /etc/apt/preferences ==
Questo è il file dove è possibile definire tutte le priorità che si vogliono, fermo restando quanto detto nella sezione dedicata ad <code>apt.conf</code>. La sintassi generale è la seguente:
<pre>
Package: nome pacchetto o espressione regolare
Pin: parametro da usare per identificare la versione desiderata
Pin-Priority: numero
</pre>
Un paio di esempi del tutto arbitrari:
<pre>
Package: vlc
Pin: release a=testing
Pin-Priority: 991
Package: virtualbox4*
Pin: Release o=Oracle Corporation
Pin-Priority: 780
</pre>
Nel primo esempio si è definito il pinning per il pacchetto di nome "vlc", richiedendo che le versioni appartenenti alla distribuzione testing abbiano priorità 991. Nel secondo invece sfruttando una semplicissima espressione regolare si impone che tutti i pacchetti il cui nome inizia per "virtualbox4" e appartenenti al repository la cui origine è definita come "Oracle Corporation" abbiano priorità 780.
Il pinning può essere orientato ai campi "Suite", "Origin", "Label" e "Codename" del file "Release" di un certo repository (si veda inizio pagina), nonché all'indirizzo del repository stesso. Si noti che per archivi personali e/o non ufficiali può non essere presente (purtroppo) un file "Release".
È utile infine evidenziare un paragrafo del manuale di ''apt_preferences'':
{{Box|Importante|''Se almeno un record in forma specifica corrisponde ad una versione di pacchetto disponibile, allora il primo di questi record determina la priorità della versione del pacchetto. In caso contrario, se almeno un record in forma generica corrisponde ad una versione di pacchetto disponibile, allora il primo di questi record determina la priorità della versione del pacchetto.''}}
{{Suggerimento|Specificare nel file <code>sources.list</code> sempre per primi il o i repository principali della distribuzione obiettivo.}}
== Esempi ==
=== 01 ===
La distribuzione principale sia testing, quella secondaria unstable.
==== sources.list ====
<pre>
deb http://ftp.it.debian.org/debian/ testing main contrib non-free
deb http://security.debian.org/ testing/updates main contrib non-free
deb http://ftp.de.debian.org/debian unstable main contrib non-free
</pre>
==== apt.conf ====
<pre>
APT
{
        Default-Release "testing";
        Cache-Limit 48000000;
        Get
        {
                AllowUnauthenticated 1;
                AutomaticRemove "true";
                Fix-Broken "true";
                Purge "true";
                Show-Upgraded "true";
        }
}
Aptitude
{
        Autoclean-After-Update "true";
        Auto-Fix-Broken "true";
        Purge-Unused "true";
}
</pre>
==== preferences ====
<br/>
<pre>
Package: *
Pin: release a=unstable
Pin-Priority: 500
Package: *
Pin: release o=Debian
Pin-Priority: -10
</pre>
==== Conseguenze ====
Usando le azioni ''install'' e ''upgrade'' senza specificare l'opzione '''-t unstable''' si installano/aggiornano pacchetti prelevando le versioni da testing, a meno che un pacchetto sia presente solo in unstable, nel qual caso sarà prelevato da lì. Le dipendenze saranno risolte se possibile usando testing, altrimenti usando unstable.
Digitando <code>apt-get install vattelapesca -t unstable</code> si installerà la versione "vattelapesca" appartenente ad unstable, così come le sue dipendenze. Si noti che in questo caso successivi aggiornamenti tramite comandi del tipo <code>apt-get upgrade</code> o <code>apt-get dist-upgrade</code> non produrranno alcun aggiornamento da unstable del pacchetto "vattelapesca" se questo è anche presente in testing; in tal caso l'unica possibilità di aggiornare "vattelapesca" è digitare nuovamente <code>apt-get install vattelapesca -t unstable</code> (o aspettare pazientemente che la versione di testing superi quella installata).
=== 02 ===
Sia testing l'unica distribuzione d'interesse, nonché quella obiettivo. Si supponga di voler usare anche la fonte ''www.deb-multimedia.org'', ma con l'unico scopo di installare solo quei pacchetti che non sono presenti nel repository principale.
{{Box|Nota|Questo esempio non permette di retrocedere automaticamente pacchetti già installati da deb-multimedia.}}
==== sources.list ====
<pre>
deb http://ftp.it.debian.org/debian/ testing main contrib non-free
deb http://security.debian.org/ testing/updates main contrib non-free
deb http://www.deb-multimedia.org testing main non-free
</pre>
==== apt.conf ====
<pre>
APT
{
        Cache-Limit 48000000;
        Get
        {
                AllowUnauthenticated 1;
                AutomaticRemove "true";
                Fix-Broken "true";
                Purge "true";
                Show-Upgraded "true";
        }
}
Aptitude
{
        Autoclean-After-Update "true";
        Auto-Fix-Broken "true";
        Purge-Unused "true";
}
</pre>
==== preferences ====
<br/>
<pre>
Package: *
Pin: Release o=Unofficial Multimedia Packages
Pin-Priority: 101
Package: *
Pin: Release a=Testing
Pin-Priority: 990
Package: *
Pin: release o=Debian
Pin-Priority: -10
</pre>
==== Osservazioni ====
Poiché entrambe le fonti, ''principale'' e ''deb-multimedia'', appartengono alla distribuzione testing in teoria questo caso non sarebbe gestibile tramite pinning, tuttavia sotto l'ipotesi di voler installare da deb-multimedia solo i pacchetti non presenti nella fonte principale il problema è risolvibile. Evitando di definire in <code>apt.conf</code> una distribuzione obiettivo e definendo in <code>preferences</code> prima il record relativo a deb-multimedia si ottiene di riuscire ad assegnare la priorità desiderata, nonostante il fatto che il secondo record si applichi in teoria anche a deb-multimedia.<br/>
Si noti che stanti così le cose dovrebbe essere in realtà possibile attribuire pin superiori, fino a 989, a deb-multimedia, senza che per questo i suoi candidati ottengano la precedenza su quelli del repository principale.
Qualora invece si desiderasse dare la precedenza ai pacchetti di deb-multimedia sarebbe sufficiente definire la distribuzione obiettivo in <code>apt.conf</code> risultando perfino inutile definire un file <code>preferences</code>, visto che come già detto di norma i candidati di deb-multimedia hanno numero di versione maggiore di queli del repository principale.
In ultimo si fa semplicemente osservare che l'utilizzo dell'opzione '''-t''' in questo caso è inutile, visto che si lavora per ipotesi con una sola distribuzione.
=== 03 ===
In questo how-to mostrerò come utilizzare pacchetti Debian provenienti da Testing, Unstable, Experimental e deb-multimedia (audio/video) ma le istruzioni sono facilmente riportabili anche ad altre situazioni (unstable + experimental, stable + testing, stable + unstable, stable + testing + unstable, ecc.).
==== Impostare i repository ====
Assicuriamoci di essere l'utente root e procediamo.
Per prima cosa editiamo il file <code>/etc/apt/sources.list</code> ed inseriamo gli archivi dei pacchetti Debian che utilizzeremo, per esempio:
<pre>
### Debian Ufficiale -- Testing
deb http://ftp.it.debian.org/debian/ testing main contrib non-free
### Debian Ufficiale -- Testing Sicurezza
deb http://security.debian.org/ testing/updates main contrib non-free
### Debian Ufficiale -- Sid
deb http://ftp.it.debian.org/debian/ unstable main contrib non-free
###  Debian Ufficiale -- Experimental
deb http://ftp.it.debian.org/debian/ experimental main contrib non-free
### deb-multimedia -- Audio/Video -- Marillat
deb http://www.deb-multimedia.org testing main non-free
deb http://www.deb-multimedia.org sid main non-free
</pre>
==== Configurare apt ====
A questo punto dobbiamo preparare due file normalmente non presenti sulla nostra debianbox: si tratta dei file <code>/etc/apt/preferences</code> e <code>/etc/apt/apt.conf</code>.
Questi due file istruiranno APT su come gestire le dipendenze dei pacchetti, informandolo su come comportarsi in caso di conflitti e altri problemi.
===== Il file <code>apt.conf</code> =====
Ora creiamo il file <code>/etc/apt/apt-conf</code>
<pre># touch /etc/apt/apt.conf</pre>
ed editiamolo inserendo quanto segue:
<pre>
APT::Default-Release "testing";
APT::Cache-Limit 15000000;
Apt::Get::Purge;
APT::Clean-Installed;
APT::Get::Fix-Broken;
APT::Get::Fix-Missing;
APT::Get::Show-Upgraded "true";
</pre>
===== Il file <code>preferences</code> =====
Creiamo il file <code>/etc/apt/preferences</code>:
<pre># touch /etc/apt/preferences</pre>
ed editiamolo col nostro editor di fiducia e inseriamo queste direttive:
<pre>
Package: *
Pin: release o=Unofficial Multimedia Packages
Pin-Priority: 950
Package: *
Pin: release a=unstable
Pin-Priority: 800
Package: *
Pin: release a=experimental
Pin-Priority: 750
</pre>
Facciamo l'update del database dei pacchetti:
<pre># apt-get update</pre>
D'ora in avanti avremo due possibilità per installare un nuovo pacchetto: il metodo che usiamo di solito e cioè:
<pre># apt-get install nome_pacchetto</pre>
che utilizzerà pacchetti proveniente dalla versione impostata come '''Default-Release''' in '''apt.conf''', oppure il comando
<pre># apt-get install -t versione_di_debian nome_pacchetto</pre>
che provvederà a installare il pacchetto da noi richiesto per la versione specificata (versione_debian), risolvendo automaticamente le dipendenze.


= Approfondimenti =
= Approfondimenti =
3 155

contributi