This is guix-cookbook.it.info, produced by makeinfo version 6.8 from
guix-cookbook.it.texi.

Copyright © 2019, 2022 Ricardo Wurmus
Copyright © 2019 Efraim Flashner
Copyright © 2019 Pierre Neidhardt
Copyright © 2020 Oleg Pykhalov
Copyright © 2020 Matthew Brooks
Copyright © 2020 Marcin Karpezo
Copyright © 2020 Brice Waegeneire
Copyright © 2020 André Batista
Copyright © 2020 Christine Lemmer-Webber
Copyright © 2021 Joshua Branson
Copyright © 2022, 2023 Maxim Cournoyer
Copyright © 2023-2025 Ludovic Courtès
Copyright © 2023 Thomas Ieong
Copyright © 2024 Florian Pelz
Copyright © 2025 45mg
Copyright © 2023 Marek Felšöci
Copyright © 2023 Konrad Hinsen
Copyright © 2023 Philippe Swartvagher

   È concesso il permesso di copiare, distribuire e/o modificare questo
documento secondo i termini della GNU Free Documentation License,
Versione 1.3 o qualsiasi versione successiva pubblicata dalla Free
Software Foundation; senza Sezioni Invarianti, senza Testi di Copertina
e senza Testi di Retro copertina. Una copia della licenza è inclusa
nella sezione intitolata "Licenza di Documentazione Libera GNU".
INFO-DIR-SECTION Amministrazione di sistema
START-INFO-DIR-ENTRY
* Libro di ricette di Guix: (guix-cookbook.it).  Tutorial ed esempi per GNU
                                                   Guix.
END-INFO-DIR-ENTRY


File: guix-cookbook.it.info,  Node: Top,  Next: Tutorial di Scheme,  Up: (dir)

Ricettario di GNU Guix
**********************

Questo documento presenta tutorial ed esempi dettagliati per GNU Guix,
uno strumento di gestione pacchetti funzionale scritto per il sistema
GNU. Si prega di *note (guix.it)Top:: per dettagli sul sistema, la sua
API e i concetti correlati.

   Questo manuale è disponibile anche in inglese (*note
(guix-cookbook)Top::), francese (*note (guix-cookbook.fr)Top::), cinese
semplificato (*note (guix-cookbook.zh_CN)Top::), tedesco (*note
(guix-cookbook.de)Top::), coreano (*note (guix-cookbook.ko)Top::),
spagnolo (*note (guix-cookbook.es)Top::), portoghese brasiliano (*note
(guix-cookbook.pt_BR)Top::), russo (*note (guix-cookbook.ru)Top::),
slovacco (*note (guix-cookbook.sk)Top::), svedese (*note
(guix-cookbook.sv)Top::) e tamulo (*note (guix-cookbook.ta)Top::). Se
desideri tradurre questo documento nella tua lingua madre, considera di
unirti a Weblate
(https://translate.codeberg.org/projects/guix/documentation-cookbook)
(*note (guix.it)Tradurre Guix::).

* Menu:

* Tutorial di Scheme::       Incontra il tuo nuovo linguaggio preferito!
* Impacchettamento::         Tutorial sull’impacchettamento
* Configurazione di sistema::  Personalizzazione del Sistema GNU
* Contenitori::              Ambienti isolati e sistemi annidati
* Macchine virtuali::        Uso e configurazione delle macchine virtuali
* Gestione avanzata dei pacchetti::  Potere agli utenti!
* Sviluppo software::        Ambienti, integrazione continua, ecc.
* Gestione dell'ambiente::   Ambiente di controllo
* Reproducible Research::    A foundation for reproducible research.
* Installare Guix su un Cluster::  Calcolo ad alte prestazioni.
* Gestione del Sistema Guix::  Specifiche della gestione di sistema.

* Ringraziamenti::           Grazie!
* Licenza di Documentazione Libera GNU::  La licenza di questo documento.
* Indice dei concetti::      Concetti.

 — L’Elenco Dettagliato dei Nodi —



Tutorial di Scheme



* Un corso intensivo di Scheme::  Un corso intensivo di Scheme

Impacchettamento



* Tutorial sull'Impacchettamento::  Un tutorial su come aggiungere pacchetti
                                      a Guix.
* Packaging Workflows::      Real life examples on working with specific
                               build systems.

Tutorial sull’Impacchettamento



* Un pacchetto "Hello World"::  Un pacchetto "Hello World"
* Configurazione::           Configurazione
* Esempio esteso::           Esempio esteso
* Altri sistemi di build::   Altri sistemi di build
* Definizione di pacchetto programmabile e automatizzata::  Definizione di
                                                              pacchetto
                                                              programmabile e
                                                              automatizzata
* Ottenere aiuto::           Ottenere aiuto
* Conclusione::              Conclusione
* Riferimenti::              Riferimenti

Configurazione



* File locale::              File locale
* Canali::                   Canali
* Modifica diretta dal checkout::  Modifica diretta dal checkout

Definizione di pacchetto programmabile e automatizzata



* Importatori ricorsivi::    Importatori ricorsivi
* Aggiornamento automatico::  Aggiornamento automatico
* Ereditarietà::             Ereditarietà

Packaging Workflows



* Packaging Rust Crates::    Packaging Rust Crates

Packaging Rust Crates



* Common Workflow for Rust Packaging::  Common Workflow for Rust Packaging
* Cargo Workspaces and Development Snapshots::  Cargo Workspaces and
                                                  Development Snapshots
* Using Rust Libraries in Other Build Systems::  Using Rust Libraries in
                                                   Other Build Systems

Configurazione di sistema



* Accesso automatico a una TTY specifica::  Accedere automaticamente un
                                              utente a una TTY specifica
* Personalizzazione del kernel::  Creazione e utilizzo di un kernel Linux
                                    personalizzato su Guix System.
* API immagine di Sistema Guix::  Personalizzazione di immagini per
                                    piattaforme specifiche.
* Utilizzo di chiavi di sicurezza::  Come usare le chiavi di sicurezza con
                                       Guix System.
* Processo mcron per DNS dinamico::  Processo per aggiornare l’indirizzo IP
                                       dietro un nome host DuckDNS.
* Connessione a una VPN Wireguard::  Connessione a una VPN Wireguard.
* Personalizzazione di un Window Manager::  Gestire la personalizzazione di
                                              un Window Manager su Guix
                                              System.
* Eseguire Guix su un Server Linode::  Eseguire Guix su un Server Linode.
* Eseguire Guix su un Server Kimsufi::  Eseguire Guix su un Server Kimsufi.
* Configurazione di un bind mount::  Configurazione di un bind mount nella
                                       definizione dei file system.
* Ottenere sostituti da Tor::  Configurazione del demone Guix per ottenere
                                 sostituti tramite Tor.
* Configurazione di NGINX con Lua::  Configurazione del server web NGINX per
                                       caricare i moduli Lua.
* Server musicale con audio Bluetooth::  Lettore musicale headless con
                                           uscita Bluetooth.

Personalizzazione di un Window Manager



* StumpWM::                  StumpWM
* Blocco sessione::          Blocco sessione

Blocco sessione



* Xorg::                     Xorg

Contenitori



* Contenitori Guix::         Ambienti perfettamente isolati
* Contenitori di Sistema Guix::  Un sistema dentro il tuo sistema

Contenitori di Sistema Guix



* Un contenitore Database::  Un contenitore Database
* Networking dei contenitori::  Networking dei contenitori

Macchine virtuali



* Ponte di rete per QEMU::   Ponte di rete per QEMU
* Rete instradata per libvirt::  Rete instradata per libvirt
* Rete personalizzata basata su NAT per libvirt::  Rete personalizzata
                                                     basata su NAT per libvirt
* Riferimenti: Riferimenti VM.  Ulteriori letture sulle macchine virtuali.

Gestione avanzata dei pacchetti



* Profili Guix in pratica::  Strategie per profili e manifesti multipli.

Profili Guix in pratica



* Configurazione di base con i manifesti::  Configurazione di base con i
                                              manifesti
* Pacchetti richiesti::      Pacchetti richiesti
* Profilo predefinito::      Profilo predefinito
* I benefici dei manifesti::  I benefici dei manifesti
* Profili riproducibili::    Profili riproducibili

Sviluppo software



* Per iniziare::             Passo 0: usare ‘guix shell’.
* Costruire con Guix::       Passo 1: compilare il tuo codice.
* Il repository come canale::  Passo 2: trasformare il repo in un canale.
* Varianti di pacchetto::    Bonus: Definire le varianti.
* Configurazione dell'integrazione continua::  Passo 3: integrazione
                                                 continua.
* Manifesto di build::       Bonus: Manifesto.
* In conclusione::           Riepilogo.

Gestione dell’ambiente



* Ambiente Guix tramite direnv::  Configura l’ambiente Guix con direnv

Using Guix for Reproducible Research



* Setting Up the Environment::  Step 1: using ‘guix shell’.
* Recording the Environment::  Step 2: using ‘guix describe’.
* Ensuring Long-Term Source Code Archiving::  Step 3: Software Heritage.
* Referencing the Software Environment::  Step 4: SWHIDs.

Installare Guix su un Cluster



* Configurazione di un nodo principale::  Il nodo che esegue il demone.
* Configurazione dei nodi di calcolo::  Nodi client.
* Accesso alla rete del cluster::  Gestione delle restrizioni di accesso
                                     alla rete.
* Utilizzo del disco del cluster::  Considerazioni sull’utilizzo del disco.
* Considerazioni sulla sicurezza del cluster::  Mantenere il cluster sicuro.

Gestione del Sistema Guix



* Aggiornare Postgres per Cuirass::  Aggiornamento dal postgres predefinito.



File: guix-cookbook.it.info,  Node: Tutorial di Scheme,  Next: Impacchettamento,  Prev: Top,  Up: Top

1 Tutorial di Scheme
********************

GNU Guix è scritto nel linguaggio di programmazione generico Scheme, e
molte delle sue funzionalità possono essere accessibili e manipolate
programmaticamente. Puoi usare Scheme per generare definizioni di
pacchetti, per modificarle, per compilarle, per distribuire interi
sistemi operativi, ecc.

   Conoscere le basi di come programmare in Scheme sbloccherà molte
delle funzionalità avanzate che Guix fornisce — e non è nemmeno
necessario essere un programmatore esperto per usarle!

   Iniziamo!

* Menu:

* Un corso intensivo di Scheme::  Un corso intensivo di Scheme


File: guix-cookbook.it.info,  Node: Un corso intensivo di Scheme,  Up: Tutorial di Scheme

1.1 Un corso intensivo di Scheme
================================

Guix utilizza l’implementazione Guile di Scheme. Per iniziare a giocare
con il linguaggio, installalo con ‘guix install guile’ e avvia un “REPL”
— abbreviazione di “read-eval-print loop”
(https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) —
eseguendo ‘guile’ dalla riga di comando.

   In alternativa, puoi anche eseguire ‘guix shell guile -- guile’ se
preferisci non avere Guile installato nel tuo profilo utente.

   Negli esempi seguenti, le righe mostrano cosa digiteresti nel REPL;
le righe che iniziano con "⇒" mostrano i risultati della valutazione,
mentre le righe che iniziano con "⊣" mostrano le cose che vengono
stampate. *Note (guile)Using Guile Interactively::, per maggiori
dettagli sul REPL.

   • La sintassi di Scheme si riduce a un albero di espressioni (o
     _s-expression_ nel gergo Lisp). Un’espressione può essere un
     letterale come numeri e stringhe, o un composto che è una lista tra
     parentesi di composti e letterali. ‘#true’ e ‘#false’ (abbreviato
     ‘#t’ e ‘#f’) rappresentano i booleani "vero" e "falso",
     rispettivamente.

     Esempi di espressioni valide:

          "Hello World!"
          ⇒ "Hello World!"

          17
          ⇒ 17

          (display (string-append "Ciao " "Guix" "\n"))
          ⊣ Ciao Guix
          ⇒ #<unspecified>

   • Quest’ultimo esempio è una chiamata di funzione annidata in
     un’altra chiamata di funzione. Quando un’espressione tra parentesi
     viene valutata, il primo termine è la funzione e il resto sono gli
     argomenti passati alla funzione. Ogni funzione restituisce l’ultima
     espressione valutata come valore di ritorno.

   • Le funzioni anonime — “procedures” nel gergo di Scheme — sono
     dichiarate con il termine ‘lambda’:

          (lambda (x) (* x x))
          ⇒ #<procedure 120e348 at <unknown port>:24:0 (x)>

     La procedura sopra restituisce il quadrato del suo argomento.
     Poiché tutto è un’espressione, l’espressione ‘lambda’ restituisce
     una procedura anonima, che a sua volta può essere applicata a un
     argomento:

          ((lambda (x) (* x x)) 3)
          ⇒ 9

     Le procedure sono valori regolari proprio come numeri, stringhe,
     booleani e così via.

   • A qualsiasi cosa può essere assegnato un nome globale con ‘define’:

          (define a 3)
          (define square (lambda (x) (* x x)))
          (square a)
          ⇒ 9

   • Le procedure possono essere definite in modo più conciso con la
     seguente sintassi:

          (define (square x) (* x x))

   • Una struttura di lista può essere creata con la procedura ‘list’:

          (list 2 a 5 7)
          ⇒ (2 3 5 7)

   • Le procedure standard sono fornite dal modulo ‘(srfi srfi-1)’ per
     creare ed elaborare liste (*note elaborazione di liste:
     (guile)SRFI-1.). Ecco alcune delle più utili in azione:

          (use-modules (srfi srfi-1))  ;importa procedure di elaborazione di liste

          (append (list 1 2) (list 3 4))
          ⇒ (1 2 3 4)

          (map (lambda (x) (* x x)) (list 1 2 3 4))
          ⇒ (1 4 9 16)

          (delete 3 (list 1 2 3 4))        ⇒ (1 2 4)
          (filter odd? (list 1 2 3 4))     ⇒ (1 3)
          (remove even? (list 1 2 3 4))    ⇒ (1 3)
          (find number? (list "a" 42 "b")) ⇒ 42

     Notare come il primo argomento di ‘map’, ‘filter’, ‘remove’ e
     ‘find’ sia una procedura!

   • Il “quote” disabilita la valutazione di un’espressione tra
     parentesi, chiamata anche S-expression o "s-exp": il primo termine
     non viene chiamato sugli altri termini (*note quote:
     (guile)Expression Syntax.). Quindi restituisce effettivamente una
     lista di termini.

          '(display (string-append "Ciao " "Guix" "\n"))
          ⇒ (display (string-append "Ciao " "Guix" "\n"))

          '(2 a 5 7)
          ⇒ (2 a 5 7)

   • Il ‘quasiquote’ (‘`’, un apice inverso) disabilita la valutazione
     di un’espressione tra parentesi finché ‘unquote’ (‘,’, una virgola)
     non la riabilita. Quindi ci fornisce un controllo preciso su cosa
     viene valutato e cosa no.

          `(2 a 5 7 (2 ,a 5 ,(+ a 4)))
          ⇒ (2 a 5 7 (2 3 5 7))

     Notare che il risultato sopra è una lista di elementi misti:
     numeri, simboli (qui ‘a’) e l’ultimo elemento è una lista stessa.

   • Guix definisce una variante delle S-expression con gli steroidi
     chiamata “G-expressions” o "gexps", che viene fornita con una
     variante di ‘quasiquote’ e ‘unquote’: ‘#~’ (o ‘gexp’) e ‘#$’ (o
     ‘ungexp’). Ti permettono di _mettere in scena il codice per
     un’esecuzione successiva_.

     Ad esempio, incontrerai le gexps in alcune definizioni di pacchetto
     dove forniscono codice da eseguire durante il processo di
     compilazione del pacchetto. Appaiono così:

          (use-modules (guix gexp)           ;così possiamo scrivere gexps
                       (gnu packages base))  ;per 'coreutils'

          ;; Di seguito una G-expression che rappresenta codice messo in scena.
          #~(begin
              ;; Invoca 'ls' dal package definito dalla variabile 'coreutils'.
              (system* #$(file-append coreutils "/bin/ls") "-l")

              ;; Crea la directory di output di questo pacchetto.
              (mkdir #$output))

     *Note (guix.it)G-expression::, per maggiori informazioni sulle
     gexps.

   • È possibile nominare più variabili localmente con ‘let’ (*note
     (guile)Local Bindings::):

          (define x 10)
          (let ((x 2)
                (y 3))
            (list x y))
          ⇒ (2 3)

          x
          ⇒ 10

          y
          error→ In procedure module-lookup: Variabile non legata: y

     Usa ‘let*’ per permettere alle dichiarazioni di variabili
     successive di fare riferimento a definizioni precedenti.

          (let* ((x 2)
                 (y (* x 3)))
            (list x y))
          ⇒ (2 6)

   • Le “Parole Chiave” sono tipicamente usate per identificare i
     parametri nominati di una procedura. Sono precedute da ‘#:’
     (cancelletto, due punti) seguito da caratteri alfanumerici:
     ‘#:in-questo-modo’. *Note (guile)Keywords::.

   • La percentuale ‘%’ è tipicamente usata per le variabili globali di
     sola lettura nella fase di compilazione. Notare che è solo una
     convenzione, come ‘_’ in C. Scheme tratta ‘%’ esattamente come
     qualsiasi altra lettera.

   • I moduli sono creati con ‘define-module’ (*note (guile)Creating
     Guile Modules::). Per esempio

          (define-module (guix build-system ruby)
            #:use-module (guix store)
            #:export (ruby-build
                      ruby-build-system))

     definisce il modulo ‘guix build-system ruby’ che deve essere
     situato in ‘guix/build-system/ruby.scm’ da qualche parte nel
     percorso di caricamento di Guile. Dipende dal modulo ‘(guix store)’
     ed esporta due variabili, ‘ruby-build’ e ‘ruby-build-system’.

     *Note (guix.it)Moduli di pacchetti::, per informazioni sui moduli
     che definiscono i pacchetti.

     Andare oltre: Scheme è un linguaggio ampiamente utilizzato per
     insegnare la programmazione e troverai molto materiale che lo usa
     come veicolo. Ecco una selezione di documenti per saperne di più su
     Scheme:

        • Un Primer di Scheme
          (https://spritely.institute/static/papers/scheme-primer.html),
          di Christine Lemmer-Webber e lo Spritely Institute.

        • Struttura e Interpretazione dei Programmi per Elaboratore
          (https://sarabander.github.io/sicp/), di Harold Abelson e
          Gerald Jay Sussman, con Julie Sussman. Conosciuto
          colloquialmente come "SICP", questo libro è un riferimento.

          Puoi anche installarlo e leggerlo dal tuo computer:

               guix install book-sicp info-reader
               info sicp

     Troverai altri libri, tutorial e altre risorse su
     <https://schemers.org/>.


File: guix-cookbook.it.info,  Node: Impacchettamento,  Next: Configurazione di sistema,  Prev: Tutorial di Scheme,  Up: Top

2 Impacchettamento
******************

Questo capitolo è dedicato a insegnarti come aggiungere pacchetti alla
collezione di pacchetti fornita con GNU Guix. Ciò comporta la scrittura
di definizioni di pacchetti in Guile Scheme, l’organizzazione in moduli
di pacchetti e la loro compilazione.

* Menu:

* Tutorial sull'Impacchettamento::  Un tutorial su come aggiungere pacchetti
                                      a Guix.
* Packaging Workflows::      Real life examples on working with specific
                               build systems.


File: guix-cookbook.it.info,  Node: Tutorial sull'Impacchettamento,  Next: Packaging Workflows,  Up: Impacchettamento

2.1 Tutorial sull’Impacchettamento
==================================

GNU Guix si distingue come il gestore di pacchetti _hackable_,
principalmente perché utilizza GNU Guile
(https://www.gnu.org/software/guile/), un potente linguaggio di
programmazione di alto livello, uno dei dialetti Scheme
(https://it.wikipedia.org/wiki/Scheme) della famiglia Lisp
(https://it.wikipedia.org/wiki/Lisp).

   Anche le definizioni dei pacchetti sono scritte in Scheme, il che
conferisce a Guix poteri unici, a differenza della maggior parte degli
altri gestori di pacchetti che utilizzano script di shell o linguaggi
semplici.

   • Usa funzioni, strutture, macro e tutta l’espressività di Scheme per
     le tue definizioni di pacchetto.

   • L’ereditarietà rende facile personalizzare un pacchetto ereditando
     da esso e modificando solo ciò che è necessario.

   • Elaborazione batch: l’intera collezione di pacchetti può essere
     analizzata, filtrata ed elaborata. Costruire un server headless con
     tutte le interfacce grafiche rimosse? È possibile. Vuoi ricompilare
     tutto dal sorgente usando flag di ottimizzazione del compilatore
     specifici? Passa l’argomento ‘#:make-flags "..."’ alla lista dei
     pacchetti. Non sarebbe un’esagerazione pensare ai flag USE di
     Gentoo (https://wiki.gentoo.org/wiki/USE_flag) qui, ma questo va
     anche oltre: le modifiche non devono essere pensate in anticipo dal
     manutentore del pacchetto, possono essere _programmed_ dall’utente!

   Il seguente tutorial copre tutte le basi sulla creazione di pacchetti
con Guix. Non presuppone molta conoscenza del sistema Guix né del
linguaggio Lisp. Si presume che il lettore abbia familiarità con la riga
di comando e abbia alcune conoscenze di programmazione di base.

* Menu:

* Un pacchetto "Hello World"::  Un pacchetto "Hello World"
* Configurazione::           Configurazione
* Esempio esteso::           Esempio esteso
* Altri sistemi di build::   Altri sistemi di build
* Definizione di pacchetto programmabile e automatizzata::  Definizione di
                                                              pacchetto
                                                              programmabile e
                                                              automatizzata
* Ottenere aiuto::           Ottenere aiuto
* Conclusione::              Conclusione
* Riferimenti::              Riferimenti


File: guix-cookbook.it.info,  Node: Un pacchetto "Hello World",  Next: Configurazione,  Up: Tutorial sull'Impacchettamento

2.1.1 Un pacchetto "Hello World"
--------------------------------

La sezione "Definire i pacchetti" del manuale introduce le basi
dell’impacchettamento con Guix (*note (guix.it)Definire i pacchetti::).
Nella sezione seguente, ripercorreremo in parte queste basi.

   GNU Hello è un progetto fittizio che serve come esempio idiomatico
per l’impacchettamento. Utilizza il sistema di compilazione GNU
(‘./configure && make && make install’). Guix fornisce già una
definizione di pacchetto che è un esempio perfetto da cui partire. Puoi
consultare la sua dichiarazione con ‘guix edit hello’ dalla riga di
comando. Vediamo come appare:

     (define-public hello
       (package
         (name "hello")
         (version "2.10")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
         (build-system gnu-build-system)
         (synopsis "Ciao, mondo GNU: Un esempio di pacchetto GNU")
         (description
          "GNU Hello stampa il messaggio \"Ciao, mondo!\" e poi esce. Serve come esempio di pratiche di codifica standard GNU. Come tale, supporta argomenti da riga di comando, più lingue, e così via.")
         (home-page "https://www.gnu.org/software/hello/")
         (license gpl3+)))

   Come puoi vedere, la maggior parte è piuttosto semplice. Ma
esaminiamo i campi insieme:

‘name’
     Il nome del progetto. Usando le convenzioni di Scheme, preferiamo
     mantenerlo in minuscolo, senza trattini bassi e usando parole
     separate da trattini.

‘source’
     Questo campo contiene una descrizione dell’origine del codice
     sorgente. Il record ‘origin’ contiene questi campi:

       1. Il metodo, qui ‘url-fetch’ per scaricare via HTTP/FTP, ma
          altri metodi esistono, come ‘git-fetch’ per i repository Git.
       2. L’URI, che è tipicamente una posizione ‘https://’ per
          ‘url-fetch’. Qui lo speciale ‘mirror://gnu‘ si riferisce a un
          insieme di posizioni note, tutte utilizzabili da Guix per
          recuperare il sorgente, nel caso in cui alcune di esse
          fallissero.
       3. La somma di controllo ‘sha256’ del file richiesto. Questo è
          essenziale per garantire che il sorgente non sia corrotto.
          Notare che Guix lavora con stringhe base32, da cui la chiamata
          alla funzione ‘base32’.

‘build-system’

     È qui che il potere di astrazione fornito dal linguaggio Scheme
     brilla davvero: in questo caso, il ‘gnu-build-system’ astrae le
     famose invocazioni di shell ‘./configure && make && make install’.
     Altri sistemi di compilazione includono il ‘trivial-build-system’
     che non fa nulla e richiede al manutentore del pacchetto di
     programmare tutti i passaggi di compilazione, il
     ‘python-build-system’, il ‘emacs-build-system’ e molti altri (*note
     (guix.it)Sistemi di build::).

‘synopsis’
     Dovrebbe essere un riassunto conciso di ciò che fa il pacchetto.
     Per molti pacchetti, uno slogan dalla home page del progetto può
     essere usato come sinossi.

‘description’
     Come per la sinossi, va bene riutilizzare la descrizione del
     progetto dalla homepage. Notare che Guix usa la sintassi Texinfo.

‘home-page’
     Usa HTTPS se disponibile.

‘license’
     Vedere ‘guix/licenses.scm’ nel sorgente del progetto per un elenco
     completo delle licenze disponibili.

   È ora di compilare il nostro primo pacchetto! Niente di speciale per
ora: ci atterremo a un fittizio ‘my-hello’, una copia della
dichiarazione precedente.

   Come per il rituale "Hello World" insegnato con la maggior parte dei
linguaggi di programmazione, questo sarà probabilmente l’approccio più
"manuale". Elaboreremo una configurazione ideale più tardi; per ora
seguiremo la strada più semplice.

   Salva quanto segue in un file ‘my-hello.scm’.

     (use-modules (guix packages)
                  (guix download)
                  (guix build-system gnu)
                  (guix licenses))

     (package
       (name "my-hello")
       (version "2.10")
       (source (origin
                 (method url-fetch)
                 (uri (string-append "mirror://gnu/hello/hello-" version
                                     ".tar.gz"))
                 (sha256
                  (base32
                   "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
       (build-system gnu-build-system)
       (synopsis "Ciao, mondo Guix: Un esempio di pacchetto Guix personalizzato")
       (description
        "GNU Hello stampa il messaggio \"Ciao, mondo!\" e poi esce. Serve
     come esempio delle pratiche di codifica standard di GNU. Come tale, supporta
     argomenti da riga di comando, più linguaggi, e così via.")
       (home-page "https://www.gnu.org/software/hello/")
       (license gpl3+))

   Spiegheremo il codice extra tra un momento.

   Sentiti libero di giocare con i diversi valori dei vari campi. Se
cambi la sorgente, dovrai aggiornare il checksum. Infatti, Guix si
rifiuta di compilare qualsiasi cosa se il checksum fornito non
corrisponde al checksum calcolato del codice sorgente. Per ottenere il
checksum corretto della dichiarazione del pacchetto, dobbiamo scaricare
la sorgente, calcolare il checksum sha256 e convertirlo in base32.

   Fortunatamente, Guix può automatizzare questo compito per noi; tutto
ciò di cui abbiamo bisogno è fornire l’URI:

     $ guix download mirror://gnu/hello/hello-2.10.tar.gz

     Inizio download di /tmp/guix-file.JLYgL7
     Da https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz...
     redirezione a `https://mirror.ibcp.fr/pub/gnu/hello/hello-2.10.tar.gz'...
      …10.tar.gz  709KiB                                 2.5MiB/s 00:00 [##################] 100.0%
     /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
     0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i

   In questo caso specifico l’output ci dice quale mirror è stato
scelto. Se il risultato del comando precedente non è lo stesso dello
snippet sopra, aggiorna di conseguenza la tua dichiarazione ‘my-hello’.

   Nota che i tarball dei pacchetti GNU sono dotati di una firma
OpenPGP, quindi dovresti assolutamente controllare la firma di questo
tarball con ‘gpg‘ per autenticarlo prima di procedere:

     $ guix download mirror://gnu/hello/hello-2.10.tar.gz.sig

     Inizio download di /tmp/guix-file.03tFfb
     Da https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz.sig...
     redirezione a `https://ftp.igh.cnrs.fr/pub/gnu/hello/hello-2.10.tar.gz.sig'. ..
      ….tar.gz.sig  819B                                                                                                                       1.2MiB/s 00:00 [##################] 100.0%
     /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig
     0q0v86n3y38z17rl146gdakw9xc4mcscpk8dscs412j22glrv9jf
     $ gpg --verify /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
     gpg: Firma creata dom 16 nov 2014 13:08:37 CET
     gpg:                usando la chiave RSA A9553245FDE9B739
     gpg: Buona firma da "Sami Kerola <kerolasa@iki.fi>" [sconosciuto]
     gpg:                 alias "Sami Kerola (http://www.iki.fi/kerolasa/) <kerolasa@iki.fi>" [sconosciuto]
     gpg: ATTENZIONE: Questa chiave non è certificata con una firma fidata!
     gpg:          Non c'è alcuna indicazione che la firma appartenga al proprietario.
     Impronta della chiave primaria: 8ED3 96E3 7E38 D471 A005  30D3 A955 3245 FDE9 B739

   Puoi quindi eseguire felicemente

     $ guix package --install-from-file=my-hello.scm

   Ora dovresti avere ‘my-hello’ nel tuo profilo!

     $ guix package --list-installed=my-hello
     my-hello	2.10	out
     /gnu/store/f1db2mfm8syb8qvc357c53slbvf1g9m9-my-hello-2.10

   Siamo andati il più lontano possibile senza alcuna conoscenza di
Scheme. Prima di passare a pacchetti più complessi, ora è il momento
giusto per rispolverare la tua conoscenza di Scheme. *Note Un corso
intensivo di Scheme:: per mettersi al passo.


File: guix-cookbook.it.info,  Node: Configurazione,  Next: Esempio esteso,  Prev: Un pacchetto "Hello World",  Up: Tutorial sull'Impacchettamento

2.1.2 Configurazione
--------------------

Nel resto di questo capitolo faremo affidamento su alcune conoscenze di
base di programmazione in Scheme. Ora analizziamo le diverse possibili
configurazioni per lavorare sui pacchetti Guix.

   Ci sono diversi modi per configurare un ambiente di pacchettizzazione
Guix.

   Ti consigliamo di lavorare direttamente sul checkout del sorgente di
Guix poiché rende più facile per tutti contribuire al progetto.

   Ma prima, diamo un’occhiata ad altre possibilità.

* Menu:

* File locale::              File locale
* Canali::                   Canali
* Modifica diretta dal checkout::  Modifica diretta dal checkout


File: guix-cookbook.it.info,  Node: File locale,  Next: Canali,  Up: Configurazione

2.1.2.1 File locale
...................

Questo è quello che abbiamo fatto in precedenza con ‘my-hello’. Con le
basi di Scheme che abbiamo trattato, siamo ora in grado di spiegare i
blocchi iniziali. Come indicato in ‘guix package --help’:

       -f, --install-from-file=FILE
                              installa il pacchetto a cui il codice all'interno di FILE
                              valuta

   Quindi l’ultima espressione _must_ restituire un pacchetto, che è il
caso del nostro esempio precedente.

   L’espressione ‘use-modules’ indica quali moduli ci servono nel file.
I moduli sono una raccolta di valori e procedure. Sono comunemente
chiamati "librerie" o "pacchetti" in altri linguaggi di programmazione.


File: guix-cookbook.it.info,  Node: Canali,  Next: Modifica diretta dal checkout,  Prev: File locale,  Up: Configurazione

2.1.2.2 Canali
..............

Guix e la sua collezione di pacchetti possono essere estesi tramite
“canali”. Un canale è un repository Git, pubblico o meno, contenente
file ‘.scm’ che forniscono pacchetti (*note (guix.it)Definire i
pacchetti::) o servizi (*note (guix.it)Definire i servizi::).

   Come si crea un canale? Innanzitutto, crea una directory che conterrà
i tuoi file ‘.scm’, diciamo ‘~/my-channel’:

     mkdir ~/my-channel

   Supponiamo che tu voglia aggiungere il pacchetto ‘my-hello’ che
abbiamo visto in precedenza; prima ha bisogno di alcune modifiche:

     (define-module (my-hello)
       #:use-module (guix licenses)
       #:use-module (guix packages)
       #:use-module (guix build-system gnu)
       #:use-module (guix download))

     (define-public my-hello
       (package
         (name "my-hello")
         (version "2.10")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
         (build-system gnu-build-system)
         (synopsis "Ciao, mondo Guix: Un esempio di pacchetto Guix personalizzato")
         (description
          "GNU Hello stampa il messaggio \"Ciao, mondo!\" e poi esce. Serve come esempio delle pratiche di codifica standard di GNU. Come tale, supporta
     argomenti da riga di comando, più linguaggi, e così via.")
         (home-page "https://www.gnu.org/software/hello/")
         (license gpl3+)))

   Nota che abbiamo assegnato il valore del pacchetto a un nome di
variabile esportato con ‘define-public’. Questo assegna effettivamente
il pacchetto alla variabile ‘my-hello’ in modo che possa essere
referenziato, tra l’altro come dipendenza di altri pacchetti.

   Se usi ‘guix package --install-from-file=my-hello.scm’ sul file
precedente, fallirà perché l’ultima espressione, ‘define-public’, non
restituisce un pacchetto. Se vuoi comunque usare ‘define-public’ in
questo caso, assicurati che il file termini con una valutazione di
‘my-hello’:

     ;; ...
     (define-public my-hello
       ;; ...
       )

     my-hello

   Quest’ultimo esempio non è molto tipico.

   Ora come si rende quel pacchetto visibile ai comandi ‘guix’ in modo
da poter testare i pacchetti? È necessario aggiungere la directory al
percorso di ricerca usando l’opzione della riga di comando ‘-L’, come in
questi esempi:

     guix show -L ~/my-channel my-hello
     guix build -L ~/my-channel my-hello

   Il passo finale è trasformare ‘~/my-channel’ in un canale vero e
proprio, rendendo la tua collezione di pacchetti disponibile senza
problemi via qualsiasi comando ‘guix’. Per farlo, devi prima renderlo un
repository Git:

     cd ~/my-channel
     git init
     git add my-hello.scm
     git commit -m "Primo commit del mio canale."

   E questo è tutto, hai un canale! Da qui in poi, puoi aggiungere
questo canale alla configurazione dei tuoi canali in
‘~/.config/guix/channels.scm’ (*note (guix.it)Specificare canali
aggiuntivi::); supponendo che per ora tu mantenga il tuo canale locale,
il file ‘channels.scm’ assomiglierebbe a qualcosa del genere:

     (append (list (channel
                     (name 'my-channel)
                     (url (string-append "file://" (getenv "HOME")
                                         "/my-channel"))))
             %default-channels)

   La prossima volta che eseguirai ‘guix pull’, il tuo canale verrà
rilevato e i pacchetti che definisce saranno prontamente disponibili per
tutti i comandi ‘guix’, anche se non passerai ‘-L’. Il comando ‘guix
describe’ mostrerà che Guix sta, effettivamente, usando sia i canali
‘my-channel’ che ‘guix’.

   *Note (guix.it)Creare un canale::, per i dettagli.


File: guix-cookbook.it.info,  Node: Modifica diretta dal checkout,  Prev: Canali,  Up: Configurazione

2.1.2.3 Modifica diretta dal checkout
.....................................

Lavorare direttamente sul progetto Guix è consigliato: riduce l’attrito
quando arriva il momento di inviare le tue modifiche upstream per far sì
che la comunità benefici del tuo duro lavoro!

   A differenza della maggior parte delle distribuzioni software, il
repository di Guix contiene in un unico posto sia gli strumenti (incluso
il gestore di pacchetti) che le definizioni dei pacchetti. Questa scelta
è stata fatta per dare agli sviluppatori la flessibilità di modificare
l’API senza rotture, aggiornando tutti i pacchetti contemporaneamente.
Ciò riduce l’inerzia dello sviluppo.

   Dai un’occhiata al repository Git (https://git-scm.com/) ufficiale:

     $ git clone https://git.guix.gnu.org/guix.git

   Nel resto di questo articolo, useremo ‘$GUIX_CHECKOUT’ per fare
riferimento alla posizione del checkout.

   Segui le istruzioni nel manuale (*note (guix.it)Contribuire::) per
configurare l’ambiente del repository.

   Una volta pronto, dovresti essere in grado di utilizzare le
definizioni dei pacchetti dall’ambiente del repository.

   Sentiti libero di modificare le definizioni dei pacchetti che si
trovano in ‘$GUIX_CHECKOUT/gnu/packages’.

   Lo script ‘$GUIX_CHECKOUT/pre-inst-env’ ti consente di usare ‘guix’
sulla collezione di pacchetti del repository (*note (guix.it)Eseguire
Guix prima di installarlo::).

   • Cerca pacchetti, come Ruby:

            $ cd $GUIX_CHECKOUT
            $ ./pre-inst-env guix package --list-available=ruby
                ruby    1.8.7-p374      out     gnu/packages/ruby.scm:119:2
                ruby    2.1.6   out     gnu/packages/ruby.scm:91:2
                ruby    2.2.2   out     gnu/packages/ruby.scm:39:2

   • Compila un pacchetto, qui Ruby versione 2.1:

            $ ./pre-inst-env guix build --keep-failed ruby@2.1
            /gnu/store/c13v73jxmj2nir2xjqaz5259zywsa9zi-ruby-2.1.6

   • Installalo nel tuo profilo utente:

            $ ./pre-inst-env guix package --install ruby@2.1

   • Controlla errori comuni:

            $ ./pre-inst-env guix lint ruby@2.1

   Guix si impegna a mantenere uno standard di pacchettizzazione
elevato; quando contribuisci al progetto Guix, ricorda di

   • seguire lo stile di codifica (*note (guix.it)Stile del codice::),
   • e rivedere la lista di controllo dal manuale (*note (guix.it)Invia
     delle patches::).

   Una volta che sei soddisfatto del risultato, sei il benvenuto a
inviare il tuo contributo per renderlo parte di Guix. Questo processo è
anche dettagliato nel manuale. (*note (guix.it)Contribuire::)

   È uno sforzo della comunità, quindi più persone si uniscono, migliore
diventa Guix!


File: guix-cookbook.it.info,  Node: Esempio esteso,  Next: Altri sistemi di build,  Prev: Configurazione,  Up: Tutorial sull'Impacchettamento

2.1.3 Esempio esteso
--------------------

L’esempio "Ciao Mondo" sopra è il più semplice possibile. I pacchetti
possono essere più complessi di così e Guix può gestire scenari più
avanzati. Diamo un’occhiata a un altro pacchetto più sofisticato
(leggermente modificato dalla fonte):

     (define-module (gnu packages version-control)
       #:use-module ((guix licenses) #:prefix license:)
       #:use-module (guix utils)
       #:use-module (guix packages)
       #:use-module (guix git-download)
       #:use-module (guix build-system cmake)
       #:use-module (gnu packages)
       #:use-module (gnu packages compression)
       #:use-module (gnu packages pkg-config)
       #:use-module (gnu packages python)
       #:use-module (gnu packages ssh)
       #:use-module (gnu packages tls)
       #:use-module (gnu packages web))

     (define-public my-libgit2
       (let ((commit "e98d0a37c93574d2c6107bf7f31140b548c6a7bf")
             (revision "1"))
         (package
           (name "my-libgit2")
           (version (git-version "0.26.6" revision commit))
           (source (origin
                     (method git-fetch)
                     (uri (git-reference
                           (url "https://github.com/libgit2/libgit2/")
                           (commit commit)))
                     (file-name (git-file-name name version))
                     (sha256
                      (base32
                       "17pjvprmdrx4h6bb1hhc98w9qi6ki7yl57f090n9kbhswxqfs7s3"))
                     (patches (search-patches "libgit2-mtime-0.patch"))
                     (modules '((guix build utils)))
                     ;; Rimuovi software in bundle.
                     (snippet '(delete-file-recursively "deps"))))
           (build-system cmake-build-system)
           (outputs '("out" "debug"))
           (arguments
            `(#:tests? #true                         ; Esegui la suite di test (questo è il valore predefinito)
              #:configure-flags '("-DUSE_SHA1DC=ON") ; Rilevamento collisioni SHA-1
              #:phases
              (modify-phases %standard-phases
                (add-after 'unpack 'fix-hardcoded-paths
                  (lambda _
                    (substitute* "tests/repo/init.c"
                      (("#!/bin/sh") (string-append "#!" (which "sh"))))
                    (substitute* "tests/clar/fs.h"
                      (("/bin/cp") (which "cp"))
                      (("/bin/rm") (which "rm")))))
                ;; Esegui i controlli in modo più verboso.
                (replace 'check
                  (lambda* (#:key tests? #:allow-other-keys)
                    (when tests?
                      (invoke "./libgit2_clar" "-v" "-Q"))))
                (add-after 'unpack 'make-files-writable-for-tests
                  (lambda _ (for-each make-file-writable (find-files ".")))))))
           (inputs
            (list libssh2 http-parser python-wrapper))
           (native-inputs
            (list pkg-config))
           (propagated-inputs
            ;; Queste due librerie sono in 'Requires.private' in libgit2.pc.
            (list openssl zlib))
           (home-page "https://libgit2.github.com/")
           (synopsis "Libreria che fornisce i metodi core di Git")
           (description
            "Libgit2 è un'implementazione portatile e pura in C dei metodi core di Git
     fornita come libreria rientrante collegabile con una solida API, che consente di
     scrivere applicazioni Git personalizzate a velocità nativa in qualsiasi linguaggio con binding.")
           ;; GPLv2 con eccezione di linking
           (license license:gpl2))))

   (Nei casi in cui si desidera solo modificare alcuni campi da una
definizione di pacchetto, si dovrebbe fare affidamento sull’ereditarietà
invece di copiare e incollare tutto. Vedi sotto.)

   Discutiamo questi campi in dettaglio.

2.1.3.1 Metodo ‘git-fetch’
..........................

A differenza del metodo ‘url-fetch’, ‘git-fetch’ si aspetta un
‘git-reference’ che accetta un repository Git e un commit. Il commit può
essere qualsiasi riferimento Git come i tag, quindi se la ‘version’ è
taggata, allora può essere usata direttamente. A volte il tag è
preceduto da una ‘v’, nel qual caso si userebbe ‘(commit (string-append
"v" version))’.

   Per assicurarsi che il codice sorgente dal repository Git sia
memorizzato in una directory con un nome descrittivo, usiamo ‘(file-name
(git-file-name name version))’.

   La procedura ‘git-version’ può essere usata per derivare la versione
quando si impacchettano programmi per un commit specifico, seguendo le
linee guida per i contributori di Guix (*note (guix.it)Numeri di
versione::).

   Come si ottiene l’hash ‘sha256’ che si trova lì, chiedi? Invocando
‘guix hash’ su un checkout del commit desiderato, in questo modo:

     git clone https://github.com/libgit2/libgit2/
     cd libgit2
     git checkout v0.26.6
     guix hash -rx .

   ‘guix hash -rx’ calcola un hash SHA256 sull’intera directory,
escludendo la sottodirectory ‘.git’ (*note (guix.it)Invocare guix
hash::).

   In futuro, ‘guix download’ sarà, si spera, in grado di eseguire
questi passaggi per te, proprio come fa per i download normali.

2.1.3.2 Frammenti
.................

Gli snippet sono codice Scheme quotato (cioè non valutato) che è un
mezzo per applicare patch al sorgente. Sono un’alternativa in stile Guix
ai tradizionali file ‘.patch’. A causa della quotatura, il codice viene
valutato solo quando passato al demone Guix per la costruzione. Possono
esserci quanti snippet sono necessari.

   Gli snippet potrebbero aver bisogno di moduli Guile aggiuntivi che
possono essere importati dal campo ‘modules’.

2.1.3.3 Input
.............

Ci sono 3 diversi tipi di input. In breve:

native-inputs
     Richiesti per la compilazione ma non per il runtime –
     l’installazione di un pacchetto tramite un sostituto non installerà
     questi input.
inputs
     Installati nello store ma non nel profilo, oltre ad essere presenti
     al momento della compilazione.
propagated-inputs
     Installati nello store e nel profilo, oltre ad essere presenti al
     momento della compilazione.

   *Note (guix.it)Riferimenti per 'package':: per maggiori dettagli.

   La distinzione tra i vari input è importante: se una dipendenza può
essere gestita come un _input_ invece di un _input propagato_, dovrebbe
essere fatto così, altrimenti “inquina” il profilo utente senza una
buona ragione.

   Ad esempio, un utente che installa un programma grafico che dipende
da uno strumento a riga di comando potrebbe essere interessato solo alla
parte grafica, quindi non è necessario forzare lo strumento a riga di
comando nel profilo utente. La dipendenza è una preoccupazione del
pacchetto, non dell’utente. Gli _Inputs_ rendono possibile gestire le
dipendenze senza infastidire l’utente aggiungendo file eseguibili (o
librerie) indesiderati al loro profilo.

   Lo stesso vale per gli _native-inputs_: una volta installato il
programma, le dipendenze di compilazione possono essere tranquillamente
raccolte come spazzatura. È importante anche quando è disponibile un
sostituto, nel qual caso verranno scaricati solo gli _inputs_ e gli
_propagated inputs_: gli _native inputs_ non sono richiesti per
installare un pacchetto da un sostituto.

     Nota: Potresti vedere qua e là snippet in cui gli input dei
     pacchetti sono scritti in modo piuttosto diverso, come questo:

          ;; Il "vecchio stile" per gli input.
          (inputs
           `(("libssh2" ,libssh2)
             ("http-parser" ,http-parser)
             ("python" ,python-wrapper)))

     Questo è il “vecchio stile”, dove a ciascun input nell’elenco viene
     esplicitamente data un’etichetta (una stringa). È ancora supportato
     ma raccomandiamo di usare invece lo stile sopra. *Note
     (guix.it)Riferimenti per 'package'::, per maggiori informazioni.

2.1.3.4 Prodotti
................

Proprio come un pacchetto può avere più input, può anche produrre più
output.

   Ogni output corrisponde a una directory separata nello store.

   L’utente può scegliere quale output installare; questo è utile per
risparmiare spazio o per evitare di inquinare il profilo utente con
eseguibili o librerie indesiderate.

   La separazione dell’output è opzionale. Quando il campo ‘outputs’
viene omesso, l’output predefinito e unico (il pacchetto completo) è
indicato come ‘"out"’.

   I nomi tipici degli output separati includono ‘debug’ e ‘doc’.

   Si consiglia di separare gli output solo quando si è dimostrato che
ne vale la pena: se la dimensione dell’output è significativa
(confrontare con ‘guix size’) o nel caso in cui il pacchetto sia
modulare.

2.1.3.5 Argomenti del sistema di compilazione
.............................................

L’argomento ‘arguments’ è un elenco di coppie chiave-valore utilizzato
per configurare il processo di compilazione.

   L’argomento più semplice ‘#:tests?’ può essere utilizzato per
disabilitare la suite di test durante la compilazione del pacchetto.
Questo è utile soprattutto quando il pacchetto non dispone di alcuna
suite di test. Si consiglia vivamente di mantenere la suite di test
attiva se presente.

   Un altro argomento comune è ‘:make-flags’, che specifica un elenco di
flag da aggiungere quando si esegue make, come si farebbe dalla riga di
comando. Ad esempio, i seguenti flag

     #:make-flags (list (string-append "prefix=" (assoc-ref %outputs "out"))
                        "CC=gcc")

   si traducono in

     $ make CC=gcc prefix=/gnu/store/...-<out>

   Questo imposta il compilatore C a ‘gcc’ e la variabile ‘prefix’ (la
directory di installazione nel linguaggio Make) a ‘(assoc-ref %outputs
"out")’, che è una variabile globale di fase di compilazione che punta
alla directory di destinazione nello store (qualcosa come
‘/gnu/store/...-my-libgit2-20180408’).

   Allo stesso modo, è possibile impostare i flag di configurazione:

     #:configure-flags '("-DUSE_SHA1DC=ON")

   La variabile ‘%build-inputs’ viene anche generata nello scope. È una
tabella di associazione che mappa i nomi degli input alle loro directory
dello store.

   La parola chiave ‘phases’ elenca i passaggi sequenziali del sistema
di compilazione. Tipicamente le fasi includono ‘unpack’, ‘configure’,
‘build’, ‘install’ e ‘check’. Per saperne di più su queste fasi, è
necessario trovare la definizione appropriata del sistema di
compilazione in ‘$GUIX_CHECKOUT/ guix/build/gnu-build-system.scm’:

     (define %standard-phases
       ;; Fasi di compilazione standard, come un elenco di coppie simbolo/procedura.
       (let-syntax ((phases (syntax-rules ()
                              ((_ p ...) `((p . ,p) ...)))))
         (phases set-SOURCE-DATE-EPOCH set-paths install-locale unpack
                 bootstrap
                 patch-usr-bin-file
                 patch-source-shebangs configure patch-generated-file-shebangs
                 build check install
                 patch-shebangs strip
                 validate-runpath
                 validate-documentation-location
                 delete-info-dir-file
                 patch-dot-desktop-files
                 make-dynamic-linker-cache
                 install-license-files
                 reset-gzip-timestamps
                 compress-documentation)))

   O dalla REPL:

     (add-to-load-path "/path/to/guix/checkout")
     ,use (guix build gnu-build-system)
     (map car %standard-phases)
     ⇒ (set-SOURCE-DATE-EPOCH set-paths install-locale unpack bootstrap patch-usr-bin-file patch-source-shebangs configure patch-generated-file-shebangs build check install patch-shebangs strip validate-runpath validate-documentation-location delete-info-dir-file patch-dot-desktop-files make-dynamic-linker-cache install-license-files reset-gzip-timestamps compress-documentation)

   Se vuoi saperne di più su cosa succede durante queste fasi, consulta
le procedure associate.

   Ad esempio, al momento in cui scrivo, la definizione di ‘unpack’ per
il sistema di compilazione GNU è:

     (define* (unpack #:key source #:allow-other-keys)
       "Decomprime SOURCE nella directory di lavoro e cambia directory all'interno del
     sorgente. Quando SOURCE è una directory, copiala in una sottodirectory della
     directory di lavoro corrente."
       (if (file-is-directory? source)
           (begin
             (mkdir "source")
             (chdir "source")

             ;; Preserva i timestamp (impostati sull'Epoch) sull'albero copiato in modo che
             ;; le cose funzionino in modo deterministico.
             (copy-recursively source "."
                               #:keep-mtime? #t)
             ;; Rendi scrivibili i file del checkout sorgente, per comodità.
             (for-each (lambda (f)
                         (false-if-exception (make-file-writable f)))
                       (find-files ".")))
           (begin
             (cond
              ((string-suffix? ".zip" source)
               (invoke "unzip" source))
              ((tarball? source)
               (invoke "tar" "xvf" source))
              (else
               (let ((name (strip-store-file-name source))
                     (command (compressor source)))
                 (copy-file source name)
                 (when command
                   (invoke command "--decompress" name)))))
             ;; Tenta di cambiare nella directory figlia.
             (and=> (first-subdirectory ".") chdir))))

   Nota la chiamata ‘chdir’: cambia la directory di lavoro dove il
sorgente è stato decompresso. Quindi ogni fase successiva a ‘unpack’
userà il sorgente come directory di lavoro, ecco perché possiamo
lavorare direttamente sui file sorgente. Cioè, a meno che una fase
successiva non cambi la directory di lavoro in qualcos’altro.

   Modifichiamo l’elenco di ‘%standard-phases’ del sistema di
compilazione con la macro ‘modify-phases’ secondo l’elenco delle
modifiche specificate, che possono avere le seguenti forme:

   • ‘(add-before PHASE NEW-PHASE PROCEDURE)’: Esegue la PROCEDURE
     denominata NEW-PHASE prima di PHASE.
   • ‘(add-after PHASE NEW-PHASE PROCEDURE)’: Idem, ma dopo.
   • ‘(replace PHASE PROCEDURE)’.
   • ‘(delete PHASE)’.

   La PROCEDURE supporta gli argomenti con parola chiave ‘inputs’ e
‘outputs’. Ogni input (sia _native_, _propagato_ o meno) e la directory
di output sono referenziati dai loro nomi in quelle variabili. Quindi
‘(assoc-ref outputs "out")’ è la directory dello store dell’output
principale del pacchetto. Una procedura di fase può apparire così:

     (lambda* (#:key inputs outputs #:allow-other-keys)
       (let ((bash-directory (assoc-ref inputs "bash"))
             (output-directory (assoc-ref outputs "out"))
             (doc-directory (assoc-ref outputs "doc")))
         ;; ... ))

   Il suo valore di ritorno viene ignorato.

2.1.3.6 Code staging
....................

Il lettore attento potrebbe aver notato la sintassi di quasi-citazione e
virgola nel campo argomento. Infatti, il codice di compilazione nella
dichiarazione del pacchetto non dovrebbe essere valutato lato client, ma
solo quando passato al demone Guix. Questo meccanismo di passaggio di
codice tra due processi in esecuzione è chiamato staging del codice
(https://arxiv.org/abs/1709.00833).

2.1.3.7 Funzioni di utilità
...........................

Quando si personalizzano le ‘phases’, spesso è necessario scrivere
codice che imita le invocazioni di sistema equivalenti (‘make’, ‘mkdir’,
‘cp’, ecc.) comunemente usate durante le normali installazioni in “stile
Unix”.

   Alcune come ‘chmod’ sono native di Guile. *Note (guile):: per un
elenco completo.

   Guix fornisce funzioni helper aggiuntive che si rivelano
particolarmente utili nel contesto della gestione dei pacchetti.

   Alcune di queste funzioni si trovano in
‘$GUIX_CHECKOUT/guix/guix/build/ utils.scm’. La maggior parte di esse
riflette il comportamento dei comandi di sistema Unix tradizionali:

‘which’
     Come il comando di sistema ‘which’.
‘find-files’
     Simile al comando di sistema ‘find’.
‘mkdir-p’
     Come ‘mkdir -p’, che crea tutti i genitori se necessario.
‘install-file’
     Simile a ‘install’ quando si installa un file in una directory
     (possibilmente non esistente). Guile ha ‘copy-file’ che funziona
     come ‘cp’.
‘copy-recursively’
     Come ‘cp -r’.
‘delete-file-recursively’
     Come ‘rm -rf’.
‘invoke’
     Esegui un eseguibile. Questo dovrebbe essere usato al posto di
     ‘system*’.
‘with-directory-excursion’
     Esegui il corpo in una diversa directory di lavoro, quindi
     ripristina la precedente directory di lavoro.
‘substitute*’
     Una funzione “simile a ‘sed’”.

   *Note (guix.it)Utilità di build::, per maggiori informazioni su
queste utilità.

2.1.3.8 Prefisso modulo
.......................

La licenza nel nostro ultimo esempio richiede un prefisso: ciò è dovuto
a come il modulo ‘license’ è stato importato nel pacchetto, come
‘#:use-module ((guix licenses) #:prefix license:)’. Il meccanismo di
importazione dei moduli Guile (*note (guile)Using Guile Modules::) offre
all’utente il controllo completo sulla gestione degli spazi dei nomi:
ciò è necessario per evitare conflitti tra, ad esempio, la variabile
‘zlib’ di ‘licenses.scm’ (un valore di _license_) e la variabile ‘zlib’
di ‘compression.scm’ (un valore di _package_).


File: guix-cookbook.it.info,  Node: Altri sistemi di build,  Next: Definizione di pacchetto programmabile e automatizzata,  Prev: Esempio esteso,  Up: Tutorial sull'Impacchettamento

2.1.4 Altri sistemi di build
----------------------------

Quanto abbiamo visto finora copre la maggior parte dei pacchetti che
utilizzano un sistema di compilazione diverso da ‘trivial-build-system’.
Quest’ultimo non automatizza nulla e ti lascia il compito di compilare
tutto manualmente. Questo può essere più impegnativo e per ora non lo
tratteremo qui, ma fortunatamente è raramente necessario ricorrere a
questo sistema.

   Per gli altri sistemi di compilazione, come ASDF, Emacs, Perl, Ruby e
molti altri, il processo è molto simile al sistema di compilazione GNU,
ad eccezione di alcuni argomenti specializzati.

   *Note (guix.it)Sistemi di build::, per maggiori informazioni sui
sistemi di compilazione, o controlla il codice sorgente nelle directory
‘$GUIX_CHECKOUT/guix/build’ e ‘$GUIX_CHECKOUT/guix/build-system’.


File: guix-cookbook.it.info,  Node: Definizione di pacchetto programmabile e automatizzata,  Next: Ottenere aiuto,  Prev: Altri sistemi di build,  Up: Tutorial sull'Impacchettamento

2.1.5 Definizione di pacchetto programmabile e automatizzata
------------------------------------------------------------

Non possiamo ripeterlo abbastanza: avere un linguaggio di programmazione
completo a portata di mano ci dà potere in modi che vanno ben oltre la
tradizionale gestione dei pacchetti.

   Illustriamo questo con alcune fantastiche funzionalità di Guix!

* Menu:

* Importatori ricorsivi::    Importatori ricorsivi
* Aggiornamento automatico::  Aggiornamento automatico
* Ereditarietà::             Ereditarietà


File: guix-cookbook.it.info,  Node: Importatori ricorsivi,  Next: Aggiornamento automatico,  Up: Definizione di pacchetto programmabile e automatizzata

2.1.5.1 Importatori ricorsivi
.............................

Potresti trovare alcuni sistemi di compilazione così buoni che c’è poco
da fare per scrivere un pacchetto, al punto che diventa ripetitivo e
noioso dopo un po’. Una _ragione d’essere_ dei computer è quella di
sostituire gli esseri umani in questi compiti noiosi. Quindi, diciamo a
Guix di farlo per noi e di creare la definizione di pacchetto di un
pacchetto R da CRAN (l’output è troncato per brevità):

     $ guix import cran --recursive walrus

     (define-public r-mc2d
         ; ...
         (license gpl2+)))

     (define-public r-jmvcore
         ; ...
         (license gpl2+)))

     (define-public r-wrs2
         ; ...
         (license gpl3)))

     (define-public r-walrus
       (package
         (name "r-walrus")
         (version "1.0.3")
         (source
           (origin
             (method url-fetch)
             (uri (cran-uri "walrus" version))
             (sha256
               (base32
                 "1nk2glcvy4hyksl5ipq2mz8jy4fss90hx6cq98m3w96kzjni6jjj"))))
         (build-system r-build-system)
         (propagated-inputs
           (list r-ggplot2 r-jmvcore r-r6 r-wrs2))
         (home-page "https://github.com/jamovi/walrus")
         (synopsis "Metodi Statistici Robusti")
         (description
           "Questo pacchetto fornisce una cassetta degli attrezzi di comuni test statistici robusti,
     inclusi descrittori robusti, t-test robusti e ANOVA robusta.
     È disponibile anche come modulo per 'jamovi' (vedere
     <https://www.jamovi.org> per maggiori informazioni). Walrus si basa sul
     pacchetto WRS2 di Patrick Mair, che a sua volta si basa sugli script e sul
     lavoro di Rand Wilcox. Queste analisi sono descritte in dettaglio nel libro
     'Introduction to Robust Estimation & Hypothesis Testing'.")
         (license gpl3)))

   L’importatore ricorsivo non importerà i pacchetti per i quali Guix ha
già definizioni di pacchetto, ad eccezione del primissimo.

   Non tutte le applicazioni possono essere impacchettate in questo
modo, solo quelle che si basano su un numero selezionato di sistemi
supportati. Leggi l’elenco completo degli importatori nella sezione
import di guix del manuale (*note (guix.it)Invocare guix import::).


File: guix-cookbook.it.info,  Node: Aggiornamento automatico,  Next: Ereditarietà,  Prev: Importatori ricorsivi,  Up: Definizione di pacchetto programmabile e automatizzata

2.1.5.2 Aggiornamento automatico
................................

Guix è abbastanza intelligente da controllare gli aggiornamenti sui
sistemi che conosce. Può segnalare definizioni di pacchetto obsolete con

     $ guix refresh hello

   Nella maggior parte dei casi, l’aggiornamento di un pacchetto a una
versione più recente richiede poco più che la modifica del numero di
versione e del checksum. Guix può farlo anche automaticamente:

     $ guix refresh hello --update


File: guix-cookbook.it.info,  Node: Ereditarietà,  Prev: Aggiornamento automatico,  Up: Definizione di pacchetto programmabile e automatizzata

2.1.5.3 Ereditarietà
....................

Se hai iniziato a sfogliare le definizioni dei pacchetti esistenti,
potresti aver notato che un numero significativo di esse ha un campo
‘inherit’:

     (define-public adwaita-icon-theme
       (package (inherit gnome-icon-theme)
         (name "adwaita-icon-theme")
         (version "3.26.1")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnome/sources/" name "/"
                                       (version-major+minor version) "/"
                                       name "-" version ".tar.xz"))
                   (sha256
                    (base32
                     "17fpahgh5dyckgz7rwqvzgnhx53cx9kr2xw0szprc6bnqy977fi8"))))
         (native-inputs (list `(,gtk+ "bin")))))

   Tutti i campi non specificati sono ereditati dal pacchetto padre.
Questo è molto comodo per creare pacchetti alternativi, ad esempio con
sorgenti, versioni o opzioni di compilazione diverse.


File: guix-cookbook.it.info,  Node: Ottenere aiuto,  Next: Conclusione,  Prev: Definizione di pacchetto programmabile e automatizzata,  Up: Tutorial sull'Impacchettamento

2.1.6 Ottenere aiuto
--------------------

Purtroppo, alcune applicazioni possono essere difficili da
impacchettare. A volte hanno bisogno di una patch per funzionare con la
gerarchia del file system non standard imposta dallo store. A volte i
test non vengono eseguiti correttamente. (Possono essere saltati ma
questo non è raccomandato.) Altre volte il pacchetto risultante non sarà
riproducibile.

   Se dovessi trovarti bloccato, incapace di capire come risolvere
qualsiasi tipo di problema di packaging, non esitare a chiedere aiuto
alla comunità.

   Vedi la homepage di Guix (https://guix.gnu.org/contact/) per
informazioni sulle mailing list, IRC, ecc.


File: guix-cookbook.it.info,  Node: Conclusione,  Next: Riferimenti,  Prev: Ottenere aiuto,  Up: Tutorial sull'Impacchettamento

2.1.7 Conclusione
-----------------

Questo tutorial è stato una vetrina della sofisticata gestione dei
pacchetti di cui Guix si vanta. A questo punto abbiamo in gran parte
limitato questa introduzione al ‘gnu-build-system’ che è un livello di
astrazione fondamentale su cui si basano astrazioni più avanzate.

   Da dove proseguiamo? Successivamente dovremmo dissezionare le viscere
del sistema di compilazione rimuovendo tutte le astrazioni, usando il
‘trivial-build-system’: questo dovrebbe darci una comprensione
approfondita del processo prima di indagare su alcune tecniche di
packaging più avanzate e casi limite.

   Altre funzionalità degne di esplorazione sono le capacità di editing
e debugging interattivi di Guix fornite dal Guile REPL.

   Queste fantasiose funzionalità sono completamente opzionali e possono
aspettare; ora è un buon momento per prendersi una meritata pausa. Con
quanto abbiamo introdotto qui dovresti essere ben attrezzato per
impacchettare molti programmi. Puoi iniziare subito e speriamo di vedere
i tuoi contributi presto!


File: guix-cookbook.it.info,  Node: Riferimenti,  Prev: Conclusione,  Up: Tutorial sull'Impacchettamento

2.1.8 Riferimenti
-----------------

   • La reference del pacchetto nel manuale
     (https://guix.gnu.org/manual/devel/it/html_node/Definire-i-pacchetti.html)

   • la guida di hacking di Pjotr a GNU Guix
     (https://gitlab.com/pjotrp/guix-notes/blob/master/HACKING.org)

   • “GNU Guix: Package without a scheme!”
     (https://guix.gnu.org/guix-ghm-andreas-20130823.pdf), di Andreas
     Enge


File: guix-cookbook.it.info,  Node: Packaging Workflows,  Prev: Tutorial sull'Impacchettamento,  Up: Impacchettamento

2.2 Packaging Workflows
=======================

The following sections provide real-life examples on working with
specific build systems, serving as extensions to the concise packaging
guidelines (*note (guix)Packaging Guidelines::).

* Menu:

* Packaging Rust Crates::    Packaging Rust Crates


File: guix-cookbook.it.info,  Node: Packaging Rust Crates,  Up: Packaging Workflows

2.2.1 Packaging Rust Crates
---------------------------

In preparation, add the following packages to our environment:

     $ guix shell rust rust:cargo cargo-audit cargo-license

* Menu:

* Common Workflow for Rust Packaging::  Common Workflow for Rust Packaging
* Cargo Workspaces and Development Snapshots::  Cargo Workspaces and
                                                  Development Snapshots
* Using Rust Libraries in Other Build Systems::  Using Rust Libraries in
                                                   Other Build Systems


File: guix-cookbook.it.info,  Node: Common Workflow for Rust Packaging,  Next: Cargo Workspaces and Development Snapshots,  Up: Packaging Rust Crates

2.2.1.1 Common Workflow for Rust Packaging
..........................................

In this example, we’ll package ‘cargo-audit’, which is published on the
crates.io (https://crates.io) Rust package repository. All its
dependencies are on crates.io as well.

  1. Since ‘cargo-audit’ is available on crates.io, we can generate a
     template via the crates.io importer (*note (guix)Invoking guix
     import::):

          $ guix import crate cargo-audit

     After manual editing, we’ll have the following definiton:

          (define-public cargo-audit
            (package
              (name "cargo-audit")
              (version "0.21.2")
              (source
               (origin
                 (method url-fetch)
                 (uri (crate-uri "cargo-audit" version))
                 (file-name (string-append name "-" version ".tar.gz"))
                 (sha256
                  (base32 "1a00yqpckkw86zh2hg7ra82c5fx0ird5766dyynimbvqiwg2ps0n"))))
              (build-system cargo-build-system)
              (arguments (list #:install-source? #f))
              (inputs (cargo-inputs 'cargo-audit))
              (home-page "https://rustsec.org/")
              (synopsis "Audit Cargo.lock for crates with security vulnerabilities")
              (description
               "This package provides a Cargo subcommand, @command{cargo audit}, to
          audit @file{Cargo.lock} for crates with security vulnerabilities.")
              (license (list license:asl2.0 license:expat))))

     The identifier used to invoke ‘cargo-inputs’, in this case
     ‘'cargo-audit’, must be unique, usually matching the variable name
     of the package.

  2. Unpack package source and navigate to the unpacked directory, then
     run the following commands:

          $ cargo generate-lockfile
          $ cargo audit
          $ cargo license

     ‘cargo generate-lockfile’ updates dependencies to compatible
     versions. Applying it to all Rust applications helps reduce a great
     number of Rust libraries we need to check later. Although sometimes
     libraries may fail to follow the semantic versioning
     (https://semver.org/) scheme, it’s still acceptable.

     ‘cargo audit’ checks known vulnerabilities and ‘cargo license’
     checks licenses, for all the dependencies. We must have an
     acceptable output of ‘cargo audit’ and ensure all dependencies are
     licensed with our supported licenses (*note (guix)Defining
     Packages::).

  3. Import dependencies from the generated lockfile:

          $ guix import --insert=gnu/packages/rust-crates.scm \
                crate --lockfile=/path/to/Cargo.lock cargo-audit

          # Or use short options, in this case the shell processes file names
          # before passing them to Guix, allowing tilde expansion, for example.
          $ guix import -i gnu/packages/rust-crates.scm \
                crate -f /path/to/Cargo.lock cargo-audit

     ‘cargo-audit’ here must be consistent with the identifier used for
     ‘cargo-inputs’ invocation in the package definition.

     At this stage, the package ‘cargo-audit’ is buildable.

  4. Finally we’ll unbundle the vendored dependencies. The lockfile
     importer inserts ‘TODO REVIEW:’ comments for libraries with high
     probability of bundled dependencies. ‘cargo-build-system’ also
     performs additional check for binary files in its
     ‘check-for-pregenerated-files’ phase, which usually indicates
     bundling:

          $ ./pre-inst-env guix build cargo-audit
          ...
          starting phase `check-for-pregenerated-files'
          Searching for binary files...
          ./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/dictionary-rust
          ./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/dictionary-rust-other
          ./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/lib.rs.zst
          ./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/long-window-size-lib.rs.zst
          ./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_aclui.a
          ./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_activeds.a
          ./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_asycfilt.a
          ./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_amsi.a
          ...

     Although Rust libraries are not publicly exported, we can still
     select them via the Guix command-line interface via a Guile
     expression:

          $ guix build --expression='(@@ (gnu packages rust-crates) rust-ring-0.17.14)'

     To unbundle most dependencies, a snippet is sufficient:

          (define rust-curl-sys-0.4.80+curl-8.12.1
            (crate-source "curl-sys" "0.4.80+curl-8.12.1"
                          "0d7ppx4kq77hc5nyff6jydmfabpgd0i3ppjvn8x0q833mhpdzxsm"
                          #:snippet '(delete-file-recursively "curl")))

          (define rust-bzip2-sys-0.1.13+1.0.8
            (crate-source "bzip2-sys" "0.1.13+1.0.8"
                          "056c39pgjh4272bdslv445f5ry64xvb0f7nph3z7860ln8rzynr2"
                          #:snippet
                          '(begin
                             (delete-file-recursively "bzip2-1.0.8")
                             (delete-file "build.rs")
                             (with-output-to-file "build.rs"
                               (lambda _
                                 (format #t "fn main() {~@
                                  println!(\"cargo:rustc-link-lib=bz2\");~@
                                  }~%"))))))

     In a more complex case, where unbundling one dependency requires a
     build process that involves other packages, we should make a full
     package in ‘(gnu packages rust-sources)’ first and reference it in
     the imported definition.

     For example, we have defined a ‘rust-ring-0.17’ in ‘(gnu packages
     rust-sources)’, then the imported definition in ‘(gnu packages
     rust-crates)’ should be modified to reference it.

          (define rust-ring-0.17.14 rust-ring-0.17)

     When one dependency can be safely removed, modify it to ‘#f’.

          (define rust-openssl-src-300.4.2+3.4.1 #f)

     To facilitate various tasks in the common workflow, several scripts
     are provided in the ‘etc/teams/rust’ directory of Guix source tree.


File: guix-cookbook.it.info,  Node: Cargo Workspaces and Development Snapshots,  Next: Using Rust Libraries in Other Build Systems,  Prev: Common Workflow for Rust Packaging,  Up: Packaging Rust Crates

2.2.1.2 Cargo Workspaces and Development Snapshots
..................................................

In this example, we’ll package ‘niri’, which depends on development
snapshots (also Cargo workspaces here).

   As we can’t ensure compatibility of a development snapshot, before
executing ‘cargo generate-lockfile’, we should modify ‘Cargo.toml’ to
pin it to a known working revision.

   To use our packaged development snapshots, it’s also necessary to
modify ‘Cargo.toml’ in a build phase, with a package-specific
substitution pattern.

     (define-public niri
       (package
        (name "niri")
        (version "25.02")
        (source (origin
                  (method git-fetch)
                  (uri (git-reference
                        (url "https://github.com/YaLTeR/niri")
                        (commit (string-append "v" version))))
                  (file-name (git-file-name name version))
                  (sha256
                   (base32
                    "0vzskaalcz6pcml687n54adjddzgf5r07gggc4fhfsa08h1wfd4r"))))
        (build-system cargo-build-system)
        (arguments
         (list #:install-source? #f
               #:phases
               #~(modify-phases %standard-phases
                   (add-after 'unpack 'use-guix-vendored-dependencies
                     (lambda _
                       (substitute* "Cargo.toml"
                         (("# version =.*")
                          "version = \"*\"")
                         (("git.*optional")
                          "version = \"*\", optional")
                         (("^git = .*")
                          "")))))))
        (native-inputs
         (list pkg-config))
        (inputs
         (cons* clang
                libdisplay-info
                libinput-minimal
                libseat
                libxkbcommon
                mesa
                pango
                pipewire
                wayland
                (cargo-inputs 'niri)))
        (home-page "https://github.com/YaLTeR/niri")
        (synopsis "Scrollable-tiling Wayland compositor")
        (description
         "Niri is a scrollable-tiling Wayland compositor which arranges windows in a
     scrollable format.  It is considered stable for daily use and performs most
     functions expected of a Wayland compositor.")
        (license license:gpl3+)))

   ‘niri’ has Cargo workspace dependencies. When packaging a Cargo
workspace dependency, parameter ‘#:cargo-package-crates’ is required.

     (define-public rust-pipewire-0.8.0.fd3d8f7
       (let ((commit "fd3d8f7861a29c2eeaa4c393402e013578bb36d9")
             (revision "0"))
         (package
           (name "rust-pipewire")
           (version (git-version "0.8.0" revision commit))
           (source
            (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://gitlab.freedesktop.org/pipewire/pipewire-rs.git")
                    (commit commit)))
              (file-name (git-file-name name version))
              (sha256
               (base32 "1hzyhz7xg0mz8a5y9j6yil513p1m610q3j9pzf6q55vdh5mcn79v"))))
           (build-system cargo-build-system)
           (arguments
            (list #:skip-build? #t
                  #:cargo-package-crates
                  ''("libspa-sys" "libspa" "pipewire-sys" "pipewire")))
           (inputs (cargo-inputs 'rust-pipewire-0.8.0.fd3d8f7))
           (home-page "https://pipewire.org/")
           (synopsis "Rust bindings for PipeWire")
           (description "This package provides Rust bindings for PipeWire.")
           (license license:expat))))

   Don’t forget to modify all workspace members in ‘(gnu packages
rust-crates)’:

     (define rust-pipewire-0.8.0.fd3d8f7 package:rust-pipewire-0.8.0.fd3d8f7)
     (define rust-pipewire-sys-0.8.0.fd3d8f7 package:rust-pipewire-0.8.0.fd3d8f7)
     ...
     (define rust-libspa-0.8.0.fd3d8f7 package:rust-pipewire-0.8.0.fd3d8f7)
     (define rust-libspa-sys-0.8.0.fd3d8f7 package:rust-pipewire-0.8.0.fd3d8f7)


File: guix-cookbook.it.info,  Node: Using Rust Libraries in Other Build Systems,  Prev: Cargo Workspaces and Development Snapshots,  Up: Packaging Rust Crates

2.2.1.3 Using Rust Libraries in Other Build Systems
...................................................

In this example, we’ll package ‘libchewing’, which combines two build
systems.

   When building Rust packages in other build systems, we need to add
‘rust’, and ‘rust:cargo’ to ‘native-inputs’, import and use modules from
both build systems, and apply necessary build phases from
‘cargo-build-system’.

   For cross-compilation support, we’ll also add ‘rust-sysroot’ created
with ‘(make-rust-sysroot (%current-target-system))’ to ‘native-inputs’,
and set ‘#:cargo-target’ for ‘cargo-build-system’’s build phases.

     (define-public libchewing
       (package
         (name "libchewing")
         (version "0.9.1")
         (source
          (origin
            (method git-fetch)
            (uri (git-reference
                  (url "https://github.com/chewing/libchewing")
                  (commit (string-append "v" version))))
            (file-name (git-file-name name version))
            (sha256
             (base32 "0gh64wvrk5pn0fhmpvj1j99d5g7f7697rk96zbkc8l72yjr819z5"))))
         (build-system cmake-build-system)
         (arguments
          (list #:imported-modules
                (append %cmake-build-system-modules
                        %cargo-build-system-modules)
                #:modules
                '(((guix build cargo-build-system) #:prefix cargo:)
                  (guix build cmake-build-system)
                  (guix build utils))
                #:phases
                #~(modify-phases %standard-phases
                    (add-after 'unpack 'prepare-cargo-build-system
                      (lambda args
                        (for-each
                         (lambda (phase)
                           (format #t "Running cargo phase: ~a~%" phase)
                           (apply (assoc-ref cargo:%standard-phases phase)
                                  ;; For cross-compilation.
                                  #:cargo-target #$(cargo-triplet)
                                  args))
                         '(unpack-rust-crates
                           configure
                           check-for-pregenerated-files
                           patch-cargo-checksums)))))))
         (native-inputs
          (append
           (list rust `(,rust "cargo") )
           ;; For cross-compilation.
           (or (and=> (%current-target-system)
                      (compose list make-rust-sysroot))
               '())))
         (inputs
          (cons* corrosion ncurses sqlite (cargo-inputs 'libchewing)))
         (synopsis "Chinese phonetic input method")
         (description "Chewing is an intelligent phonetic (Zhuyin/Bopomofo) input
     method, one of the most popular choices for Traditional Chinese users.")
         (home-page "https://chewing.im/")
         (license license:lgpl2.1+)))


File: guix-cookbook.it.info,  Node: Configurazione di sistema,  Next: Contenitori,  Prev: Impacchettamento,  Up: Top

3 Configurazione di sistema
***************************

Guix offre un linguaggio flessibile per configurare dichiarativamente il
tuo sistema Guix. Questa flessibilità può a volte essere eccessiva. Lo
scopo di questo capitolo è dimostrare alcuni concetti avanzati di
configurazione.

   *note (guix.it)Configurazione di sistema:: per un riferimento
completo.

* Menu:

* Accesso automatico a una TTY specifica::  Accedere automaticamente un
                                              utente a una TTY specifica
* Personalizzazione del kernel::  Creazione e utilizzo di un kernel Linux
                                    personalizzato su Guix System.
* API immagine di Sistema Guix::  Personalizzazione di immagini per
                                    piattaforme specifiche.
* Utilizzo di chiavi di sicurezza::  Come usare le chiavi di sicurezza con
                                       Guix System.
* Processo mcron per DNS dinamico::  Processo per aggiornare l’indirizzo IP
                                       dietro un nome host DuckDNS.
* Connessione a una VPN Wireguard::  Connessione a una VPN Wireguard.
* Personalizzazione di un Window Manager::  Gestire la personalizzazione di
                                              un Window Manager su Guix
                                              System.
* Eseguire Guix su un Server Linode::  Eseguire Guix su un Server Linode.
* Eseguire Guix su un Server Kimsufi::  Eseguire Guix su un Server Kimsufi.
* Configurazione di un bind mount::  Configurazione di un bind mount nella
                                       definizione dei file system.
* Ottenere sostituti da Tor::  Configurazione del demone Guix per ottenere
                                 sostituti tramite Tor.
* Configurazione di NGINX con Lua::  Configurazione del server web NGINX per
                                       caricare i moduli Lua.
* Server musicale con audio Bluetooth::  Lettore musicale headless con
                                           uscita Bluetooth.


File: guix-cookbook.it.info,  Node: Accesso automatico a una TTY specifica,  Next: Personalizzazione del kernel,  Up: Configurazione di sistema

3.1 Accesso automatico a una TTY specifica
==========================================

Mentre il manuale di Guix spiega l’auto-login di un utente su _tutte_ le
TTY (*note (guix.it)auto-login to TTY::), alcuni potrebbero preferire
una situazione in cui un utente è loggato su una TTY con le altre TTY
configurate per accedere a utenti diversi o a nessuno. Si noti che si
può auto-loggare un utente su qualsiasi TTY, ma di solito è
consigliabile evitare ‘tty1’, che, per impostazione predefinita, viene
utilizzata per registrare avvisi ed errori.

   Ecco come si potrebbe impostare l’accesso automatico per un utente a
una tty:

     (define (auto-login-to-tty config tty user)
       (if (string=? tty (mingetty-configuration-tty config))
             (mingetty-configuration
              (inherit config)
              (auto-login user))
             config))

     (define %my-services
       (modify-services %base-services
         ;; ...
         (mingetty-service-type config =>
                                (auto-login-to-tty
                                 config "tty3" "alice"))))

     (operating-system
       ;; ...
       (services %my-services))

   Si potrebbe anche ‘compose’ (*note (guile)Higher-Order Functions::)
‘auto-login-to-tty’ per accedere a più utenti su più tty.

   Infine, ecco una nota di cautela. Impostare l’auto-login su una TTY
significa che chiunque può accendere il tuo computer ed eseguire comandi
come il tuo utente regolare. Tuttavia, se hai una partizione root
crittografata, e quindi hai già bisogno di inserire una passphrase
all’avvio del sistema, l’auto-login potrebbe essere un’ opzione comoda.


File: guix-cookbook.it.info,  Node: Personalizzazione del kernel,  Next: API immagine di Sistema Guix,  Prev: Accesso automatico a una TTY specifica,  Up: Configurazione di sistema

3.2 Personalizzazione del kernel
================================

Guix è, al suo interno, una distribuzione basata su sorgente con
sostituti (*note (guix.it)Sostituti::), e come tale la compilazione di
pacchetti dal loro codice sorgente è una parte prevista delle normali
installazioni e aggiornamenti di pacchetti. Dato questo punto di
partenza, ha senso che siano fatti sforzi per ridurre il tempo impiegato
nella compilazione dei pacchetti, e i recenti cambiamenti e
aggiornamenti alla costruzione e distribuzione dei sostituti continuano
ad essere un argomento di discussione all’interno di Guix.

   Il kernel, pur non richiedendo un’eccessiva quantità di RAM per la
compilazione, impiega un tempo piuttosto lungo su una macchina media. La
configurazione ufficiale del kernel, come accade con molte distribuzioni
GNU/Linux, tende all’inclusività, ed è proprio questo che fa sì che la
compilazione richieda così tanto tempo quando il kernel viene compilato
dal sorgente.

   Il kernel Linux, tuttavia, può anche essere semplicemente descritto
come un normale vecchio pacchetto, e come tale può essere personalizzato
proprio come qualsiasi altro pacchetto. La procedura è leggermente
diversa, anche se ciò è dovuto principalmente alla natura di come è
scritta la definizione del pacchetto.

   La definizione del pacchetto kernel ‘linux-libre’ è in realtà una
procedura che crea un pacchetto.

     (define* (make-linux-libre* version gnu-revision source supported-systems
                                 #:key
                                 (extra-version #f)
                                 ;; Una funzione che accetta un'architettura e una variante.
                                 ;; Vedi kernel-config per un esempio.
                                 (configuration-file #f)
                                 (defconfig "defconfig")
                                 (extra-options (default-extra-linux-options version)))
       ...)

   L’attuale pacchetto ‘linux-libre’ è per la serie 5.15.x, ed è
dichiarato così:

     (define-public linux-libre-5.15
       (make-linux-libre* linux-libre-5.15-version
                          linux-libre-5.15-gnu-revision
                          linux-libre-5.15-source
                          '("x86_64-linux" "i686-linux" "armhf-linux"
                            "aarch64-linux" "riscv64-linux")
                          #:configuration-file kernel-config))

   Qualsiasi chiave a cui non sono stati assegnati valori eredita il
loro valore predefinito dalla definizione ‘make-linux-libre’.
Confrontando i due snippet sopra, nota il commento al codice che si
riferisce a ‘#:configuration-file’. A causa di ciò, non è effettivamente
facile includere una configurazione personalizzata del kernel dalla
definizione, ma non preoccuparti, ci sono altri modi per lavorare con
ciò che abbiamo.

   Ci sono due modi per creare un kernel con una configurazione kernel
personalizzata. Il primo è fornire un ‘defconfig’ standard alla
procedura ‘customize-linux’. Per produrre tale file è necessario
ottenere il codice sorgente Linux, creare un file ‘.config’ (usando il
comando ‘make menuconfig’, ad esempio) o fornirne uno che già si
possiede. Dopodiché sarà necessario eseguire il comando ‘make
savedefconfig’ all’interno dell’albero sorgente del kernel — questo
produrrà il file ‘defconfig’ che useremo per compilare un kernel
personalizzato.

   Di seguito è riportato un esempio di pacchetto kernel.

     (define-public my-linux-libre
       (package
         (inherit (customize-linux
                   #:linux linux-libre
                   #:defconfig
                   (local-file "defconfig")))
         (name "my-linux-libre")))

   Nella stessa directory del file che definisce ‘my-linux-libre’ c’è un
file chiamato ‘defconfig’. In questo modo puoi fornire le opzioni del
kernel che desideri nel kernel risultante.

   Il secondo modo per creare un kernel personalizzato è passare un
nuovo valore alla parola chiave ‘extra-options’ della procedura
‘make-linux-libre’. La parola chiave ‘extra-options’ funziona con
un’altra funzione definita subito sotto:

     (define (default-extra-linux-options version)
       `(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html
        ("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #true)
        ;; Moduli richiesti per initrd:
        ("CONFIG_NET_9P" . m)
        ("CONFIG_NET_9P_VIRTIO" . m)
        ("CONFIG_VIRTIO_BLK" . m)
        ("CONFIG_VIRTIO_NET" . m)
        ("CONFIG_VIRTIO_PCI" . m)
        ("CONFIG_VIRTIO_BALLOON" . m)
        ("CONFIG_VIRTIO_MMIO" . m)
        ("CONFIG_FUSE_FS" . m)
        ("CONFIG_CIFS" . m)
        ("CONFIG_9P_FS" . m)))

     (define (config->string options)
       (string-join (map (match-lambda
                           ((option . 'm)
                            (string-append option "=m"))
                           ((option . #true)
                            (string-append option "=y"))
                           ((option . #false)
                            (string-append option "=n")))
                         options)
                    "\n"))

   E nello script di configurazione personalizzato del pacchetto
‘make-linux-libre‘:

     ;; L'aggiunta funziona anche se l'opzione non era presente nel
     ;; file. L'ultima prevale se duplicata.
     (let ((port (open-file ".config" "a"))
           (extra-configuration ,(config->string extra-options)))
       (display extra-configuration port)
       (close-port port))

     (invoke "make" "oldconfig")

   Quindi, non fornendo un file di configurazione, il ‘.config’ inizia
vuoto, e poi ci scriviamo la raccolta di flag che vogliamo. Ecco un
altro kernel personalizzato:

     (define %macbook41-full-config
       (append %macbook41-config-options
               %file-systems
               %efi-support
               %emulation
               ((@@ (gnu packages linux) default-extra-linux-options) version)))

     (define-public linux-libre-macbook41
       ;; XXX: Accedere alla procedura interna 'make-linux-libre*', che è
       ;; privata e non esportata, e soggetta a modifiche future.
       ((@@ (gnu packages linux) make-linux-libre*)
        (@@ (gnu packages linux) linux-libre-version)
        (@@ (gnu packages linux) linux-libre-gnu-revision)
        (@@ (gnu packages linux) linux-libre-source)
        '("x86_64-linux")
        #:extra-version "macbook41"
        #:extra-options %macbook41-config-options))

   Nell’esempio precedente ‘%file-systems’ è una raccolta di flag che
abilitano il supporto di diversi file system, ‘%efi-support’ abilita il
supporto EFI e ‘%emulation’ abilita una macchina x86_64-linux a operare
anche in modalità 32 bit. La procedura ‘default-extra-linux-options’ è
quella definita sopra, che è stata usata per evitare di perdere le
opzioni di configurazione predefinite della parola chiave
‘extra-options’.

   Tutto questo sembra fattibile, ma come si fa a sapere quali moduli
sono richiesti per un sistema particolare? Due posti che possono essere
utili nel tentativo di rispondere a questa domanda sono il Manuale
Gentoo (https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel)
e la documentazione del kernel stesso
(https://www.kernel.org/doc/html/latest/admin-guide/README.html?highlight=localmodconfig).
Dalla documentazione del kernel, sembra che ‘make localmodconfig’ sia il
comando che vogliamo.

   Per poter effettivamente eseguire ‘make localmodconfig’, dobbiamo
prima ottenere e decomprimere il codice sorgente del kernel:

     tar xf $(guix build linux-libre --source)

   Una volta all’interno della directory contenente il codice sorgente,
esegui ‘touch .config’ per creare un file ‘.config’ iniziale e vuoto con
cui iniziare. ‘make localmodconfig’ funziona controllando ciò che hai
già in ‘.config’ e facendoti sapere cosa ti manca. Se il file è vuoto,
ti manca tutto. Il passo successivo è eseguire:

     guix shell -D linux-libre -- make localmodconfig

   e annota l’output. Si noti che il file ‘.config’ è ancora vuoto.
L’output generalmente contiene due tipi di avvisi. I primi iniziano con
"WARNING" e possono essere ignorati nel nostro caso. I secondi recitano:

     il modulo pcspkr non aveva configurazioni CONFIG_INPUT_PCSPKR

   Per ciascuna di queste righe, copia la porzione ‘CONFIG_XXXX_XXXX’
nel ‘.config’ nella directory, e aggiungi ‘=m’, così alla fine appare
così:

     CONFIG_INPUT_PCSPKR=m
     CONFIG_VIRTIO=m

   Dopo aver copiato tutte le opzioni di configurazione, esegui di nuovo
‘make localmodconfig’ per assicurarti di non avere output che iniziano
con “module”. Dopo tutti questi moduli specifici della macchina, ne
rimangono un paio che sono anche necessari. ‘CONFIG_MODULES’ è
necessario affinché tu possa compilare e caricare i moduli separatamente
e non avere tutto compilato nel kernel. ‘CONFIG_BLK_DEV_SD’ è richiesto
per la lettura da dischi rigidi. È possibile che tu abbia bisogno di
altri moduli.

   Questo post non intende tuttavia essere una guida alla configurazione
del proprio kernel, quindi se decidi di compilare un kernel
personalizzato dovrai cercare altre guide per creare un kernel adatto
alle tue esigenze.

   Il secondo modo per configurare il kernel sfrutta maggiormente le
funzionalità di Guix e consente di condividere segmenti di
configurazione tra kernel diversi. Ad esempio, tutte le macchine che
usano EFI per l’avvio hanno una serie di flag di configurazione EFI di
cui hanno bisogno. È probabile che tutti i kernel condividano un elenco
di file system da supportare. Usando le variabili è più facile vedere a
colpo d’occhio quali funzionalità sono abilitate e assicurarsi di non
avere funzionalità in un kernel ma mancanti in un altro.

   Rimane tuttavia non discusso il sistema initrd di Guix e la sua
personalizzazione. È probabile che sia necessario modificare l’initrd su
una macchina che utilizza un kernel personalizzato, poiché alcuni moduli
che ci si aspetta siano compilati potrebbero non essere disponibili per
l’inclusione nell’initrd.


File: guix-cookbook.it.info,  Node: API immagine di Sistema Guix,  Next: Utilizzo di chiavi di sicurezza,  Prev: Personalizzazione del kernel,  Up: Configurazione di sistema

3.3 API immagine di Sistema Guix
================================

Storicamente, Guix System è incentrato su una struttura
‘operating-system’. Questa struttura contiene vari campi che vanno dal
bootloader e dalla dichiarazione del kernel ai servizi da installare.

   A seconda della macchina di destinazione, che può variare da una
macchina ‘x86_64’ standard a un piccolo computer a scheda singola ARM
come la Pine64, i vincoli dell’immagine possono variare molto. I
produttori di hardware imporranno diversi formati di immagine con varie
dimensioni e offset delle partizioni.

   Per creare immagini adatte a tutte quelle macchine, è necessaria una
nuova astrazione: questo è l’obiettivo del record ‘image’. Questo record
contiene tutte le informazioni necessarie per essere trasformate in
un’immagine standalone, che può essere avviata direttamente su qualsiasi
macchina di destinazione.

     (define-record-type* <image>
       image make-image
       image?
       (name               image-name ;simbolo
                           (default #f))
       (format             image-format) ;simbolo
       (target             image-target
                           (default #f))
       (size               image-size  ;dimensione in byte come intero
                           (default 'guess))
       (operating-system   image-operating-system  ;<operating-system>
                           (default #f))
       (partitions         image-partitions ;lista di <partition>
                           (default '()))
       (compression?       image-compression? ;booleano
                           (default #t))
       (volatile-root?     image-volatile-root? ;booleano
                           (default #t))
       (substitutable?     image-substitutable? ;booleano
                           (default #t)))

   Questo record contiene il sistema operativo da istanziare. Il campo
‘format’ definisce il tipo di immagine e può essere ‘efi-raw’, ‘qcow2’ o
‘iso9660’ per esempio. In futuro, potrebbe essere esteso a ‘docker’ o
altri tipi di immagine.

   Una nuova directory nelle fonti Guix è dedicata alla definizione
delle immagini. Per ora ci sono quattro file:

   • ‘gnu/system/images/hurd.scm’
   • ‘gnu/system/images/pine64.scm’
   • ‘gnu/system/images/novena.scm’
   • ‘gnu/system/images/pinebook-pro.scm’

   Diamo un’occhiata a ‘pine64.scm’. Contiene la variabile
‘pine64-barebones-os’ che è una definizione minima di un sistema
operativo dedicata alla scheda Pine A64 LTS.

     (define pine64-barebones-os
       (operating-system
        (host-name "vignemale")
        (timezone "Europe/Paris")
        (locale "en_US.utf8")
        (bootloader (bootloader-configuration
                     (bootloader u-boot-pine64-lts-bootloader)
                     (targets '("/dev/vda"))))
        (initrd-modules '())
        (kernel linux-libre-arm64-generic)
        (file-systems (cons (file-system
                             (device (file-system-label "my-root"))
                             (mount-point "/")
                             (type "ext4"))
                            %base-file-systems))
        (services (cons (service agetty-service-type
                                 (agetty-configuration
                                  (extra-options '("-L")) ; nessun rilevamento portante
                                  (baud-rate "115200")
                                  (term "vt100")
                                  (tty "ttyS0")))
                        %base-services))))

   I campi ‘kernel’ e ‘bootloader’ puntano a pacchetti dedicati a questa
scheda.

   Subito sotto, è definita anche la variabile ‘pine64-image-type’.

     (define pine64-image-type
       (image-type
        (name 'pine64-raw)
        (constructor (cut image-with-os arm64-disk-image <>))))

   Sta usando un record di cui non abbiamo ancora parlato, il record
‘image-type’, definito in questo modo:

     (define-record-type* <image-type>
       image-type make-image-type
       image-type?
       (name           image-type-name) ;simbolo
       (constructor    image-type-constructor)) ;<operating-system> -> <image>

   Lo scopo principale di questo record è associare un nome a una
procedura che trasforma un ‘operating-system’ in un’immagine. Per capire
perché è necessario, diamo un’occhiata al comando che produce
un’immagine da un file di configurazione ‘operating-system’:

     guix system image my-os.scm

   Questo comando si aspetta una configurazione ‘operating-system’ ma
come dovremmo indicare che vogliamo un’immagine destinata a una scheda
Pine64? Dobbiamo fornire un’informazione extra, il ‘image-type’,
passando il flag ‘--image-type’ o ‘-t’, in questo modo:

     guix system image --image-type=pine64-raw my-os.scm

   Questo parametro ‘image-type’ punta al ‘pine64-image-type’ definito
sopra. Quindi, il ‘operating-system’ dichiarato in ‘my-os.scm’ verrà
applicato alla procedura ‘(cut image-with-os arm64-disk-image <>)’ per
trasformarlo in un’immagine.

   L’immagine risultante si presenta così:

     (image
      (format 'disk-image)
      (target "aarch64-linux-gnu")
      (operating-system my-os)
      (partitions
       (list (partition
              (inherit root-partition)
              (offset root-offset)))))

   che è l’aggregazione del ‘operating-system’ definito in ‘my-os.scm’
al record ‘arm64-disk-image’.

   Ma basta follia Scheme. Cosa porta questa API immagine all’utente
Guix?

   Si può eseguire:

     mathieu@cervin:~$ guix system --list-image-types
     I tipi di immagine disponibili sono:

        - unmatched-raw
        - rock64-raw
        - pinebook-pro-raw
        - pine64-raw
        - novena-raw
        - hurd-raw
        - hurd-qcow2
        - qcow2
        - iso9660
        - uncompressed-iso9660
        - tarball
        - efi-raw
        - mbr-raw
        - docker
        - wsl2
        - raw-with-offset
        - efi32-raw

   e scrivendo un file ‘operating-system’ basato su
‘pine64-barebones-os’, puoi personalizzare la tua immagine secondo le
tue preferenze in un file (‘my-pine-os.scm’) come questo:

     (use-modules (gnu services linux)
                  (gnu system images pine64))

     (let ((base-os pine64-barebones-os))
       (operating-system
         (inherit base-os)
         (timezone "America/Indiana/Indianapolis")
         (services
          (cons
           (service earlyoom-service-type
                    (earlyoom-configuration
                     (prefer-regexp "icecat|chromium")))
           (operating-system-user-services base-os)))))

   esegui:

     guix system image --image-type=pine64-raw my-pine-os.scm

   o,

     guix system image --image-type=hurd-raw my-hurd-os.scm

   per ottenere un’immagine che può essere scritta direttamente su un
disco rigido e avviata.

   Senza cambiare nulla in ‘my-hurd-os.scm’, chiamando:

     guix system image --image-type=hurd-qcow2 my-hurd-os.scm

   produrrà invece un’immagine Hurd QEMU.


File: guix-cookbook.it.info,  Node: Utilizzo di chiavi di sicurezza,  Next: Processo mcron per DNS dinamico,  Prev: API immagine di Sistema Guix,  Up: Configurazione di sistema

3.4 Utilizzo di chiavi di sicurezza
===================================

L’uso delle chiavi di sicurezza può migliorare la tua sicurezza fornendo
una seconda fonte di autenticazione che non può essere facilmente rubata
o copiata, almeno per un avversario remoto (qualcosa che hai), al
segreto principale (una passphrase – qualcosa che sai), riducendo il
rischio di impersonificazione.

   L’esempio di configurazione dettagliato di seguito mostra quali
configurazioni minime devono essere apportate al tuo sistema Guix per
consentire l’uso di una chiave di sicurezza Yubico. Si spera che la
configurazione possa essere utile anche per altre chiavi di sicurezza,
con piccole modifiche.

3.4.1 Configurazione per l’uso come autenticatore a due fattori (2FA)
---------------------------------------------------------------------

Per essere utilizzabile, le regole udev del sistema dovrebbero essere
estese con regole specifiche per la chiave. Il seguente mostra come
estendere le tue regole udev con il file di regole udev
‘lib/udev/rules.d/70-u2f.rules’ fornito dal pacchetto ‘libfido2’ dal
modulo ‘(gnu packages security-token)’ e aggiungere il tuo utente al
gruppo ‘"plugdev"’ che utilizza:

     (use-package-modules ... security-token ...)
     ...
     (operating-system
      ...
      (users (cons* (user-account
                    (name "tuo-utente")
                    (group "users")
                    (supplementary-groups
     		'("wheel" "netdev" "audio" "video"
                       "plugdev"))           ;<- gruppo di sistema aggiunto
                    (home-directory "/home/tuo-utente"))
                   %base-user-accounts))
      ...
      (services
       (cons*
        ...
        (udev-rules-service 'fido2 libfido2 #:groups '("plugdev")))))

   Dopo aver riconfigurato il sistema e aver effettuato nuovamente
l’accesso alla sessione grafica in modo che il nuovo gruppo sia
effettivo per il tuo utente, puoi verificare che la tua chiave sia
utilizzabile avviando:

     guix shell ungoogled-chromium -- chromium chrome://settings/securityKeys

   e verificando che la chiave di sicurezza possa essere resettata
tramite il menu “Reset your security key”. Se funziona, congratulazioni,
la tua chiave di sicurezza è pronta per essere utilizzata con
applicazioni che supportano l’autenticazione a due fattori (2FA).

3.4.2 Disabilitazione della generazione di codici OTP per una Yubikey
---------------------------------------------------------------------

Se utilizzi una chiave di sicurezza Yubikey e sei irritato dai codici
OTP spuri che genera quando tocchi involontariamente la chiave (ad
esempio, facendoti diventare uno spammer nel canale ‘#guix’ mentre
discuti dal tuo client IRC preferito!), puoi disabilitarlo tramite il
seguente comando ‘ykman’:

     guix shell python-yubikey-manager -- ykman config usb --force --disable OTP

   In alternativa, potresti usare il comando ‘ykman-gui’ fornito dal
pacchetto ‘yubikey-manager-qt’ e disabilitare completamente
l’applicazione ‘OTP’ per l’interfaccia USB oppure, dalla vista
‘Applications -> OTP’, eliminare la configurazione dello slot 1, che
viene preconfigurata con l’applicazione Yubico OTP.

3.4.3 Richiedere una Yubikey per aprire un database KeePassXC
-------------------------------------------------------------

L’applicazione KeePassXC, gestore di password, supporta le Yubikey, ma
richiede l’installazione di regole udev per il tuo sistema Guix e una
certa configurazione dell’applicazione Yubico OTP sulla chiave.

   Il file di regole udev necessario proviene dal pacchetto
‘yubikey-personalization’, e può essere installato così:

     (use-package-modules ... security-token ...)
     ...
     (operating-system
      ...
      (services
       (cons*
        ...
        (udev-rules-service 'yubikey yubikey-personalization))))

   Dopo aver riconfigurato il sistema (e ricollegato la tua Yubikey),
dovrai poi configurare l’applicazione di sfida/risposta OTP della tua
Yubikey sullo slot 2, che è ciò che KeePassXC usa. È facile farlo
tramite lo strumento di configurazione grafica Yubikey Manager, che può
essere invocato con:

     guix shell yubikey-manager-qt -- ykman-gui

   Innanzitutto, assicurati che ‘OTP’ sia abilitato nella scheda
‘Interfacce’, quindi vai a ‘Applicazioni -> OTP’ e fai clic sul pulsante
‘Configura’ nella sezione ‘Tocco lungo (Slot 2)’. Seleziona
‘Challenge-response’, inserisci o genera una chiave segreta e fai clic
sul pulsante ‘Fine’. Se hai una seconda Yubikey che desideri utilizzare
come backup, dovresti configurarla nello stesso modo, utilizzando la
_stessa_ chiave segreta.

   La tua Yubikey dovrebbe ora essere rilevata da KeePassXC. Può essere
aggiunta a un database navigando nel menu ‘Database -> Sicurezza
database...’ di KeePassXC, quindi facendo clic sul pulsante ‘Aggiungi
protezione aggiuntiva...’, quindi su ‘Aggiungi Challenge-Response’,
selezionando la chiave di sicurezza dal menu a discesa e facendo clic
sul pulsante ‘OK’ per completare la configurazione.


File: guix-cookbook.it.info,  Node: Processo mcron per DNS dinamico,  Next: Connessione a una VPN Wireguard,  Prev: Utilizzo di chiavi di sicurezza,  Up: Configurazione di sistema

3.5 Processo mcron per DNS dinamico
===================================

Se il tuo ISP (Internet Service Provider) fornisce solo indirizzi IP
dinamici, può essere utile configurare un servizio DNS (Domain Name
System) dinamico (noto anche come DDNS (Dynamic DNS)) per associare un
nome host statico a un indirizzo IP pubblico ma dinamico (spesso
variabile). Esistono diversi servizi che possono essere utilizzati a
questo scopo; nel seguente job mcron, DuckDNS (https://duckdns.org)
viene utilizzato. Dovrebbe funzionare anche con altri servizi DNS
dinamici che offrono un’interfaccia simile per aggiornare l’ indirizzo
IP, come <https://freedns.afraid.org/>, con piccole modifiche.

   Il job mcron è fornito di seguito, dove DOMAIN dovrebbe essere
sostituito con il tuo prefisso di dominio, e il token fornito da DuckDNS
associato a DOMAIN aggiunto al file ‘/etc/duckdns/DOMAIN.token’.

     (define duckdns-job
       ;; Aggiorna l'IP del dominio personale ogni 5 minuti.
       #~(job '(next-minute (range 0 60 5))
     	 #$(program-file
                 "duckdns-update"
                 (with-extensions (list guile-gnutls) ;richiesto da (web client)
                   #~(begin
                       (use-modules (ice-9 textual-ports)
                                    (web client))
                       (let ((token (string-trim-both
                                     (call-with-input-file "/etc/duckdns/DOMAIN.token"
                                       get-string-all)))
                             (query-template (string-append "https://www.duckdns.org/"
                                                            "update?domains=DOMAIN"
                                                            "&token=~a&ip=")))
                         (http-get (format #f query-template token))))))
              "duckdns-update"
              #:user "nobody"))

   Il job deve quindi essere aggiunto all’elenco dei job mcron per il
tuo sistema, usando qualcosa come:

     (operating-system
      (services
       (cons* (service mcron-service-type
                (mcron-configuration
                  (jobs (list duckdns-job ...))))
              ...
              %base-services)))


File: guix-cookbook.it.info,  Node: Connessione a una VPN Wireguard,  Next: Personalizzazione di un Window Manager,  Prev: Processo mcron per DNS dinamico,  Up: Configurazione di sistema

3.6 Connessione a una VPN Wireguard
===================================

Per connettersi a un server VPN Wireguard è necessario che il modulo del
kernel sia caricato in memoria e un pacchetto che fornisca strumenti di
rete che lo supportino (ad esempio, ‘wireguard-tools’ o
‘network-manager’).

   Ecco un esempio di configurazione per Linux-Libre < 5.6, dove il
modulo è esterno all’albero e deve essere caricato manualmente—le
revisioni successive del kernel lo hanno integrato e quindi non
necessitano di tale configurazione:

     (use-modules (gnu))
     (use-service-modules desktop)
     (use-package-modules vpn)

     (operating-system
       ;; …
       (services (cons (simple-service 'wireguard-module
                                       kernel-module-loader-service-type
                                       '("wireguard"))
                       %desktop-services))
       (packages (cons wireguard-tools %base-packages))
       (kernel-loadable-modules (list wireguard-linux-compat)))

   Dopo aver riconfigurato e riavviato il sistema, puoi usare gli
strumenti Wireguard o NetworkManager per connetterti a un server VPN.

3.6.1 Utilizzo degli strumenti Wireguard
----------------------------------------

Per testare la tua configurazione Wireguard è comodo usare ‘wg-quick’.
Basta dargli un file di configurazione ‘wg-quick up ./wg0.conf’; o
metterlo in ‘/etc/wireguard’ ed eseguire ‘wg-quick up wg0’ invece.

     Nota: Si noti che l’autore ha descritto questo comando come: “[…]
     uno script bash molto veloce e sporco […]”.

3.6.2 Utilizzo di NetworkManager
--------------------------------

Grazie al supporto di NetworkManager per Wireguard, possiamo connetterci
alla nostra VPN usando il comando ‘nmcli’. Fino a questo punto, questa
guida presuppone che stai usando il servizio Network Manager fornito da
‘%desktop-services’. Altrimenti devi regolare l’elenco dei tuoi servizi
per caricare ‘network-manager-service-type’ e riconfigurare il tuo
sistema Guix.

   Per importare la tua configurazione VPN, esegui il comando nmcli
import:

     # nmcli connection import type wireguard file wg0.conf
     Connessione 'wg0' (edbee261-aa5a-42db-b032-6c7757c60fde) aggiunta con successo

   Questo creerà un file di configurazione in ‘/etc/NetworkManager/
wg0.nmconnection’. Quindi connettiti al server Wireguard:

     $ nmcli connection up wg0
     Connessione attivata con successo (percorso attivo D-Bus: /org/freedesktop/
     NetworkManager/ActiveConnection/6)

   Per impostazione predefinita, NetworkManager si connetterà
automaticamente all’avvio del sistema. Per modificare questo
comportamento, devi modificare la tua configurazione:

     # nmcli connection modify wg0 connection.autoconnect no

   Per informazioni più specifiche su NetworkManager e Wireguard, vedi
questo post di Thaller
(https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/).


File: guix-cookbook.it.info,  Node: Personalizzazione di un Window Manager,  Next: Eseguire Guix su un Server Linode,  Prev: Connessione a una VPN Wireguard,  Up: Configurazione di sistema

3.7 Personalizzazione di un Window Manager
==========================================

* Menu:

* StumpWM::                  StumpWM
* Blocco sessione::          Blocco sessione


File: guix-cookbook.it.info,  Node: StumpWM,  Next: Blocco sessione,  Up: Personalizzazione di un Window Manager

3.7.1 StumpWM
-------------

Potresti installare StumpWM con un sistema Guix aggiungendo i pacchetti
‘stumpwm’ e opzionalmente ‘`(,stumpwm "lib")’ a un file di
configurazione di sistema, ad esempio: ‘/etc/config.scm’.

   Una configurazione di esempio può apparire così:

     (use-modules (gnu))
     (use-package-modules wm)

     (operating-system
       ;; …
       (packages (append (list sbcl stumpwm `(,stumpwm "lib"))
                         %base-packages)))

   Per impostazione predefinita StumpWM utilizza i font X11, che
potrebbero essere piccoli o pixelati sul tuo sistema. Puoi risolvere
questo problema installando il modulo Lisp di StumpWM contrib
‘sbcl-ttf-fonts’, aggiungendolo ai pacchetti di sistema Guix:

     (use-modules (gnu))
     (use-package-modules fonts wm)

     (operating-system
       ;; …
       (packages (append (list sbcl stumpwm `(,stumpwm "lib"))
                         sbcl-ttf-fonts font-dejavu %base-packages)))

   Quindi devi aggiungere il seguente codice a un file di configurazione
di StumpWM ‘~/.stumpwm.d/init.lisp’:

     (require :ttf-fonts)
     (setf xft:*font-dirs* '("/run/current-system/profile/share/fonts/"))
     (setf clx-truetype:+font-cache-filename+ (concat (getenv "HOME")
                                                      "/.fonts/font-cache.sexp"))
     (xft:cache-fonts)
     (set-font (make-instance 'xft:font :family "DejaVu Sans Mono"
                                        :subfamily "Book" :size 11))


File: guix-cookbook.it.info,  Node: Blocco sessione,  Prev: StumpWM,  Up: Personalizzazione di un Window Manager

3.7.2 Blocco sessione
---------------------

A seconda del tuo ambiente, il blocco dello schermo della tua sessione
potrebbe essere integrato o potresti doverlo configurare tu stesso. Se
usi un ambiente desktop come GNOME o KDE, di solito è integrato. Se usi
un semplice window manager come StumpWM o EXWM, potresti doverlo
configurare tu stesso.

* Menu:

* Xorg::                     Xorg


File: guix-cookbook.it.info,  Node: Xorg,  Up: Blocco sessione

3.7.2.1 Xorg
............

Se usi Xorg, puoi usare l’utility xss-lock
(https://www.mankier.com/1/xss-lock) per bloccare lo schermo della tua
sessione. xss-lock è attivato da DPMS che da Xorg 1.8 è auto-rilevato e
abilitato se ACPI è anche abilitato durante l’esecuzione del kernel.

   Per usare xss-lock, puoi semplicemente eseguirlo e metterlo in
background prima di avviare il tuo window manager da, ad esempio, il tuo
‘~/.xsession’:

     xss-lock -- slock &
     exec stumpwm

   In questo esempio, xss-lock usa ‘slock’ per bloccare effettivamente
lo schermo quando lo ritiene opportuno, ad esempio quando sospendi il
tuo dispositivo.

   Affinché slock possa essere un blocco schermo per la sessione
grafica, deve essere reso setuid-root in modo da poter autenticare gli
utenti, e ha bisogno di un servizio PAM. Ciò può essere ottenuto
aggiungendo il seguente servizio al tuo ‘config.scm’:

     (service screen-locker-service-type
              (screen-locker-configuration
               (name "slock")
               (program (file-append slock "/bin/slock"))))

   Se blocchi manualmente lo schermo, ad esempio chiamando direttamente
slock quando vuoi bloccare lo schermo ma non sospenderlo, è una buona
idea notificare xss-lock in modo che non si crei confusione. Ciò può
essere fatto eseguendo ‘xset s activate’ immediatamente prima di
eseguire slock.


File: guix-cookbook.it.info,  Node: Eseguire Guix su un Server Linode,  Next: Eseguire Guix su un Server Kimsufi,  Prev: Personalizzazione di un Window Manager,  Up: Configurazione di sistema

3.8 Eseguire Guix su un Server Linode
=====================================

Per eseguire Guix su un server ospitato da Linode
(https://www.linode.com), inizia con un server Debian consigliato.
Consigliamo di usare la distro predefinita come modo per avviare Guix.
Crea le tue chiavi SSH.

     ssh-keygen

   Assicurati di aggiungere la tua chiave SSH per un facile accesso al
server remoto. Questo è facilmente fatto tramite l’interfaccia grafica
di Linode per l’aggiunta di chiavi SSH. Vai al tuo profilo e clicca su
aggiungi chiave SSH. Copia al suo interno l’output di:

     cat ~/.ssh/<nomeutente>_rsa.pub

   Spegni il Linode.

   Nella scheda Storage di Linode, ridimensiona il disco Debian per
renderlo più piccolo. Si consigliano 30 GB di spazio libero. Quindi
clicca su "Aggiungi un disco" e compila il modulo con quanto segue:

   • Etichetta: "Guix"

   • Filesystem: ext4

   • Impostalo alla dimensione rimanente

   Nella scheda Configurazioni, premi "Modifica" sul profilo Debian
predefinito. Sotto "Assegnazione Dispositivo a Blocchi" clicca "Aggiungi
un Dispositivo". Dovrebbe essere ‘/dev/sdc’ e puoi selezionare il disco
"Guix". Salva le modifiche.

   Ora "Aggiungi una Configurazione", con quanto segue:
   • Etichetta: Guix

   • Kernel:GRUB 2 (è in fondo! Questo passaggio è IMPORTANTE!)

   • Assegnazione dispositivo a blocchi:

   • ‘/dev/sda’: Guix

   • ‘/dev/sdb’: swap

   • Dispositivo root: ‘/dev/sda’

   • Disattiva tutti gli assistenti di filesystem/avvio

   Ora riaccendilo, avviando con la configurazione Debian. Una volta in
esecuzione, connettiti al tuo server via ssh con ‘ssh
root@<IL-TUO-IP-SERVER-QUI>’. (Puoi trovare l’indirizzo IP del tuo
server nella sezione Riepilogo di Linode.) Ora puoi eseguire i passaggi
per "installare Guix da *note (guix.it)Installazione binaria::":

     sudo apt-get install gpg
     wget https://sv.gnu.org/people/viewgpg.php?user_id=15145 -qO - | gpg --import -
     wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
     chmod +x guix-install.sh
     ./guix-install.sh
     guix pull

   Ora è il momento di scrivere una configurazione per il server. Le
informazioni chiave sono qui sotto. Salva il file risultante come
‘guix-config.scm’.

     (use-modules (gnu)
                  (guix modules))
     (use-service-modules networking
                          ssh)
     (use-package-modules admin
                          package-management
                          ssh
                          tls)

     (operating-system
       (host-name "my-server")
       (timezone "America/New_York")
       (locale "en_US.UTF-8")
       ;; Questo codice strambo genererà il grub.cfg
       ;; senza installare il bootloader grub sul disco.
       (bootloader (bootloader-configuration
                    (bootloader
                     (bootloader
                      (inherit grub-bootloader)
                      (installer #~(const #true))))))
       (file-systems (cons (file-system
                             (device "/dev/sda")
                             (mount-point "/")
                             (type "ext4"))
                           %base-file-systems))


       (swap-devices (list "/dev/sdb"))


       (initrd-modules (cons "virtio_scsi"    ; Necessario per trovare il disco
                             %base-initrd-modules))

       (users (cons (user-account
                     (name "janedoe")
                     (group "users")
                     ;; Aggiungendo l'account al gruppo "wheel"
                     ;; lo rende un sudoer.
                     (supplementary-groups '("wheel"))
                     (home-directory "/home/janedoe"))
                    %base-user-accounts))

       (packages (cons* openssh-sans-x
                        %base-packages))

       (services (cons*
                  (service dhcp-client-service-type)
                  (service openssh-service-type
                           (openssh-configuration
                            (openssh openssh-sans-x)
                            (password-authentication? #false)
                            (authorized-keys
                             `(("janedoe" ,(local-file "janedoe_rsa.pub"))
                               ("root" ,(local-file "janedoe_rsa.pub"))))))
                  %base-services)))

   Sostituisci i seguenti campi nella configurazione sopra:
     (host-name "il-mio-server")       ; sostituisci con il nome del tuo server
     ; se hai scelto un server linode fuori dagli Stati Uniti, allora
     ; usa tzselect per trovare una stringa di fuso orario corretta
     (timezone "America/New_York") ; se necessario sostituisci il fuso orario
     (name "janedoe")              ; sostituisci con il tuo nome utente
     ("janedoe" ,(local-file "janedoe_rsa.pub")) ; sostituisci con la tua chiave ssh
     ("root" ,(local-file "janedoe_rsa.pub")) ; sostituisci con la tua chiave ssh

   L’ultima riga nell’esempio sopra ti permette di accedere al server
come root e impostare la password iniziale di root (vedi la nota alla
fine di questa ricetta su l’accesso come root). Dopo aver fatto ciò,
puoi eliminare quella riga dalla tua configurazione e riconfigurare per
impedire l’accesso come root.

   Copia la tua chiave pubblica ssh (es: ‘~/.ssh/id_rsa.pub’) come
‘<IL-TUO-NOMEUTENTE-QUI>_rsa.pub’ e metti ‘guix-config.scm’ nella stessa
directory. In un nuovo terminale esegui questi comandi.

     sftp root@<indirizzo ip del server remoto>
     put /percorso/ai/files/<nomeutente>_rsa.pub .
     put /percorso/ai/files/guix-config.scm .

   Nel tuo primo terminale, monta l’unità guix:

     mkdir /mnt/guix
     mount /dev/sdc /mnt/guix

   A causa del modo in cui abbiamo configurato la sezione del bootloader
di guix-config.scm, solo il file di configurazione di grub verrà
installato. Quindi, dobbiamo copiare parte del resto del GRUB già
installato sul sistema Debian:

     mkdir -p /mnt/guix/boot/grub
     cp -r /boot/grub/* /mnt/guix/boot/grub/

   Ora inizializza l’installazione di Guix:

     guix system init guix-config.scm /mnt/guix

   Ok, spegnilo! Ora dalla console di Linode, seleziona boot e seleziona
"Guix".

   Una volta avviato, dovresti essere in grado di accedere via SSH! (La
configurazione del server sarà cambiata però.) Potresti incontrare un
errore come:

     $ ssh root@<indirizzo ip del server>
     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@     ATTENZIONE: L'IDENTIFICAZIONE DELL'HOST REMOTO È CAMBIATA!      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ È POSSIBILE CHE QUALCUNO STIA FACENDO QUALCOSA DI BRUTTO!
     Qualcuno potrebbe intercettarti in questo momento (attacco man-in-the-middle)!
     È anche possibile che una chiave host sia stata appena cambiata.
     L'impronta digitale della chiave ECDSA inviata dall'host remoto è
     SHA256:0B+wp33w57AnKQuHCvQP0+ZdKaqYrI/kyU7CfVbS7R4.
     Si prega di contattare l'amministratore del sistema.
     Aggiungi la chiave host corretta in /home/joshua/.ssh/known_hosts per eliminare questo messaggio.
     Chiave ECDSA offensiva in /home/joshua/.ssh/known_hosts:3
     La chiave host ECDSA per 198.58.98.76 è cambiata e hai richiesto un controllo rigoroso.
     Verifica della chiave host fallita.

   Elimina il file ‘~/.ssh/known_hosts’ oppure elimina la riga
incriminata che inizia con l’indirizzo IP del tuo server.

   Assicurati di impostare la tua password e quella di root.

     ssh root@<indirizzo ip remoto>
     passwd  ; per la password di root
     passwd <nomeutente> ; per la password utente

   Potresti non essere in grado di eseguire i comandi sopra a questo
punto. Se hai problemi ad accedere in remoto alla tua macchina Linode
via SSH, potresti ancora dover impostare inizialmente la password di
root e dell’utente cliccando sull’opzione “Launch Console” nel tuo
Linode. Scegli “Glish” invece di “Weblish”. Ora dovresti essere in grado
di accedere alla macchina tramite ssh.

   Evviva! A questo punto puoi spegnere il server, eliminare il disco
Debian, e ridimensionare il Guix al resto della dimensione.
Congratulazioni!

   A proposito, se lo salvi come immagine disco proprio a questo punto,
avrai facilità a creare nuove immagini Guix! Potrebbe essere necessario
ridurre la dimensione dell’immagine Guix a 6144MB, per salvarla come
immagine. Quindi puoi ridimensionarla di nuovo a la dimensione massima.


File: guix-cookbook.it.info,  Node: Eseguire Guix su un Server Kimsufi,  Next: Configurazione di un bind mount,  Prev: Eseguire Guix su un Server Linode,  Up: Configurazione di sistema

3.9 Eseguire Guix su un Server Kimsufi
======================================

Per eseguire Guix su un server ospitato da Kimsufi
(https://www.kimsufi.com/), clicca sulla scheda netboot, quindi
seleziona rescue64-pro e riavvia.

   OVH ti invierà via email le credenziali necessarie per accedere via
ssh a un sistema Debian.

   Ora puoi eseguire i passaggi per "installare Guix da *note
(guix.it)Installazione binaria::":

     wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
     chmod +x guix-install.sh
     ./guix-install.sh
     guix pull

   Partiziona i dischi e formattali, prima ferma l’array raid:

     mdadm --stop /dev/md127
     mdadm --zero-superblock /dev/sda2 /dev/sdb2

   Quindi azzera i dischi e configura le partizioni, creeremo un array
RAID 1.

     wipefs -a /dev/sda
     wipefs -a /dev/sdb

     parted /dev/sda --align=opt -s -m -- mklabel gpt
     parted /dev/sda --align=opt -s -m -- \
      mkpart bios_grub 1049kb 512MiB \
      set 1 bios_grub on
     parted /dev/sda --align=opt -s -m -- \
      mkpart primary 512MiB -512MiB
      set 2 raid on
     parted /dev/sda --align=opt -s -m -- mkpart primary linux-swap 512MiB 100%

     parted /dev/sdb --align=opt -s -m -- mklabel gpt
     parted /dev/sdb --align=opt -s -m -- \
          mkpart bios_grub 1049kb 512MiB \
          set 1 bios_grub on
     parted /dev/sdb --align=opt -s -m -- \
          mkpart primary 512MiB -512MiB \
          set 2 raid on
     parted /dev/sdb --align=opt -s -m -- mkpart primary linux-swap 512MiB 100%

   Crea l’array:

     mdadm --create /dev/md127 --level=1 --raid-disks=2 \
       --metadata=0.90 /dev/sda2 /dev/sdb2

   Ora crea i file system sulle partizioni pertinenti, prima le
partizioni di avvio:

     mkfs.ext4  /dev/sda1
     mkfs.ext4  /dev/sdb1

   Quindi la partizione root:

     mkfs.ext4 /dev/md127

   Inizializza le partizioni di swap:

     mkswap /dev/sda3
     swapon /dev/sda3
     mkswap /dev/sdb3
     swapon /dev/sdb3

   Monta l’unità guix:

     mkdir /mnt/guix
     mount /dev/md127 /mnt/guix

   Ora è il momento di scrivere un file di dichiarazione del sistema
operativo ‘os.scm’; ecco un esempio:

     (use-modules (gnu) (guix))
     (use-service-modules networking ssh vpn virtualization sysctl admin mcron)
     (use-package-modules ssh tls tmux vpn virtualization)

     (operating-system
       (host-name "kimsufi")

       (bootloader (bootloader-configuration
     	       (bootloader grub-bootloader)
     	       (targets (list "/dev/sda" "/dev/sdb"))
     	       (terminal-outputs '(console))))

       ;; Aggiungi un modulo del kernel per RAID-1 (alias "mirror").
       (initrd-modules (cons* "raid1"  %base-initrd-modules))

       (mapped-devices
        (list (mapped-device
               (source (list "/dev/sda2" "/dev/sdb2"))
               (target "/dev/md127")
               (type raid-device-mapping))))

       (swap-devices
        (list (swap-space
               (target "/dev/sda3"))
              (swap-space
               (target "/dev/sdb3"))))

       (issue
        ;; Contenuti predefiniti per /etc/issue.
        "\
     Questo è il sistema GNU su Kimsufi. Benvenuto.\n")

       (file-systems (cons* (file-system
     		         (mount-point "/")
     		         (device "/dev/md127")
     		         (type "ext4")
     		         (dependencies mapped-devices))
     		       %base-file-systems))

       (users (cons (user-account
     	        (name "guix")
     	        (comment "guix")
     	        (group "users")
     	        (supplementary-groups '("wheel"))
     	        (home-directory "/home/guix"))
     	       %base-user-accounts))

       (sudoers-file
        (plain-file "sudoers" "\
     root ALL=(ALL) ALL
     %wheel ALL=(ALL) ALL
     guix ALL=(ALL) NOPASSWD:ALL\n"))

       ;; Pacchetti installati globalmente.
       (packages (cons* tmux gnutls wireguard-tools %base-packages))
       (services
        (cons*
         (service static-networking-service-type
     	     (list (static-networking
     		    (addresses (list (network-address
     				      (device "enp3s0")
     				      (value "INDIRIZZO-IP-SERVER/24"))))
     		    (routes (list (network-route
     				   (destination "default")
     				   (gateway "SERVER-GATEWAY"))))
     		    (name-servers '("213.186.33.99")))))

         (service unattended-upgrade-service-type)

         (service openssh-service-type
     	     (openssh-configuration
     	      (openssh openssh-sans-x)
     	      (permit-root-login #f)
     	      (authorized-keys
     	       `(("guix" ,(plain-file "SSH-KEY-NAME.PUB"
                                           "CONTENUTO-CHIAVE-PUBBLICA-SSH"))))))
         (modify-services %base-services
           (sysctl-service-type
            config =>
            (sysctl-configuration
     	(settings (append '(("net.ipv6.conf.all.autoconf" . "0")
     			    ("net.ipv6.conf.all.accept_ra" . "0"))
     			  %default-sysctl-settings))))))))

   Non dimenticare di sostituire le variabili INDIRIZZO-IP-SERVER,
SERVER-GATEWAY, NOME-CHIAVE-SSH e CONTENUTO-CHIAVE-PUBBLICA-SSH con i
tuoi valori.

   Il gateway è l’ultimo IP utilizzabile nel tuo blocco, quindi se hai
un server con un IP di ‘37.187.79.10’ allora il suo gateway sarà
‘37.187.79.254’.

   Trasferisci il file di dichiarazione del tuo sistema operativo
‘os.scm’ sul server tramite i comandi ‘scp’ o ‘sftp’.

   Ora non resta che installare Guix con un ‘guix system init’ e
riavviare.

   Tuttavia, dobbiamo prima configurare un chroot, perché la partizione
root del sistema di recupero è montata su una partizione aufs e se provi
a installare Guix fallirà al passaggio di installazione di GRUB
lamentandosi del percorso canonico di "aufs".

   Installa i pacchetti che verranno usati nel chroot:

     guix install bash-static parted util-linux-with-udev coreutils guix

   Quindi esegui quanto segue per creare le directory necessarie per il
chroot:

     cd /mnt && \
     mkdir -p bin etc gnu/store root/.guix-profile/ root/.config/guix/current \
       var/guix proc sys dev

   Copia il resolv.conf dell’host nel chroot:

     cp /etc/resolv.conf etc/

   Monta i dispositivi a blocchi, lo store e il suo database e la
configurazione attuale di guix:

     mount --rbind /proc /mnt/proc
     mount --rbind /sys /mnt/sys
     mount --rbind /dev /mnt/dev
     mount --rbind /var/guix/ var/guix/
     mount --rbind /gnu/store gnu/store/
     mount --rbind /root/.config/ root/.config/
     mount --rbind /root/.guix-profile/bin/ bin
     mount --rbind /root/.guix-profile root/.guix-profile/

   Chroot in /mnt e installa il sistema:

     chroot /mnt/ /bin/bash

     guix system init /root/os.scm /guix

   Infine, dall’interfaccia utente web (UI), cambia ‘netboot’ in ‘avvio
da disco’ e riavvia (anche dall’interfaccia utente web).

   Aspetta qualche minuto e prova a connetterti via ssh con ‘ssh
guix@INDIRIZZO-IP-SERVER> -i PATH-TO-YOUR-SSH-KEY’

   Dovresti avere un sistema Guix attivo e funzionante su Kimsufi;
congratulazioni!


File: guix-cookbook.it.info,  Node: Configurazione di un bind mount,  Next: Ottenere sostituti da Tor,  Prev: Eseguire Guix su un Server Kimsufi,  Up: Configurazione di sistema

3.10 Configurazione di un bind mount
====================================

Per montare con bind un file system, è necessario prima impostare alcune
definizioni prima della sezione ‘operating-system’ della definizione del
sistema. In questo esempio monteremo con bind una cartella da un disco
rotante su ‘/tmp’, per risparmiare usura sul SSD primario, senza
dedicare un’intera partizione da montare come ‘/tmp’.

   Innanzitutto, l’unità sorgente che ospita la cartella che desideriamo
montare con bind dovrebbe essere definita, in modo che il mount bind
possa dipendere da essa.

     (define source-drive ;; "source-drive" può essere chiamato come vuoi.
        (file-system
         (device (uuid "UUID va qui"))
         (mount-point "/percorso-al-disco-rotante-va-qui")
         (type "ext4"))) ;Assicurati di impostarlo al tipo appropriato per la tua unità.

   La cartella sorgente deve essere definita anche, in modo che guix
sappia che non è un dispositivo a blocchi regolare, ma una cartella.
     ;; "source-directory" può essere qualsiasi nome di variabile valido.
     (define (%source-directory) "/percorso-al-disco-rotante-va-qui/tmp")

   Infine, all’interno della definizione ‘file-systems’, dobbiamo
aggiungere il mount stesso.

     (file-systems (cons*

                     ...<altre unità omesse per chiarezza>...

                     ;; Deve corrispondere al nome che hai dato all'unità sorgente nella definizione precedente.
                     source-drive

                     (file-system
                      ;; Assicurati che "source-directory" corrisponda alla tua definizione precedente.
                      (device (%source-directory))
                      (mount-point "/tmp")
                      ;; Stiamo montando una cartella, non una partizione, quindi questo tipo deve essere "none"
                      (type "none")
                      (flags '(bind-mount))
                      ;; Assicurati che "source-drive" corrisponda al nome che hai dato alla variabile per l'unità.
                      (dependencies (list source-drive))
                      )

                      ...<altre unità omesse per chiarezza>...

                     ))


File: guix-cookbook.it.info,  Node: Ottenere sostituti da Tor,  Next: Configurazione di NGINX con Lua,  Prev: Configurazione di un bind mount,  Up: Configurazione di sistema

3.11 Ottenere sostituti da Tor
==============================

Il demone Guix può usare un proxy HTTP per ottenere i sostituti, qui lo
stiamo configurando per ottenerli tramite Tor.

     Avviso: _Non tutto_ il traffico del demone Guix passerà attraverso
     Tor! Solo HTTP/HTTPS sarà proxato; FTP, protocollo Git, SSH, ecc.
     le connessioni passeranno comunque attraverso il clearnet. Ancora
     una volta, questa configurazione non è a prova di errore, parte del
     tuo traffico non sarà affatto instradato da Tor. Usala a tuo
     rischio e pericolo.

     Si noti inoltre che la procedura qui descritta si applica solo alla
     sostituzione di pacchetti. Quando si aggiorna la distribuzione guix
     con ‘guix pull’, è comunque necessario utilizzare ‘torsocks’ se si
     desidera instradare la connessione ai server del repository git di
     guix tramite Tor.

   Il server di sostituzione di Guix è disponibile come servizio Onion,
se vuoi usarlo per ottenere i tuoi sostituti tramite Tor, configura il
tuo sistema come segue:

     (use-modules (gnu))
     (use-service-module base networking)

     (operating-system
       …
       (services
         (cons
           (service tor-service-type
                   (tor-configuration
                     (config-file (plain-file "tor-config"
                                              "HTTPTunnelPort 127.0.0.1:9250"))))
           (modify-services %base-services
             (guix-service-type
               config => (guix-configuration
                           (inherit config)
                           ;; servizio Onion di ci.guix.gnu.org
                           (substitute-urls "\
     https://4zwzi66wwdaalbhgnix55ea3ab4pvvw66ll2ow53kjub6se4q2bclcyd.onion")
                           (http-proxy "http://localhost:9250")))))))

   Questo manterrà un processo tor in esecuzione che fornisce un tunnel
HTTP CONNECT che sarà usato da ‘guix-daemon’. Il demone può usare altri
protocolli oltre a HTTP(S) per ottenere risorse remote, le richieste che
usano tali protocolli non passeranno attraverso Tor poiché stiamo
impostando solo un tunnel HTTP qui. Si noti che ‘substitutes-urls’ sta
usando HTTPS e non HTTP o non funzionerà, questa è una limitazione del
tunnel di Tor; potresti voler usare ‘privoxy’ invece per evitare tali
limitazioni.

   Se non vuoi ottenere sempre sostituti tramite Tor ma usarlo solo a
volte, allora salta la ‘guix-configuration’. Quando vuoi ottenere un
sostituto dal tunnel Tor esegui:

     sudo herd set-http-proxy guix-daemon http://localhost:9250
     guix build \
       --substitute-urls=https://4zwzi66wwdaalbhgnix55ea3ab4pvvw66ll2ow53kjub6se4q2bclcyd.onion ...


File: guix-cookbook.it.info,  Node: Configurazione di NGINX con Lua,  Next: Server musicale con audio Bluetooth,  Prev: Ottenere sostituti da Tor,  Up: Configurazione di sistema

3.12 Configurazione di NGINX con Lua
====================================

NGINX potrebbe essere esteso con script Lua.

   Guix fornisce il servizio NGINX con la capacità di caricare il modulo
Lua e specifici pacchetti Lua, e di rispondere alle richieste valutando
gli script Lua.

   Il seguente esempio dimostra la definizione del sistema con la
configurazione per valutare lo script Lua ‘index.lua’ su richiesta HTTP
all’endpoint <http://localhost/hello>:

     local shell = require "resty.shell"

     local stdin = ""
     local timeout = 1000  -- ms
     local max_size = 4096  -- byte

     local ok, stdout, stderr, reason, status =
        shell.run([[/run/current-system/profile/bin/ls /tmp]], stdin, timeout, max_size)

     ngx.say(stdout)

     (use-modules (gnu))
     (use-service-modules #;… web)
     (use-package-modules #;… lua)
     (operating-system
       ;; …
       (services
        ;; …
        (service nginx-service-type
                 (nginx-configuration
                  (modules
                   (list
                    (file-append nginx-lua-module "/etc/nginx/modules/ngx_http_lua_module.so")))
                  (lua-package-path (list lua-resty-core
                                          lua-resty-lrucache
                                          lua-resty-signal
                                          lua-tablepool
                                          lua-resty-shell))
                  (lua-package-cpath (list lua-resty-signal))
                  (server-blocks
                   (list (nginx-server-configuration
                          (server-name '("localhost"))
                          (listen '("80"))
                          (root "/etc")
                          (locations (list
                                      (nginx-location-configuration
                                       (uri "/hello")
                                       (body (list #~(format #f "content_by_lua_file ~s;"
                                                             #$(local-file "index.lua"))))))))))))))


File: guix-cookbook.it.info,  Node: Server musicale con audio Bluetooth,  Prev: Configurazione di NGINX con Lua,  Up: Configurazione di sistema

3.13 Server musicale con audio Bluetooth
========================================

MPD, il Music Player Daemon, è un’applicazione flessibile lato server
per riprodurre musica. I programmi client su diverse macchine della rete
— un telefono cellulare, un laptop, una workstation desktop — possono
connettersi ad esso per controllare la riproduzione di file audio dalla
tua collezione musicale locale. MPD decodifica i file audio e li
riproduce su una o più uscite.

   Per impostazione predefinita MPD riprodurrà sul dispositivo audio
predefinito. Nell’esempio seguente rendiamo le cose un po’ più
interessanti impostando un server musicale headless. Non ci sarà
interfaccia grafica utente, nessun demone Pulseaudio, e nessuna uscita
audio locale. Invece configureremo MPD con due uscite: un altoparlante
bluetooth e un server web per servire flussi audio a qualsiasi lettore
multimediale in streaming.

   Il Bluetooth è spesso piuttosto frustrante da configurare. Dovrai
accoppiare il tuo dispositivo Bluetooth e assicurarti che il dispositivo
sia connesso automaticamente non appena si accende. Il servizio di
sistema Bluetooth restituito dalla procedura ‘bluetooth-service’
fornisce l’infrastruttura necessaria per configurarlo.

   Riconfigura il tuo sistema con almeno i seguenti servizi e pacchetti:

     (operating-system
       ;; …
       (packages (cons* bluez bluez-alsa
                        %base-packages))
       (services
        ;; …
        (dbus-service #:services (list bluez-alsa))
        (bluetooth-service #:auto-enable? #t)))

   Avvia il servizio ‘bluetooth’ e poi usa ‘bluetoothctl’ per scandire i
dispositivi Bluetooth. Prova a identificare il tuo altoparlante
Bluetooth e ricava il suo ID dispositivo dalla lista risultante di
dispositivi che è indubbiamente dominata da un’incredibile varietà di
gadget di automazione domestica dei tuoi vicini. Questo deve essere
fatto solo una volta:

     $ bluetoothctl
     [NEW] Controller 00:11:22:33:95:7F BlueZ 5.40 [default]

     [bluetooth]# power on
     [bluetooth]# Changing power on succeeded

     [bluetooth]# agent on
     [bluetooth]# Agente registrato

     [bluetooth]# default-agent
     [bluetooth]# Richiesta agente predefinito riuscita

     [bluetooth]# scan on
     [bluetooth]# Rilevamento avviato
     [CHG] Controller 00:11:22:33:95:7F Rilevamento: sì
     [NEW] Dispositivo AA:BB:CC:A4:AA:CD Il mio altoparlante Bluetooth
     [NEW] Dispositivo 44:44:FF:2A:20:DC TV del mio vicino
     ...

     [bluetooth]# pair AA:BB:CC:A4:AA:CD
     Tentativo di accoppiamento con AA:BB:CC:A4:AA:CD
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD Connesso: sì

     [My Bluetooth Speaker]# [CHG] Dispositivo AA:BB:CC:A4:AA:CD UUIDs: 0000110b-0000-1000-8000-00xxxxxxxxxx
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD UUIDs: 0000110c-0000-1000-8000-00xxxxxxxxxx
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD UUIDs: 0000110e-0000-1000-8000-00xxxxxxxxxx
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD Accoppiato: sì
     Accoppiamento riuscito

     [CHG] Dispositivo AA:BB:CC:A4:AA:CD Connesso: no

     [bluetooth]#
     [bluetooth]# trust AA:BB:CC:A4:AA:CD
     [bluetooth]# [CHG] Dispositivo AA:BB:CC:A4:AA:CD Affidabile: sì
     Modifica dell'affidabilità di AA:BB:CC:A4:AA:CD riuscita

     [bluetooth]#
     [bluetooth]# connect AA:BB:CC:A4:AA:CD
     Tentativo di connessione a AA:BB:CC:A4:AA:CD
     [bluetooth]# [CHG] Dispositivo AA:BB:CC:A4:AA:CD RSSI: -63
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD Connesso: sì
     Connessione riuscita

     [My Bluetooth Speaker]# scan off
     [CHG] Dispositivo AA:BB:CC:A4:AA:CD RSSI è nullo
     Rilevamento interrotto
     [CHG] Controller 00:11:22:33:95:7F Rilevamento: no

   Congratulazioni, ora puoi connetterti automaticamente al tuo
altoparlante Bluetooth!

   Ora è il momento di configurare ALSA per utilizzare il modulo
Bluetooth _bluealsa_, in modo da poter definire un dispositivo pcm ALSA
corrispondente al tuo altoparlante Bluetooth. Per un server headless che
utilizza _bluealsa_ con un dispositivo Bluetooth fisso è probabilmente
più semplice che configurare Pulseaudio e il suo comportamento di
commutazione del flusso. Configureremo ALSA creando una
‘alsa-configuration’ personalizzata per il ‘alsa-service-type’. La
configurazione dichiarerà un tipo ‘pcm’ ‘bluealsa’ dal modulo ‘bluealsa’
fornito dal pacchetto ‘bluez-alsa’, e quindi definirà un dispositivo
‘pcm’ di quel tipo per il tuo altoparlante Bluetooth.

   Tutto ciò che resta da fare è far sì che MPD invii dati audio a
questo dispositivo ALSA. Aggiungiamo anche un’uscita MPD secondaria che
rende i file audio attualmente riprodotti disponibili come stream
tramite un server web sulla porta 8080. Quando abilitato un dispositivo
sulla rete potrebbe ascoltare il flusso audio collegando qualsiasi
lettore multimediale compatibile al server HTTP sulla porta 8080,
indipendentemente dallo stato dell’altoparlante Bluetooth.

   Quello che segue è lo schema di una dichiarazione ‘operating-system’
che dovrebbe compiere i compiti sopra menzionati:

     (use-modules (gnu))
     (use-service-modules audio dbus sound #;… etc)
     (use-package-modules audio linux #;… etc)
     (operating-system
       ;; …
       (packages (cons* bluez bluez-alsa
                        %base-packages))
       (services
        ;; …
        (service mpd-service-type
                 (mpd-configuration
                  (user "il-tuo-nome-utente")
                  (music-dir "/percorso/alla/tua/musica")
                  (address "192.168.178.20")
                  (outputs (list (mpd-output
                                  (type "alsa")
                                  (name "MPD")
                                  (extra-options
                                   ;; Usa lo stesso nome della configurazione ALSA
                                   ;; qui sotto.
                                   '((device . "pcm.btspeaker"))))
                                 (mpd-output
                                  (type "httpd")
                                  (name "streaming")
                                  (enabled? #false)
                                  (always-on? #true)
                                  (tags? #true)
                                  (mixer-type 'null)
                                  (extra-options
                                   '((encoder . "vorbis")
                                     (port    . "8080")
                                     (bind-to-address . "192.168.178.20")
                                     (max-clients . "0") ;nessun limite
                                     (quality . "5.0")
                                     (format  . "44100:16:1"))))))))
        (dbus-service #:services (list bluez-alsa))
        (bluetooth-service #:auto-enable? #t)
        (service alsa-service-type
                 (alsa-configuration
                  (pulseaudio? #false) ;non ne abbiamo bisogno
                  (extra-options
                   #~(string-append "\
     # Dichiara il tipo di dispositivo audio Bluetooth \"bluealsa\" dal modulo bluealsa
     pcm_type.bluealsa {
         lib \""
     #$(file-append bluez-alsa "/lib/alsa-lib/libasound_module_pcm_bluealsa.so") "\"
     }

     # Dichiara il tipo di dispositivo di controllo \"bluealsa\" dallo stesso modulo
     ctl_type.bluealsa {
         lib \""
     #$(file-append bluez-alsa "/lib/alsa-lib/libasound_module_ctl_bluealsa.so") "\"
     }

     # Definisci il dispositivo audio Bluetooth effettivo.
     pcm.btspeaker {
         type bluealsa
         device \"AA:BB:CC:A4:AA:CD\" # identificatore unico del dispositivo
         profile \"a2dp\"
     }

     # Definisci un controller associato.
     ctl.btspeaker {
         type bluealsa
     }
     "))))))

   Goditi la musica con il client MPD di tua scelta o un lettore
multimediale capace di streaming via HTTP!


File: guix-cookbook.it.info,  Node: Contenitori,  Next: Macchine virtuali,  Prev: Configurazione di sistema,  Up: Top

4 Contenitori
*************

Il kernel Linux fornisce una serie di strutture condivise che sono
disponibili ai processi nel sistema. Queste strutture includono una
vista condivisa sul file system, altri processi, dispositivi di rete,
identità di utenti e gruppi, e alcune altre. Dal kernel Linux 3.19 un
utente può scegliere di _unshare_ alcune di queste strutture condivise
per processi selezionati, fornendo loro (e ai loro processi figli) una
vista diversa del sistema.

   Un processo con un namespace ‘mount’ non condiviso, ad esempio, ha la
sua propria vista sul file system — sarà in grado di vedere solo le
directory che sono state esplicitamente vincolate nel suo namespace
mount. Un processo con il suo proprio namespace ‘proc’ si considererà
l’unico processo in esecuzione sul sistema, in esecuzione come PID 1.

   Guix utilizza queste funzionalità del kernel per fornire ambienti
completamente isolati e anche contenitori Guix System completi, macchine
virtuali leggere che condividono il kernel del sistema host. Questa
funzionalità è particolarmente utile quando si utilizza Guix su una
distribuzione esterna per prevenire interferenze da librerie o file di
configurazione esterni disponibili a livello di sistema.

* Menu:

* Contenitori Guix::         Ambienti perfettamente isolati
* Contenitori di Sistema Guix::  Un sistema dentro il tuo sistema


File: guix-cookbook.it.info,  Node: Contenitori Guix,  Next: Contenitori di Sistema Guix,  Up: Contenitori

4.1 Contenitori Guix
====================

Il modo più semplice per iniziare è usare ‘guix shell’ con l’opzione
‘--container’. *Note (guix.it)Invocare guix shell:: per un riferimento
delle opzioni valide.

   Il seguente frammento avvia un processo shell minimale con la maggior
parte dei namespace non condivisi dal sistema. La directory di lavoro
corrente è visibile al processo, ma qualsiasi altra cosa sul file system
non è disponibile. Questa estrema isolazione può essere molto utile
quando si desidera escludere qualsiasi tipo di interferenza da variabili
d’ambiente, librerie installate globalmente o file di configurazione.

     guix shell --container

   È un ambiente desolato, sterile, deserto. Scoprirai che nemmeno i
coreutils GNU sono disponibili qui, quindi per esplorare questa landa
deserta devi usare i comandi shell integrati. Anche la di solito
gigantesca directory ‘/gnu/store’ è ridotta a una flebile ombra di se
stessa.

     $ echo /gnu/store/*
     /gnu/store/...-gcc-10.3.0-lib
     /gnu/store/...-glibc-2.33
     /gnu/store/...-bash-static-5.1.8
     /gnu/store/...-ncurses-6.2.20210619
     /gnu/store/...-bash-5.1.8
     /gnu/store/...-profile
     /gnu/store/...-readline-8.1.1

   Non c’è molto che tu possa fare in un ambiente come questo oltre a
uscirne. Puoi usare <^D> o ‘exit’ per terminare questo ambiente shell
limitato.

   È possibile rendere disponibili altre directory all’interno
dell’ambiente del contenitore; utilizzare ‘--expose=DIRECTORY’ per
montare con bind la directory specificata come posizione di sola lettura
all’interno del contenitore, o utilizzare ‘--share=DIRECTORY’ per
rendere la posizione scrivibile. Con un argomento di mappatura
aggiuntivo dopo il nome della directory è possibile controllare il nome
della directory all’interno del contenitore. Nell’esempio seguente
mappiamo ‘/etc’ sul sistema host a ‘/the/host/etc’ all’interno di un
contenitore in cui sono installati i coreutils GNU.

     $ guix shell --container --share=/etc=/the/host/etc coreutils
     $ ls /the/host/etc

   Allo stesso modo, puoi impedire che la directory di lavoro corrente
venga mappata nel contenitore con l’opzione ‘--no-cwd’. Un’altra buona
idea è creare una directory dedicata che fungerà da directory home del
contenitore, e avviare la shell del contenitore da quella directory.

   Su un sistema esterno, un ambiente container può essere utilizzato
per compilare software che non può essere collegato a librerie di
sistema o alla toolchain del compilatore del sistema. Un caso d’uso
comune in un contesto di ricerca è l’installazione di pacchetti da una
sessione R. Al di fuori di un ambiente container è molto probabile che
la toolchain del compilatore esterno e le librerie di sistema
incompatibili vengano trovate per prime, risultando in binari
incompatibili che non possono essere utilizzati da R. In una shell
container questo problema scompare, poiché le librerie di sistema e gli
eseguibili semplicemente non sono disponibili a causa del namespace
‘mount’ non condiviso.

   Prendiamo un manifesto completo che fornisce un ambiente di sviluppo
confortevole per l’uso con R:

     (specifications->manifest
       (list "r-minimal"

             ;; pacchetti base
             "bash-minimal"
             "glibc-locales"
             "nss-certs"

             ;; Strumenti comuni da riga di comando per evitare che il contenitore sia troppo vuoto.
             "coreutils"
             "grep"
             "which"
             "wget"
             "sed"

             ;; Strumenti R markdown
             "pandoc"

             ;; Toolchain e librerie comuni per "install.packages"
             "gcc-toolchain@10"
             "gfortran-toolchain"
             "gawk"
             "tar"
             "gzip"
             "unzip"
             "make"
             "cmake"
             "pkg-config"
             "cairo"
             "libxt"
             "openssl"
             "curl"
             "zlib"))

   Utilizziamolo per eseguire R all’interno di un ambiente container.
Per comodità, condividiamo il namespace ‘net’ per utilizzare le
interfacce di rete del sistema host. Ora possiamo compilare i pacchetti
R dal sorgente nel modo tradizionale senza doverci preoccupare di
disallineamenti ABI o incompatibilità.

     $ guix shell --container --network --manifest=manifest.scm -- R

     R version 4.2.1 (2022-06-23) -- "Funny-Looking Kid"
     Copyright (C) 2022 The R Foundation for Statistical Computing
     ...
     > e <- Sys.getenv("GUIX_ENVIRONMENT")
     > Sys.setenv(GIT_SSL_CAINFO=paste0(e, "/etc/ssl/certs/ca-certificates.crt"))
     > Sys.setenv(SSL_CERT_FILE=paste0(e, "/etc/ssl/certs/ca-certificates.crt"))
     > Sys.setenv(SSL_CERT_DIR=paste0(e, "/etc/ssl/certs"))
     > install.packages("Cairo", lib=paste0(getwd()))
     ...
     * installing *source* package 'Cairo' ...
     ...
     * DONE (Cairo)

     I pacchetti sorgente scaricati si trovano in
     	'/tmp/RtmpCuwdwM/downloaded_packages'
     > library("Cairo", lib=getwd())
     > # successo!

   L’uso delle shell container è divertente, ma possono diventare un po’
complicate quando si vuole andare oltre un singolo processo interattivo.
Alcuni compiti diventano molto più facili quando si basano sulla solida
fondazione di un vero sistema Guix e del suo ricco set di servizi di
sistema. La prossima sezione ti mostrerà come avviare un sistema Guix
completo all’interno di un container.


File: guix-cookbook.it.info,  Node: Contenitori di Sistema Guix,  Prev: Contenitori Guix,  Up: Contenitori

4.2 Contenitori di Sistema Guix
===============================

Il sistema Guix fornisce una vasta gamma di servizi di sistema
interconnessi che sono configurati in modo dichiarativo per formare una
fondazione affidabile e senza stato per il sistema GNU per qualsiasi
attività tu gli assegni. Anche quando usi Guix su una distribuzione
esterna, puoi beneficiare del design del sistema Guix eseguendo
un’istanza di sistema come container. Usando le stesse funzionalità del
kernel di namespace non condivisi menzionati nella sezione precedente,
l’istanza Guix System risultante è isolata dal sistema host e condivide
solo le posizioni del file system che dichiari esplicitamente.

   Un contenitore del sistema Guix differisce dal processo di shell
creato da ‘guix shell --container’ in una serie di modi importanti.
Mentre in una shell contenitore il processo containerizzato è un
processo shell Bash, un contenitore del sistema Guix esegue Shepherd
come PID 1. In un contenitore di sistema tutti i servizi di sistema
(*note (guix)Services::) sono configurati esattamente come lo sarebbero
su un sistema Guix in una macchina virtuale o su hardware bare metal —
questo include i demoni gestiti da GNU Shepherd (*note (guix.it)Servizi
Shepherd::) così come altri tipi di estensioni al sistema operativo
(*note (guix.it)Composizione dei servizi::).

   Il percepito aumento di complessità nell’esecuzione di un contenitore
del sistema Guix è facilmente giustificato quando si ha a che fare con
applicazioni più complesse che hanno requisiti più elevati o
semplicemente più rigidi sui loro contesti di esecuzione — file di
configurazione, account utente dedicati, directory per cache o file di
log, ecc. Nel sistema Guix le esigenze di questo tipo di software sono
soddisfatte attraverso l’implementazione di servizi di sistema.

* Menu:

* Un contenitore Database::  Un contenitore Database
* Networking dei contenitori::  Networking dei contenitori


File: guix-cookbook.it.info,  Node: Un contenitore Database,  Next: Networking dei contenitori,  Up: Contenitori di Sistema Guix

4.2.1 Un contenitore Database
-----------------------------

Un buon esempio potrebbe essere un server di database PostgreSQL. Gran
parte della complessità della configurazione di un tale server di
database è incapsulata in questa ingannevolmente breve dichiarazione di
servizio:

     (service postgresql-service-type
              (postgresql-configuration
               (postgresql postgresql-14)))

   Una dichiarazione completa del sistema operativo da utilizzare con un
contenitore del sistema Guix sarebbe simile a questa:

     (use-modules (gnu))
     (use-package-modules databases)
     (use-service-modules databases)

     (operating-system
       (host-name "container")
       (timezone "Europe/Berlin")
       (file-systems (cons (file-system
                             (device (file-system-label "non-importa"))
                             (mount-point "/")
                             (type "ext4"))
                           %base-file-systems))
       (bootloader (bootloader-configuration
                    (bootloader grub-bootloader)
                    (targets '("/dev/sdX"))))
       (services
        (cons* (service postgresql-service-type
                        (postgresql-configuration
                         (postgresql postgresql-14)
                         (config-file
                          (postgresql-config-file
                           (log-destination "stderr")
                           (hba-file
                            (plain-file "pg_hba.conf"
                                        "\
     local	all	all			trust
     host	all	all	10.0.0.1/32 	trust"))
                           (extra-config
                            '(("listen_addresses" "*")
                              ("log_directory"    "/var/log/postgresql")))))))
               (service postgresql-role-service-type
                        (postgresql-role-configuration
                         (roles
                          (list (postgresql-role
                                 (name "test")
                                 (create-database? #t))))))
               %base-services)))

   Con ‘postgresql-role-service-type’ definiamo un ruolo “test” e
creiamo un database corrispondente, in modo da poter testare subito
senza alcuna ulteriore configurazione manuale. Le impostazioni di
‘postgresql-config-file’ permettono a un client dall’indirizzo IP
10.0.0.1 di connettersi senza richiedere autenticazione—una cattiva idea
nei sistemi di produzione, ma comoda per questo esempio.

   Costruiamo uno script che avvierà un’istanza di questo sistema Guix
come contenitore. Scrivi la dichiarazione ‘operating-system’ sopra in un
file ‘os.scm’ e poi usa ‘guix system container’ per costruire il
launcher. (*note (guix.it)Invocare guix system::).

     $ guix system container os.scm
     Verranno costruite le seguenti derivazioni:
       /gnu/store/...-run-container.drv
       ...
     costruzione di /gnu/store/...-run-container.drv...
     /gnu/store/...-run-container

   Ora che abbiamo uno script di avvio, possiamo eseguirlo per avviare
il nuovo sistema con un servizio PostgreSQL in esecuzione. Si noti che a
causa di alcune limitazioni non ancora risolte, dobbiamo eseguire il
launcher come utente root, ad esempio con ‘sudo’.

     $ sudo /gnu/store/...-run-container
     il contenitore di sistema è in esecuzione come PID 5983
     ...

   Metti in background il processo con <Ctrl-z> seguito da ‘bg’. Nota il
ID del processo nell’output; ci servirà per connetterci al contenitore
più tardi. Sai cosa? Proviamo a connetterci al contenitore subito.
Useremo ‘nsenter’, uno strumento fornito dal pacchetto ‘util-linux’:

     $ guix shell util-linux
     $ sudo nsenter -a -t 5983
     root@container /# pgrep -a postgres
     49 /gnu/store/...-postgresql-14.4/bin/postgres -D /var/lib/postgresql/data --config-file=/gnu/store/...-postgresql.conf -p 5432
     51 postgres: checkpointer
     52 postgres: background writer
     53 postgres: walwriter
     54 postgres: autovacuum launcher
     55 postgres: stats collector
     56 postgres: logical replication launcher
     root@container /# exit

   Il servizio PostgreSQL è in esecuzione nel contenitore!


File: guix-cookbook.it.info,  Node: Networking dei contenitori,  Prev: Un contenitore Database,  Up: Contenitori di Sistema Guix

4.2.2 Networking dei contenitori
--------------------------------

A che serve un sistema Guix che esegue un servizio di database
PostgreSQL come contenitore quando possiamo comunicare con esso solo con
processi originari del contenitore? Sarebbe molto meglio se potessimo
comunicare con il database tramite la rete.

   Il modo più semplice per farlo è creare una coppia di dispositivi
Ethernet virtuali connessi (noti come ‘veth’). Spostiamo uno dei
dispositivi (‘ceth-test’) nel namespace ‘net’ del contenitore e lasciamo
l’altra estremità (‘veth-test’) della connessione sul sistema host.

     pid=5983
     ns="guix-test"
     host="veth-test"
     client="ceth-test"

     # Collega il nuovo net namespace "guix-test" al PID del contenitore.
     sudo ip netns attach $ns $pid

     # Crea la coppia di dispositivi
     sudo ip link add $host type veth peer name $client

     # Sposta il dispositivo client nel namespace di rete del contenitore
     sudo ip link set $client netns $ns

   Quindi configuriamo il lato host:

     sudo ip link set $host up
     sudo ip addr add 10.0.0.1/24 dev $host

   ...e poi configuriamo il lato client:

     sudo ip netns exec $ns  ip link set lo up
     sudo ip netns exec $ns  ip link set $client up
     sudo ip netns exec $ns  ip addr add 10.0.0.2/24 dev $client

   A questo punto l’host può raggiungere il contenitore all’indirizzo IP
10.0.0.2, e il contenitore può raggiungere l’host all’IP 10.0.0.1.
Questo è tutto ciò di cui abbiamo bisogno per parlare con il server di
database all’interno del contenitore dal sistema host all’esterno.

     $ psql -h 10.0.0.2 -U test
     psql (14.4)
     Digita "help" per aiuto.

     test=> CREATE TABLE hello (who TEXT NOT NULL);
     CREATE TABLE
     test=> INSERT INTO hello (who) VALUES ('world');
     INSERT 0 1
     test=> SELECT * FROM hello;
       who
     -------
      world
     (1 riga)

   Ora che abbiamo finito con questa piccola dimostrazione, puliamo:

     sudo kill $pid
     sudo ip netns del $ns
     sudo ip link del $host


File: guix-cookbook.it.info,  Node: Macchine virtuali,  Next: Gestione avanzata dei pacchetti,  Prev: Contenitori,  Up: Top

5 Macchine virtuali
*******************

Guix può produrre immagini disco (*note (guix.it)Invocare guix system::)
che possono essere utilizzate con soluzioni di macchine virtuali come
virt-manager, GNOME Boxes o il più semplice QEMU, tra gli altri.

   Questo capitolo si propone di fornire esempi pratici e concreti
relativi all’utilizzo e alla configurazione di macchine virtuali su un
sistema Guix.

* Menu:

* Ponte di rete per QEMU::   Ponte di rete per QEMU
* Rete instradata per libvirt::  Rete instradata per libvirt
* Rete personalizzata basata su NAT per libvirt::  Rete personalizzata
                                                     basata su NAT per libvirt
* Riferimenti: Riferimenti VM.  Ulteriori letture sulle macchine virtuali.


File: guix-cookbook.it.info,  Node: Ponte di rete per QEMU,  Next: Rete instradata per libvirt,  Up: Macchine virtuali

5.1 Ponte di rete per QEMU
==========================

Per impostazione predefinita, QEMU utilizza un back-end di rete host
cosiddetto “user mode”, che è comodo in quanto non richiede alcuna
configurazione. Sfortunatamente, è anche piuttosto limitato. In questa
modalità, la VM (macchina virtuale) guest può accedere alla rete nello
stesso modo in cui lo farebbe l’host, ma non può essere raggiunta
dall’host. Inoltre, poiché la modalità di rete utente di QEMU si basa su
ICMP, gli strumenti di rete basati su ICMP come ‘ping’ _not_ funzionano
in questa modalità. Pertanto, è spesso desiderabile configurare un
bridge di rete, che consente al guest di partecipare pienamente alla
rete. Ciò è necessario, ad esempio, quando il guest deve essere
utilizzato come server.

5.1.1 Creazione di un’interfaccia bridge di rete
------------------------------------------------

Esistono molti modi per creare un bridge di rete. Il seguente comando
mostra come usare NetworkManager e il suo strumento ‘nmcli’ da riga di
comando (CLI), che dovrebbe essere già disponibile se la dichiarazione
del tuo sistema operativo si basa su uno dei modelli desktop:

     # nmcli con add type bridge con-name br0 ifname br0

   Per far sì che questo bridge faccia parte della tua rete, devi
associare il tuo bridge di rete all’interfaccia Ethernet usata per
connetterti alla rete. Supponendo che la tua interfaccia si chiami
‘enp2s0’, il seguente comando può essere usato per farlo:

     # nmcli con add type bridge-slave ifname enp2s0 master br0

     Importante: Solo le interfacce Ethernet possono essere aggiunte a
     un bridge. Per le interfacce wireless, considerare l’approccio di
     rete instradata dettagliato in *Note Rete instradata per libvirt::.

   Per impostazione predefinita, il bridge di rete consentirà ai tuoi
ospiti di ottenere il loro indirizzo IP tramite DHCP, se disponibile
sulla tua rete locale. Per semplicità, questo è ciò che useremo qui. Per
trovare facilmente gli ospiti, possono essere configurati per
pubblicizzare i loro nomi host tramite mDNS.

5.1.2 Configurazione dello script helper del bridge QEMU
--------------------------------------------------------

QEMU viene fornito con un programma di aiuto per utilizzare comodamente
un’interfaccia bridge di rete come utente non privilegiato *note
(QEMU)Network options::. Il binario deve essere reso setuid root per il
corretto funzionamento; questo può essere ottenuto aggiungendolo al
campo ‘privileged-programs’ della tua definizione ‘operating-system’
(host), come mostrato sotto:

     (privileged-programs
      (cons (privileged-program
              (program (file-append qemu "/libexec/qemu-bridge-helper"))
              (setuid? #t))
            %default-privileged-programs))

   Il file ‘/etc/qemu/bridge.conf’ deve anche essere modificato per
consentire l’interfaccia del bridge, poiché l’impostazione predefinita è
di negare tutto. Aggiungi quanto segue all’elenco dei servizi per farlo:

     (extra-special-file "/etc/qemu/host.conf"
                         (plain-file "host.conf" "allow br0\n"))

5.1.3 Avviare QEMU con le opzioni da riga di comando corrette
-------------------------------------------------------------

Quando si invoca QEMU, le seguenti opzioni devono essere fornite in modo
che il bridge di rete sia utilizzato, dopo aver selezionato un indirizzo
MAC unico per il guest.

     Importante: Per impostazione predefinita, viene utilizzato un
     singolo indirizzo MAC per tutti gli ospiti, a meno che non venga
     fornito. Il mancato fornitura di indirizzi MAC diversi a ciascuna
     macchina virtuale che utilizza il bridge causerebbe problemi di
     rete.

     $ qemu-system-x86_64 [...] \
         -device virtio-net-pci,netdev=user0,mac=XX:XX:XX:XX:XX:XX \
         -netdev bridge,id=user0,br=br0 \
         [...]

   Per generare indirizzi MAC che hanno il prefisso registrato da QEMU,
può essere utilizzato il seguente frammento:

     mac_address="52:54:00:$(dd if=/dev/urandom bs=512 count=1 2>/dev/null \
                                | md5sum \
                                | sed -E 's/^(..)(..)(..).*$/\1:\2:\3/')"
     echo $mac_address

5.1.4 Problemi di rete causati da Docker
----------------------------------------

Se usi Docker sulla tua macchina, potresti riscontrare problemi di
connettività quando tenti di usare un bridge di rete, causati dal fatto
che Docker si basa anche sui bridge di rete e configura le proprie
regole di routing. La soluzione è aggiungere il seguente frammento
‘iptables’ alla tua dichiarazione ‘operating-system’:

     (service iptables-service-type
                  (iptables-configuration
                   (ipv4-rules (plain-file "iptables.rules" "\
     *filter
     :INPUT ACCEPT [0:0]
     :FORWARD DROP [0:0]
     :OUTPUT ACCEPT [0:0]
     -A FORWARD -i br0 -o br0 -j ACCEPT
     COMMIT
     "))


File: guix-cookbook.it.info,  Node: Rete instradata per libvirt,  Next: Rete personalizzata basata su NAT per libvirt,  Prev: Ponte di rete per QEMU,  Up: Macchine virtuali

5.2 Rete instradata per libvirt
===============================

Se la macchina che ospita le tue macchine virtuali è collegata in
modalità wireless alla rete, non sarai in grado di usare un vero bridge
di rete come spiegato nella sezione precedente (*note Ponte di rete per
QEMU::). In questo caso, la prossima migliore opzione è usare uno
_switch di rete virtuale_ con routing statico e configurare una macchina
virtuale basata su libvirt per usarlo (tramite la GUI di ‘virt-manager’
per esempio). Questo è simile alla modalità di funzionamento predefinita
di QEMU/libvirt, tranne che invece di usare NAT (Network Address
Translation), si basa su rotte statiche per unire l’indirizzo IP della
VM (macchina virtuale) alla LAN (rete locale). Questo fornisce
connettività bidirezionale da e verso la macchina virtuale, che è
necessaria per esporre i servizi ospitati sulla macchina virtuale.

5.2.1 Creazione di uno switch di rete virtuale
----------------------------------------------

Uno switch di rete virtuale consiste in un dispositivo di rete virtuale
chiamato ‘bridge virtuale’, server DHCP (dnsmasq) e regole firewall
(iptables). Vedi l’articolo wiki di libvirt sulle Reti Virtuali
(https://wiki.libvirt.org/VirtualNetworking.html) per maggiori dettagli
sulle modalità di funzionamento, gestione e implementazione degli switch
di rete virtuali.

   Il comando ‘virsh’, fornito dal pacchetto ‘libvirt’, rende molto
facile creare uno switch virtuale. Per prima cosa devi scegliere una
sottorete di rete per il tuo switch virtuale; se la tua LAN domestica è
nella rete ‘192.168.1.0/24’, potresti optare per l’uso ad es.:
‘192.168.2.0/24’. Definisci un file XML, ad es.: ‘/tmp/virbr0.xml’,
contenente quanto segue:

     <network>
       <name>virbr0</name>
       <bridge name="virbr0" />
       <forward mode="route"/>
       <ip address="192.168.2.0" netmask="255.255.255.0">
         <dhcp>
           <range start="192.168.2.1" end="192.168.2.254"/>
         </dhcp>
       </ip>
     </network>

   Quindi crea e configura l’interfaccia usando il comando ‘virsh’, come
root:

     virsh net-define /tmp/virbr0.xml
     virsh net-autostart virbr0
     virsh net-start virbr0

   L’interfaccia ‘virbr0’ dovrebbe ora essere visibile ad es.: tramite
il comando ‘ip address’. Verrà avviata automaticamente ogni volta che la
tua macchina virtuale libvirt viene avviata.

5.2.2 Configurazione delle rotte statiche per il tuo bridge virtuale
--------------------------------------------------------------------

Se hai configurato la tua macchina virtuale per utilizzare la tua nuova
interfaccia bridge virtuale ‘virbr0’, dovrebbe già ricevere un IP
tramite DHCP come ‘192.168.2.15’ ed essere raggiungibile dal server che
la ospita, ad es.: tramite ‘ping 192.168.2.15’. C’è un’ultima
configurazione necessaria affinché la VM possa raggiungere la rete
esterna: aggiungere rotte statiche al router della rete.

   In questo esempio, la rete LAN è ‘192.168.1.0/24’ e la pagina web di
configurazione del router potrebbe essere accessibile ad es.: tramite la
pagina <http://192.168.1.1>. Su un router che esegue il firmware
libreCMC (https://librecmc.org/), dovresti navigare alla pagina Rete →
Rotte Statiche
(<https://192.168.1.1/cgi-bin/luci/admin/network/routes>), e
aggiungeresti una nuova voce a ‘Rotte IPv4 Statiche’ con le seguenti
informazioni:

‘Interfaccia’
     lan
‘Destinazione’
     192.168.2.0
‘Maschera di rete IPv4’
     255.255.255.0
‘Gateway IPv4’
     IP-SERVER
‘Tipo di rotta’
     unicast

   dove SERVER-IP è l’indirizzo IP della macchina che ospita le VM, che
dovrebbe essere statico.

   Dopo aver salvato/applicato questa nuova rotta statica, la
connettività esterna dovrebbe funzionare all’interno della tua VM; puoi
ad es.: eseguire ‘ping gnu.org’ per verificare che funzioni
correttamente.


File: guix-cookbook.it.info,  Node: Rete personalizzata basata su NAT per libvirt,  Next: Riferimenti VM,  Prev: Rete instradata per libvirt,  Up: Macchine virtuali

5.3 Rete personalizzata basata su NAT per libvirt
=================================================

Come menzionato nella sezione precedente (*note Rete instradata per
libvirt::), libvirt permette di definire reti virtuali tramite file XML
e di gestirle con il comando ‘virsh’. I dettagli della creazione e
rimozione di switch di rete virtuali sono gestiti da libvirt, quindi
l’utente non deve occuparsene.

   Tuttavia, la gestione degli switch di rete virtuali da parte di
libvirt può a volte entrare in conflitto con configurazioni di rete più
complesse. In particolare, le regole iptables inserite da libvirt per
gli switch che operano in modalità NAT possono entrare in conflitto con
regole iptables/nftables esistenti, portando a un filtraggio dei
pacchetti insicuro o interrotto.

   In questi casi, l’unica soluzione è configurare manualmente uno
switch di rete virtuale. Questa sezione fornirà istruzioni su come farlo
utilizzando i servizi del sistema Guix.

5.3.1 Creazione del bridge di rete virtuale
-------------------------------------------

Il ‘static-networking-service-type’ può essere usato per creare un
bridge di rete virtuale e assegnargli un indirizzo IP:

     (service static-networking-service-type
              (list (static-networking
                     ;; La fornitura predefinita è 'networking; se stai usando qualsiasi
                     ;; altro servizio con questa fornitura, come
                     ;; `network-manager-service-type`, allora devi cambiare il
                     ;; predefinito.
                     (provision '(static-networking))
                     (links
                      (list (network-link
                             (name "virbr0")
                             (type 'bridge)
                             (arguments '()))))
                     (addresses
                      (list (network-address
                             (device "virbr0")
                             (value "192.168.10.1/24")))))))

5.3.2 Esecuzione di dnsmasq per il bridge di rete virtuale
----------------------------------------------------------

Il ‘dnsmasq-service-type’ può essere usato per fornire DNS e DHCP per
gli ospiti connessi a questo switch di rete virtuale:

     (service dnsmasq-service-type
              (dnsmasq-configuration
               ;; Puoi avere più istanze di `dnsmasq-service-type` purché
               ;; ognuna abbia una diversa shepherd-provision.
               (shepherd-provision '(dnsmasq-virbr0))
               (extra-options (list
                               ;; Bind solo al bridge virtuale. Questo
                               ;; evita conflitti con altre istanze di
                               ;; dnsmasq in esecuzione.
                               "--except-interface=lo"
                               "--interface=virbr0"
                               "--bind-dynamic"
                               ;; Indirizzi IPv4 da offrire alle VM. Questo
                               ;; dovrebbe corrispondere alla sottorete scelta.
                               "--dhcp-range=192.168.10.2,192.168.10.254"))))

5.3.3 Configurazione del NAT per lo switch di rete virtuale
-----------------------------------------------------------

Se intendi utilizzare lo switch di rete virtuale in modalità NAT, dovrai
utilizzare le regole nftables (o iptables) per impostare il masquerading
IP. Il seguente esempio mostra come utilizzare ‘nftables-service-type’
per farlo:

     (service nftables-service-type
              (nftables-configuration
               (ruleset
                (plain-file "nftables.conf"
                            "\
     table inet filter {

       input catena {
         tipo filtro hook input priorità filtro; policy drop;
         # Aggiungi qui le tue regole di filtraggio pacchetti esistenti...
         iifname virbr0 udp dport 67 contatore accetta commento \"consenti DHCP su virbr0\"
         iifname virbr0 meta l4proto {tcp, udp} th dport 53 accetta \\
             commento \"consenti DNS su virbr0\"
       }

       chain forward {
         type filter hook forward priority filter; policy drop;
         # Aggiungi qui le tue regole di inoltro esistenti...
         iifname virbr0 accept comment \"consenti il traffico in uscita da virbr0\"
         oifname virbr0 ct state {established, related } accept \\
             comment \"consenti il traffico stabilito verso virbr0\"
       }

     }

     table inet nat {
       chain postrouting {
         type nat hook postrouting priority srcnat; policy accept;
         # Aggiungi qui le tue regole NAT esistenti...
         iifname virbr0 ip daddr { 224.0.0.0/24, 255.255.255.255/32 } return \\
             comment \"non mascherare verso blocchi di indirizzi riservati\"
         iifname virbr0 oifname != virbr0 masquerade \\
             comment \"mascherare tutto il traffico in uscita dalle VM\"
       }
     }
     "))))

   Assicurati di avere l’inoltro IPv4 abilitato (puoi usare
‘sysctl-service-type’ per questo).


File: guix-cookbook.it.info,  Node: Riferimenti VM,  Prev: Rete personalizzata basata su NAT per libvirt,  Up: Macchine virtuali

5.4 Riferimenti
===============

   • The (unofficial) libvirt Networking Handbook
     (https://jamielinux.com/docs/libvirt-networking-handbook/index.html)
     Nota che questa risorsa è piuttosto datata al momento della stesura
     (a marzo 2025, è stata aggiornata l’ultima volta nel 2015).
     Ciononostante, gli autori di questo capitolo l’hanno trovata una
     preziosa fonte di informazioni.


File: guix-cookbook.it.info,  Node: Gestione avanzata dei pacchetti,  Next: Sviluppo software,  Prev: Macchine virtuali,  Up: Top

6 Gestione avanzata dei pacchetti
*********************************

Guix è un gestore di pacchetti funzionale che offre molte funzionalità
oltre a ciò che i gestori di pacchetti più tradizionali possono fare.
Per i non iniziati, queste funzionalità potrebbero non avere casi d’uso
ovvi all’inizio. Lo scopo di questo capitolo è dimostrare alcuni
concetti avanzati di gestione dei pacchetti.

   *note (guix)Gestione dei pacchetti:: per un riferimento completo.

* Menu:

* Profili Guix in pratica::  Strategie per profili e manifesti multipli.


File: guix-cookbook.it.info,  Node: Profili Guix in pratica,  Up: Gestione avanzata dei pacchetti

6.1 Profili Guix in pratica
===========================

Guix fornisce una funzionalità molto utile che potrebbe essere piuttosto
estranea ai nuovi arrivati: i “profiles”. Sono un modo per raggruppare
le installazioni di pacchetti e tutti gli utenti sullo stesso sistema
sono liberi di usare quanti profili desiderano.

   Che tu sia uno sviluppatore o meno, potresti scoprire che più profili
ti offrono grande potenza e flessibilità. Sebbene spostino un po’ il
paradigma rispetto ai _gestori di pacchetti tradizionali_, sono molto
comodi da usare una volta che hai capito come configurarli.

     Nota: Questa sezione è una guida ragionata sull’uso di più profili.
     Precede ‘guix shell’ e la sua cache veloce dei profili (*note
     (guix.it)Invocare guix shell::).

     In molti casi, potresti scoprire che l’utilizzo di ‘guix shell’ per
     configurare l’ambiente di cui hai bisogno, quando ne hai bisogno,
     richiede meno lavoro rispetto al mantenimento di un profilo
     dedicato. A te la scelta!

   Se hai familiarità con ‘virtualenv’ di Python, puoi pensare a un
profilo come a una sorta di ‘virtualenv’ universale che può contenere
qualsiasi tipo di software, non solo software Python. Inoltre, i profili
sono autosufficienti: catturano tutte le dipendenze di runtime, il che
garantisce che tutti i programmi all’interno di un profilo funzioneranno
sempre in qualsiasi momento.

   Più profili offrono molti vantaggi:

   • Pulita separazione semantica dei vari pacchetti di cui un utente ha
     bisogno per diversi contesti.

   • È possibile rendere disponibili più profili nell’ambiente sia
     all’accesso che all’interno di una shell dedicata.

   • I profili possono essere caricati su richiesta. Ad esempio,
     l’utente può usare più shell, ognuna delle quali esegue profili
     diversi.

   • Isolamento: i programmi di un profilo non utilizzeranno i programmi
     dell’altro, e l’utente può persino installare diverse versioni
     degli stessi programmi nei due profili senza conflitto.

   • Deduplicazione: i profili condividono dipendenze che risultano
     essere esattamente le stesse. Questo rende più profili efficienti
     in termini di archiviazione.

   • Riproducibile: se utilizzato con manifest dichiarativi, un profilo
     può essere completamente specificato dal commit Guix attivo al
     momento della sua configurazione. Ciò significa che lo stesso
     identico profilo può essere configurato ovunque e in qualsiasi
     momento
     (https://guix.gnu.org/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my/),
     con le sole informazioni di commit. Consulta la sezione sui *note
     Profili riproducibili::.

   • Aggiornamenti e manutenzione più semplici: più profili rendono
     facile avere a portata di mano gli elenchi dei pacchetti e rendono
     gli aggiornamenti completamente senza attriti.

   Concretamente, ecco alcuni profili tipici:

   • Le dipendenze di un progetto su cui stai lavorando.

   • Le tue librerie di linguaggio di programmazione preferite.

   • Programmi specifici per laptop (come ‘powertop’) di cui non hai
     bisogno su un desktop.

   • TeXlive (questo può essere davvero utile quando hai bisogno di
     installare un solo pacchetto per un documento che hai appena
     ricevuto via email).

   • Giochi.

   Immergiamoci nella configurazione!

* Menu:

* Configurazione di base con i manifesti::  Configurazione di base con i
                                              manifesti
* Pacchetti richiesti::      Pacchetti richiesti
* Profilo predefinito::      Profilo predefinito
* I benefici dei manifesti::  I benefici dei manifesti
* Profili riproducibili::    Profili riproducibili


File: guix-cookbook.it.info,  Node: Configurazione di base con i manifesti,  Next: Pacchetti richiesti,  Up: Profili Guix in pratica

6.1.1 Configurazione di base con i manifesti
--------------------------------------------

Un profilo Guix può essere configurato via un “manifest”. Un manifest è
uno snippet di codice Scheme che specifica l’insieme di pacchetti che
desideri avere nel tuo profilo; assomiglia a questo:

     (specifications->manifest
       '("pacchetto-1"
         ;; Versione 1.3 del pacchetto-2.
         "pacchetto-2@1.3"
         ;; L'output "lib" del pacchetto-3.
         "pacchetto-3:lib"
         ; ...
         "pacchetto-N"))

   *Note (guix.it)Scrivere manifesti::, per maggiori informazioni sulla
sintassi.

   Possiamo creare una specifica di manifest per ogni profilo e
installarli in questo modo:

     GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
     mkdir -p "$GUIX_EXTRA_PROFILES"/my-project # se non esiste ancora
     guix package --manifest=/percorso/a/guix-my-project-manifest.scm \
      --profile="$GUIX_EXTRA_PROFILES"/my-project/my-project

   Qui impostiamo una variabile arbitraria ‘GUIX_EXTRA_PROFILES’ per
indicare la directory dove memorizzeremo i nostri profili nel resto di
questo articolo.

   Posizionare tutti i tuoi profili in una singola directory, con ogni
profilo che ottiene la propria sottodirectory, è un po’ più pulito. In
questo modo, ogni sottodirectory conterrà tutti i symlink per un solo
profilo. Inoltre, “iterare sui profili” diventa ovvio da qualsiasi
linguaggio di programmazione (ad esempio: uno script di shell)
semplicemente iterando sulle sottodirectory di ‘$GUIX_EXTRA_PROFILES’.

   Nota che è anche possibile scorrere l’output di

     guix package --list-profiles

   anche se probabilmente dovrai filtrare ‘~/.config/guix/current’.

   Per abilitare tutti i profili all’accesso, aggiungi questo al tuo
‘~/.bash_profile’ (o simile):

     for i in $GUIX_EXTRA_PROFILES/*; do
       profile=$i/$(basename "$i")
       if [ -f "$profile"/etc/profile ]; then
         GUIX_PROFILE="$profile"
         . "$GUIX_PROFILE"/etc/profile
       fi
       unset profile
     done

   Nota per gli utenti di Guix System: quanto sopra riflette come il tuo
profilo predefinito ‘~/.guix-profile’ viene attivato da ‘/etc/profile’,
quest’ultimo caricato da ‘~/.bashrc’ per impostazione predefinita.

   Puoi ovviamente scegliere di abilitarne solo un sottoinsieme:

     for i in "$GUIX_EXTRA_PROFILES"/my-project-1 "$GUIX_EXTRA_PROFILES"/my-project-2; do
       profile=$i/$(basename "$i")
       if [ -f "$profile"/etc/profile ]; then
         GUIX_PROFILE="$profile"
         . "$GUIX_PROFILE"/etc/profile
       fi
       unset profile
     done

   Quando un profilo è disabilitato, è semplice abilitarlo per una
singola shell senza "inquinare" il resto della sessione utente:

     GUIX_PROFILE="percorso/al/mio-progetto" ; . "$GUIX_PROFILE"/etc/profile

   La chiave per abilitare un profilo è _source_ il suo file
‘etc/profile’. Questo file contiene codice shell che esporta le
variabili d’ambiente corrette necessarie per attivare il software
contenuto nel profilo. È costruito automaticamente da Guix e destinato
all’esecuzione. Contiene le stesse variabili che otterresti eseguendo:

     guix package --search-paths=prefix --profile=$my_profile"

   Ancora una volta, vedi *note (guix.it)Invocare guix package:: per le
opzioni della riga di comando.

   Per aggiornare un profilo, è sufficiente installare di nuovo il
manifest:

     guix package -m /percorso/a/guix-my-project-manifest.scm \
      -p "$GUIX_EXTRA_PROFILES"/my-project/my-project

   Per aggiornare tutti i profili, è abbastanza facile scorrerli. Ad
esempio, supponendo che le specifiche del tuo manifest siano archiviate
in ‘~/.guix-manifests/guix-$profile-manifest.scm’, con ‘$profile’ che è
il nome del profilo (es.: "project1"), potresti fare quanto segue in una
shell Bourne:

     for profile in "$GUIX_EXTRA_PROFILES"/*; do
       guix package --profile="$profile" \
        --manifest="$HOME/.guix-manifests/guix-$profile-manifest.scm"
     done

   Ogni profilo ha le sue generazioni:

     guix package -p "$GUIX_EXTRA_PROFILES"/my-project/my-project --list-generations

   Puoi tornare indietro a qualsiasi generazione di un dato profilo:

     guix package -p "$GUIX_EXTRA_PROFILES"/my-project/my-project --switch-generations=17

   Infine, se vuoi passare a un profilo senza ereditare dall’ambiente
corrente, puoi attivarlo da una shell vuota:

     env -i $(which bash) --login --noprofile --norc
     . my-project/etc/profile


File: guix-cookbook.it.info,  Node: Pacchetti richiesti,  Next: Profilo predefinito,  Prev: Configurazione di base con i manifesti,  Up: Profili Guix in pratica

6.1.2 Pacchetti richiesti
-------------------------

L’attivazione di un profilo si riduce essenzialmente all’esportazione di
una serie di variabili d’ambiente. Questo è il ruolo del file
‘etc/profile’ all’interno del profilo.

   _Nota: verranno impostate solo le variabili d’ambiente dei pacchetti
che le consumano._

   Ad esempio, ‘MANPATH’ non verrà impostato se non esiste
un’applicazione che consuma le pagine man all’interno del profilo.
Quindi, se hai bisogno di accedere in modo trasparente alle pagine man
una volta caricato il profilo, hai due opzioni:

   • Esporta la variabile manualmente, ad esempio
          export MANPATH=/percorso/al/profilo${MANPATH:+:}$MANPATH

   • Oppure includi ‘man-db’ nel manifest del profilo.

   Lo stesso vale per ‘INFOPATH’ (puoi installare ‘info-reader’),
‘PKG_CONFIG_PATH’ (installa ‘pkg-config’), ecc.


File: guix-cookbook.it.info,  Node: Profilo predefinito,  Next: I benefici dei manifesti,  Prev: Pacchetti richiesti,  Up: Profili Guix in pratica

6.1.3 Profilo predefinito
-------------------------

Che dire del profilo predefinito che Guix mantiene in ‘~/.guix-profile’?

   Puoi assegnargli il ruolo che desideri. Tipicamente installeresti il
manifest dei pacchetti che vuoi usare sempre.

   In alternativa, potresti mantenerlo “senza manifest” per pacchetti
usa-e-getta che useresti solo per un paio di giorni. In questo modo è
comodo eseguire

     guix install package-foo
     guix upgrade package-bar

   senza dover specificare il percorso di un profilo.


File: guix-cookbook.it.info,  Node: I benefici dei manifesti,  Next: Profili riproducibili,  Prev: Profilo predefinito,  Up: Profili Guix in pratica

6.1.4 I benefici dei manifesti
------------------------------

I manifest ti permettono di “declare” l’insieme di pacchetti che
vorresti avere in un profilo (*note (guix.it)Scrivere manifesti::). Sono
un modo conveniente per tenere a portata di mano gli elenchi dei
pacchetti e, ad esempio, sincronizzarli su più macchine utilizzando un
sistema di controllo versione.

   Una lamentela comune sui manifest è che possono essere lenti da
installare quando contengono un gran numero di pacchetti. Questo è
particolarmente ingombrante quando si desidera solo un aggiornamento per
un pacchetto all’interno di un manifest grande.

   Questo è un motivo in più per utilizzare più profili, che si rivelano
perfetti per suddividere i manifest in più insiemi di pacchetti
semanticamente collegati. L’utilizzo di più profili piccoli offre
maggiore flessibilità e usabilità.

   I manifest offrono numerosi vantaggi. In particolare, facilitano la
manutenzione:

   • Quando un profilo viene configurato da un manifest, il manifest
     stesso è autosufficiente per mantenere un “elenco di pacchetti” e
     reinstallare il profilo in seguito o su un sistema diverso. Per i
     profili ad-hoc, dovremmo generare manualmente una specifica di
     manifest e mantenere le versioni dei pacchetti per i pacchetti che
     non utilizzano la versione predefinita.

   • ‘guix package --upgrade’ tenta sempre di aggiornare i pacchetti che
     hanno input propagati, anche se non c’è nulla da fare. I manifest
     di Guix rimuovono questo problema.

   • Quando si aggiorna parzialmente un profilo, possono sorgere
     conflitti (a causa di dipendenze divergenti tra i pacchetti
     aggiornati e quelli non aggiornati) e possono essere fastidiosi da
     risolvere manualmente. I manifest eliminano del tutto questo
     problema, poiché tutti i pacchetti vengono sempre aggiornati
     contemporaneamente.

   • Come accennato in precedenza, i manifest consentono profili
     riproducibili, mentre i comandi imperativi ‘guix install’, ‘guix
     upgrade’, ecc. non lo fanno, poiché producono profili diversi ogni
     volta anche quando contengono gli stessi pacchetti. Vedi la
     discussione correlata sull’argomento
     (https://issues.guix.gnu.org/issue/33285).

   • Le specifiche dei manifest sono utilizzabili da altri comandi
     ‘guix’. Ad esempio, puoi eseguire ‘guix weather -m manifest.scm’
     per vedere quanti sostituti sono disponibili, il che può aiutarti a
     decidere se vuoi provare ad aggiornare oggi o aspettare un po’. Un
     altro esempio: puoi eseguire ‘guix pack -m manifest.scm’ per creare
     un pacchetto contenente tutti i pacchetti nel manifest (e i loro
     riferimenti transitivi).

   • Infine, i manifest hanno una rappresentazione Scheme, il tipo di
     record ‘<manifest>’. Possono essere manipolati in Scheme e passati
     alle varie API
     (https://it.wikipedia.org/wiki/Application_programming_interface)
     di Guix.

   È importante capire che, sebbene i manifest possano essere usati per
dichiarare i profili, non sono strettamente equivalenti: i profili hanno
l’effetto collaterale di “fissare” i pacchetti nello store, il che
impedisce che vengano raccolti dalla spazzatura (*note (guix.it)Invocare
guix gc::) e assicura che saranno ancora disponibili in qualsiasi
momento in futuro. Il comando ‘guix shell’ protegge anche i profili
usati di recente dalla raccolta della spazzatura; i profili che non sono
stati usati per un po’ possono essere comunque raccolti dalla
spazzatura, insieme ai pacchetti a cui si riferiscono.

   Per essere sicuri al 100% che un dato profilo non verrà mai raccolto,
installare il manifest in un profilo e usare ‘GUIX_PROFILE=/il/profilo;
. "$GUIX_PROFILE"/etc/profile’ come spiegato sopra: questo garantisce
che il nostro ambiente di hacking sarà sempre disponibile.

   _Avviso di sicurezza:_ Sebbene mantenere i vecchi profili possa
essere comodo, tieni presente che i pacchetti obsoleti potrebbero non
aver ricevuto le ultime correzioni di sicurezza.


File: guix-cookbook.it.info,  Node: Profili riproducibili,  Prev: I benefici dei manifesti,  Up: Profili Guix in pratica

6.1.5 Profili riproducibili
---------------------------

Per riprodurre un profilo bit per bit, abbiamo bisogno di due
informazioni:

   • un manifest (*note (guix.it)Scrivere manifesti::);
   • una specifica di canale Guix (*note (guix.it)Replicare Guix::).

   Infatti, i soli manifest potrebbero non essere sufficienti: diverse
versioni di Guix (o diversi canali) possono produrre output diversi per
un dato manifest.

   È possibile generare la specifica del canale Guix con ‘guix describe
--format=channels’ (*note (guix)Invocare guix describe::). Salva questo
in un file, ad esempio ‘channel-specs.scm’.

   Su un altro computer, è possibile utilizzare il file di specifica del
canale e il manifest per riprodurre lo stesso identico profilo:

     GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
     GUIX_EXTRA=$HOME/.guix-extra

     mkdir -p "$GUIX_EXTRA"/my-project
     guix pull --channels=channel-specs.scm --profile="$GUIX_EXTRA/my-project/guix"

     mkdir -p "$GUIX_EXTRA_PROFILES/my-project"
     "$GUIX_EXTRA"/my-project/guix/bin/guix package \
      --manifest=/percorso/a/guix-my-project-manifest.scm \
      --profile="$GUIX_EXTRA_PROFILES"/my-project/my-project

   È sicuro eliminare il profilo del canale Guix che hai appena
installato con la specifica del canale, il profilo del progetto non
dipende da esso.


File: guix-cookbook.it.info,  Node: Sviluppo software,  Next: Gestione dell'ambiente,  Prev: Gestione avanzata dei pacchetti,  Up: Top

7 Sviluppo software
*******************

Guix è uno strumento utile per gli sviluppatori; ‘guix shell’, in
particolare, fornisce un ambiente di sviluppo autonomo per il tuo
pacchetto, indipendentemente dal linguaggio/i in cui è scritto (*note
(guix.it)Invocare guix shell::). Per beneficiarne, devi inizialmente
scrivere una definizione di pacchetto e averla in Guix stesso, o in un
canale, o direttamente nell’albero sorgente del tuo progetto come file
‘guix.scm’. Quest’ultima opzione è allettante: tutto ciò che gli
sviluppatori devono fare per iniziare è clonare il repository del
progetto ed eseguire ‘guix shell’, senza argomenti.

   Le esigenze di sviluppo vanno oltre gli ambienti di sviluppo. Come
possono gli sviluppatori eseguire l’integrazione continua del loro
codice negli ambienti di costruzione di Guix? Come possono consegnare il
loro codice direttamente agli utenti più avventurosi? Questo capitolo
descrive un insieme di file che gli sviluppatori possono aggiungere al
loro repository per configurare ambienti di sviluppo basati su Guix,
integrazione continua e consegna continua — tutto in una volta sola(1).

* Menu:

* Per iniziare::             Passo 0: usare ‘guix shell’.
* Costruire con Guix::       Passo 1: compilare il tuo codice.
* Il repository come canale::  Passo 2: trasformare il repo in un canale.
* Varianti di pacchetto::    Bonus: Definire le varianti.
* Configurazione dell'integrazione continua::  Passo 3: integrazione
                                                 continua.
* Manifesto di build::       Bonus: Manifesto.
* In conclusione::           Riepilogo.

   ---------- Footnotes ----------

   (1) Questo capitolo è adattato da un post del blog
(https://guix.gnu.org/en/blog/2023/from-development-environments-to-continuous-integrationthe-ultimate-guide-to-software-development-with-guix/)
pubblicato a giugno 2023 sul sito web di Guix.


File: guix-cookbook.it.info,  Node: Per iniziare,  Next: Costruire con Guix,  Up: Sviluppo software

7.1 Per iniziare
================

Come “Guixificare” un repository? Il primo passo, come abbiamo visto,
sarà aggiungere un file ‘guix.scm’ alla radice del repository in
questione. Prenderemo Guile (https://www.gnu.org/software/guile) come
esempio in questo capitolo: è scritto principalmente in Scheme e C, e ha
una serie di dipendenze — una toolchain di compilazione C, librerie C,
Autoconf e i suoi amici, LaTeX, e così via. Il file ‘guix.scm’
risultante assomiglia alla solita definizione di pacchetto (*note
(guix)Definire i pacchetti::), solo senza il pezzo ‘define-public’:

     ;; Il file «guix.scm» per Guile, da usare con «guix shell».

     (use-modules (guix)
                  (guix build-system gnu)
                  ((guix licenses) #:prefix license:)
                  (gnu packages autotools)
                  (gnu packages base)
                  (gnu packages bash)
                  (gnu packages bdw-gc)
                  (gnu packages compression)
                  (gnu packages flex)
                  (gnu packages gdb)
                  (gnu packages gettext)
                  (gnu packages gperf)
                  (gnu packages libffi)
                  (gnu packages libunistring)
                  (gnu packages linux)
                  (gnu packages pkg-config)
                  (gnu packages readline)
                  (gnu packages tex)
                  (gnu packages texinfo)
                  (gnu packages version-control))

     (package
       (name "guile")
       (version "3.0.99-git")                          ;numero di versione strano
       (source #f)                                     ;nessuna fonte
       (build-system gnu-build-system)
       (native-inputs
        (append (list autoconf
                      automake
                      libtool
                      gnu-gettext
                      flex
                      texinfo
                      texlive-base                 ;per "make pdf"
                      texlive-epsf
                      gperf
                      git
                      gdb
                      strace
                      readline
                      lzip
                      pkg-config)

                ;; Quando si esegue la compilazione incrociata, è necessaria una
                ;; versione nativa di Guile.
                (if (%current-target-system)
                    (list this-package)
                    '())))
       (inputs
        (list libffi bash-minimal))
       (propagated-inputs
        (list libunistring libgc))

       (native-search-paths
        (list (search-path-specification
               (variable "GUILE_LOAD_PATH")
               (files '("share/guile/site/3.0")))
              (search-path-specification
               (variable "GUILE_LOAD_COMPILED_PATH")
               (files '("lib/guile/3.0/site-ccache")))))
       (synopsis "Implementazione Scheme destinata in particolare alle estensioni")
       (description
        "Guile è il Linguaggio Intelligente Onnipresente GNU per le Estensioni,
     ed è in realtà un'implementazione Scheme completa!")
       (home-page "https://www.gnu.org/software/guile/")
       (license license:lgpl3+))

   Un bel po’ di codice standard, ma ora chiunque voglia mettere mano a
Guile deve solo eseguire:

     guix shell

   Questo fornisce loro una shell contenente tutte le dipendenze di
Guile: quelle elencate sopra, ma anche _dipendenze implicite_ come la
tool chain GCC, GNU Make, sed, grep e così via. *Note (guix.it)Invocare
guix shell::, per maggiori informazioni su ‘guix shell’.

     Il consiglio dello chef: Il nostro suggerimento è di creare
     ambienti di sviluppo come questo:

          guix shell --container --link-profile

     ... o, in breve:

          guix shell -CP

     Questo fornisce una shell in un contenitore isolato, e tutte le
     dipendenze appaiono in ‘$HOME/.guix-profile’, che funziona bene con
     le cache come ‘config.cache’ (*note (autoconf)File Cache::) e i
     nomi di file assoluti registrati nei ‘Makefile’ generati e simili.
     Il fatto che la shell venga eseguita in un contenitore porta
     tranquillità: nulla, tranne la directory corrente e le dipendenze
     di Guile, è visibile all’interno del contenitore; nulla del sistema
     può interferire con il tuo sviluppo.


File: guix-cookbook.it.info,  Node: Costruire con Guix,  Next: Il repository come canale,  Prev: Per iniziare,  Up: Sviluppo software

7.2 Livello 1: Costruire con Guix
=================================

Ora che abbiamo una definizione di pacchetto (*note Per iniziare::),
perché non approfittarne anche per costruire Guile con Guix? Avevamo
lasciato il campo ‘source’ vuoto, perché ‘guix shell’ si occupa solo
degli _inputs_ del nostro pacchetto — in modo da poter configurare
l’ambiente di sviluppo — non del pacchetto stesso.

   Per costruire il pacchetto con Guix, dovremo compilare il campo
‘source’, seguendo queste linee:

     (use-modules (guix)
                  (guix git-download)  ;per ‘git-predicate’
                  ...)

     (define vcs-file?
       ;; Restituisce vero se il file dato è sotto controllo di versione.
       (or (git-predicate (current-source-directory))
           (const #t)))                                ;non in un checkout Git

     (package
       (name "guile")
       (version "3.0.99-git")                          ;numero di versione strano
       (source (local-file "." "guile-checkout"
                           #:recursive? #t
                           #:select? vcs-file?))
       ...)

   Ecco cosa abbiamo cambiato rispetto alla sezione precedente:

  1. Abbiamo aggiunto ‘(guix git-download)’ al nostro set di moduli
     importati, in modo da poter utilizzare la sua procedura
     ‘git-predicate’.
  2. Abbiamo definito ‘vcs-file?’ come una procedura che restituisce
     vero quando le viene passato un file sotto controllo di versione.
     Per sicurezza, aggiungiamo un caso di fallback per quando non siamo
     in un checkout Git: restituiamo sempre vero.
  3. Abbiamo impostato ‘source’ su un ‘local-file’
     (https://guix.gnu.org/manual/devel/it/html_node/G_002dexpression.html#index-local_002dfile)
     — una copia ricorsiva della directory corrente (‘"."’), limitata ai
     file sotto controllo di versione (il pezzo ‘#:select?’).

   Da qui in poi, il nostro file ‘guix.scm’ serve a un secondo scopo: ci
permette di costruire il software con Guix. Il punto principale della
costruzione con Guix è che si tratta di una costruzione “pulita” — puoi
essere sicuro che nulla dal tuo albero di lavoro o dal sistema
interferisca con il risultato della costruzione — e ti permette di
testare una varietà di cose. Innanzitutto, puoi fare una semplice
costruzione nativa:

     guix build -f guix.scm

   Ma puoi anche costruire per un altro sistema (eventualmente dopo aver
configurato *note scaricamento: (guix.it)Configurazione dello scarico
del demone. o *note emulazione trasparente: (guix.it)Servizi di
virtualizzazione.):

     guix build -f guix.scm -s aarch64-linux -s riscv64-linux

... o compilare incrociando:

     guix build -f guix.scm --target=x86_64-w64-mingw32

   È inoltre possibile utilizzare le “trasformazioni di pacchetto” per
testare le varianti di pacchetto (*note (guix.it)Opzioni di
trasformazione dei pacchetti::):

     # E se costruissimo con Clang invece di GCC?
     guix build -f guix.scm \
       --with-c-toolchain=guile@3.0.99-git=clang-toolchain

     # E quel flag di configurazione poco testato?
     guix build -f guix.scm \
       --with-configure-flag=guile@3.0.99-git=--disable-networking

   Comodo!


File: guix-cookbook.it.info,  Node: Il repository come canale,  Next: Varianti di pacchetto,  Prev: Costruire con Guix,  Up: Sviluppo software

7.3 Livello 2: Il Repository come Canale
========================================

Ora abbiamo un repository Git contenente (tra le altre cose) una
definizione di pacchetto (*note Costruire con Guix::). Non possiamo
trasformarlo in un “channel” (*note (guix.it)Canali::)? Dopotutto, i
canali sono progettati per spedire le definizioni dei pacchetti agli
utenti, ed è esattamente quello che stiamo facendo con il nostro
‘guix.scm’.

   Si scopre che possiamo effettivamente trasformarlo in un canale, ma
con una cautela: dobbiamo creare una directory separata per il/i file
‘.scm’ del nostro canale in modo che ‘guix pull’ non carichi file ‘.scm’
non correlati quando qualcuno scarica il canale — e in Guile ce ne sono
molti! Quindi inizieremo così, mantenendo un symlink ‘guix.scm’ di primo
livello per il bene di ‘guix shell’:

     mkdir -p .guix/modules
     mv guix.scm .guix/modules/guile-package.scm
     ln -s .guix/modules/guile-package.scm guix.scm

   Per renderlo utilizzabile come parte di un canale, dobbiamo
trasformare il nostro file ‘guix.scm’ in un “modulo pacchetto” (*note
(guix.it)Moduli di pacchetti::): lo facciamo cambiando la forma
‘use-modules’ in alto in una forma ‘define-module’. Dobbiamo anche
effettivamente _export_ una variabile pacchetto, con ‘define-public’,
pur restituendo il valore del pacchetto alla fine del file in modo da
poter ancora usare ‘guix shell’ e ‘guix build -f guix.scm’. Il risultato
finale assomiglia a questo (non ripetendo cose che non sono cambiate):

     (define-module (guile-package)
       #:use-module (guix)
       #:use-module (guix git-download)   ;per ‘git-predicate’
       ...)

     (define vcs-file?
       ;; Restituisce vero se il file dato è sotto controllo di versione.
       (or (git-predicate (dirname (dirname (current-source-directory))))
           (const #t)))                                ;non in un checkout Git

     (define-public guile
       (package
         (name "guile")
         (version "3.0.99-git")                          ;numero di versione strano
         (source (local-file "../.." "guile-checkout"
                             #:recursive? #t
                             #:select? vcs-file?))
         ...))

     ;; Restituisce l'oggetto pacchetto definito sopra alla fine del modulo.
     guile

   Ci serve un’ultima cosa: un file ‘.guix-channel’
(https://guix.gnu.org/manual/devel/en/html_node/Package-Modules-in-a-Sub_002ddirectory.html)
in modo che Guix sappia dove cercare i moduli dei pacchetti nel nostro
repository:

     ;; Questo file ci permette di presentare questo repository come un canale Guix.

     (channel
       (version 0)
       (directory ".guix/modules"))  ;cerca i moduli dei pacchetti sotto .guix/modules/

   Per ricapitolare, ora abbiamo questi file:

     .
     ├── .guix-channel
     ├── guix.scm → .guix/modules/guile-package.scm
     └── .guix
         └── modules
            └── guile-package.scm

   E questo è tutto: abbiamo un canale! (Potremmo fare di meglio e
supportare _l’autenticazione del canale_
(https://guix.gnu.org/manual/devel/en/html_node/Specifying-Channel-Authorizations.html)
in modo che gli utenti sappiano di scaricare codice autentico. Ti
risparmiamo i dettagli qui, ma vale la pena considerarlo!) Gli utenti
possono scaricare da questo canale aggiungendolo a
‘~/.config/guix/channels.scm’
(https://guix.gnu.org/manual/devel/en/html_node/Specifying-Additional-Channels.html),
secondo queste linee:

     (append (list (channel
                     (name 'guile)
                     (url "https://git.savannah.gnu.org/git/guile.git")
                     (branch "main")))
             %default-channels)

   Dopo aver eseguito ‘guix pull’, possiamo vedere il nuovo pacchetto:

     $ guix describe
     Generazione 264  26 maggio 2023 16:00:35    (corrente)
       guile 36fd2b4
         URL repository: https://git.savannah.gnu.org/git/guile.git
         ramo: main
         commit: 36fd2b4920ae926c79b936c29e739e71a6dff2bc
       guix c5bc698
         URL repository: https://git.guix.gnu.org/guix.git
         commit: c5bc698e8922d78ed85989985cc2ceb034de2f23
     $ guix package -A ^guile$
     guile   3.0.99-git      out,debug       guile-package.scm:51:4
     guile   3.0.9           out,debug       gnu/packages/guile.scm:317:2
     guile   2.2.7           out,debug       gnu/packages/guile.scm:258:2
     guile   2.2.4           out,debug       gnu/packages/guile.scm:304:2
     guile   2.0.14          out,debug       gnu/packages/guile.scm:148:2
     guile   1.8.8           out             gnu/packages/guile.scm:77:2
     $ guix build guile@3.0.99-git
     [...]
     /gnu/store/axnzbl89yz7ld78bmx72vpqp802dwsar-guile-3.0.99-git-debug
     /gnu/store/r34gsij7f0glg2fbakcmmk0zn4v62s5w-guile-3.0.99-git

   È così che, come sviluppatore, consegni il tuo software direttamente
nelle mani degli utenti! Nessun intermediario, eppure nessuna perdita di
trasparenza e tracciamento della provenienza.

   Con questo in atto, diventa anche banale per chiunque creare immagini
Docker, pacchetti Deb/RPM o un semplice tarball con ‘guix pack’ (*note
(guix.it)Invocare guix pack::):

     # Che ne dici di un'immagine Docker del nostro snapshot Guile?
     guix pack -f docker -S /bin=bin guile@3.0.99-git

     # E un RPM rilocabile?
     guix pack -f rpm -R -S /bin=bin guile@3.0.99-git


File: guix-cookbook.it.info,  Node: Varianti di pacchetto,  Next: Configurazione dell'integrazione continua,  Prev: Il repository come canale,  Up: Sviluppo software

7.4 Bonus: Varianti di Pacchetto
================================

Ora abbiamo un canale effettivo, ma contiene un solo pacchetto (*note Il
repository come canale::). Già che ci siamo, possiamo definire “varianti
di pacchetto” (*note (guix.it)Definire varianti di pacchetto::) nel
nostro file ‘guile-package.scm’, varianti che vogliamo poter testare
come sviluppatori Guile — in modo simile a quanto fatto sopra con le
opzioni di trasformazione. Possiamo aggiungerle così:

     ;; Questo è il file «.guix/modules/guile-package.scm».

     (define-module (guile-package)
       ...)

     (define-public guile
       ...)

     (define (package-with-configure-flags p flags)
       "Restituisce P con FLAGS come flag 'configure' aggiuntivi."
       (package/inherit p
         (arguments
          (substitute-keyword-arguments (package-arguments p)
            ((#:configure-flags original-flags #~(list))
             #~(append #$original-flags #$flags))))))

     (define-public guile-without-threads
       (package
         (inherit (package-with-configure-flags guile
                                                #~(list "--without-threads")))
         (name "guile-without-threads")))

     (define-public guile-without-networking
       (package
         (inherit (package-with-configure-flags guile
                                                #~(list "--disable-networking")))
         (name "guile-without-networking")))


     ;; Restituisce l'oggetto pacchetto definito sopra alla fine del modulo.
     guile

   Possiamo costruire queste varianti come pacchetti regolari una volta
che abbiamo scaricato il canale. In alternativa, da un checkout di
Guile, possiamo eseguire un comando come questo dal livello superiore:

     guix build -L $PWD/.guix/modules guile-without-threads


File: guix-cookbook.it.info,  Node: Configurazione dell'integrazione continua,  Next: Manifesto di build,  Prev: Varianti di pacchetto,  Up: Sviluppo software

7.5 Livello 3: Configurazione dell’Integrazione Continua
========================================================

Il canale che abbiamo definito sopra (*note Il repository come canale::)
diventa ancora più interessante una volta che configuriamo
“l’integrazione continua”
(https://it.wikipedia.org/wiki/Integrazione_continua) (CI). Ci sono
diversi modi per farlo.

   Puoi utilizzare uno degli strumenti di integrazione continua più
diffusi, come GitLab-CI. Per farlo, devi assicurarti di eseguire i job
in un’immagine Docker o in una macchina virtuale che abbia Guix
installato. Se lo facessimo nel caso di Guile, avremmo un job che esegue
un comando shell come questo:

     guix build -L $PWD/.guix/modules guile@3.0.99-git

   Fare questo funziona alla grande e ha il vantaggio di essere facile
da ottenere sulla tua piattaforma CI preferita.

   Detto questo, otterrai il massimo usandoti di Cuirass
(https://guix.gnu.org/it/cuirass), uno strumento di CI progettato e
strettamente integrato con Guix. Usarlo richiede più lavoro rispetto
all’utilizzo di uno strumento di CI ospitato perché devi prima
configurarlo, ma quella fase di configurazione è notevolmente
semplificata se usi il suo servizio Guix System (*note
(guix.it)Integrazione continua::). Tornando al nostro esempio, diamo a
Cuirass un file di specifica che assomiglia a questo:

     ;; File di specifica Cuirass per costruire tutti i pacchetti del canale «guile».
     (list (specification
             (name "guile")
             (build '(channels guile))
             (channels
              (append (list (channel
                              (name 'guile)
                              (url "https://git.savannah.gnu.org/git/guile.git")
                              (branch "main")))
                      %default-channels))))

   Differisce da ciò che faresti con altri strumenti di CI in due modi
importanti:

   • Cuirass sa che sta tracciando _two_ canali, ‘guile’ e ‘guix’.
     Infatti, il nostro pacchetto ‘guile’ dipende da molti pacchetti
     forniti dal canale ‘guix’ — GCC, la GNU libc, libffi, e così via.
     Le modifiche ai pacchetti del canale ‘guix’ possono potenzialmente
     influenzare la nostra build di ‘guile’ e questo è qualcosa che
     vorremmo vedere il prima possibile come sviluppatori Guile.
   • I risultati della costruzione non vengono scartati: possono essere
     distribuiti come “sostituti” in modo che gli utenti del nostro
     canale ‘guile’ ottengano in modo trasparente i binari precompilati!
     (*note (guix.it)Sostituti::, per informazioni di base sui
     sostituti.)

   Dal punto di vista di uno sviluppatore, il risultato finale è questa
pagina di stato (https://ci.guix.gnu.org/jobset/guile) che elenca le
_evaluations_: ogni valutazione è una combinazione di commit dei canali
‘guix’ e ‘guile’ che fornisce un numero di _job_ — un job per pacchetto
definito in ‘guile-package.scm’ moltiplicato per il numero di
architetture di destinazione.

   Per quanto riguarda i sostituti, sono gratuiti! Ad esempio, poiché il
nostro jobset ‘guile’ è costruito su ci.guix.gnu.org, che esegue ‘guix
publish’ (*note (guix.it)Invocare guix publish::) oltre a Cuirass, si
ottengono automaticamente i sostituti per le build di ‘guile’ da
ci.guix.gnu.org; non è necessario alcun lavoro aggiuntivo per questo.


File: guix-cookbook.it.info,  Node: Manifesto di build,  Next: In conclusione,  Prev: Configurazione dell'integrazione continua,  Up: Sviluppo software

7.6 Bonus: Manifest di costruzione
==================================

La specifica Cuirass sopra è comoda: costruisce ogni pacchetto nel
nostro canale, che include alcune varianti (*note Configurazione
dell'integrazione continua::). Tuttavia, questo potrebbe essere
insufficientemente espressivo in alcuni casi: si potrebbero volere
specifici job di cross-compilazione, trasformazioni, immagini Docker,
pacchetti RPM/Deb, o persino test di sistema.

   Per ottenere ciò, puoi scrivere un “manifest” (*note
(guix.it)Scrivere manifesti::). Quello che abbiamo per Guile ha voci per
le varianti di pacchetto che abbiamo definito sopra, così come varianti
aggiuntive e build incrociate:

     ;; Questo è «.guix/manifest.scm».

     (use-modules (guix)
                  (guix profiles)
                  (guile-package))   ;importa il nostro modulo pacchetto

     (define* (package->manifest-entry* package system
                                        #:key target)
       "Restituisce una voce di manifest per PACKAGE su SYSTEM, opzionalmente cross-compilato su
     TARGET."
       (manifest-entry
         (inherit (package->manifest-entry package))
         (name (string-append (package-name package) "." system
                              (if target
                                  (string-append "." target)
                                  "")))
         (item (with-parameters ((%current-system system)
                                 (%current-target-system target))
                 package))))

     (define native-builds
       (manifest
        (append (map (lambda (system)
                       (package->manifest-entry* guile system))

                     '("x86_64-linux" "i686-linux"
                       "aarch64-linux" "armhf-linux"
                       "powerpc64le-linux"))
                (map (lambda (guile)
                       (package->manifest-entry* guile "x86_64-linux"))
                     (cons (package
                             (inherit (package-with-c-toolchain
                                       guile
                                       `(("clang-toolchain"
                                          ,(specification->package
                                            "clang-toolchain")))))
                             (name "guile-clang"))
                           (list guile-without-threads
                                 guile-without-networking
                                 guile-debug
                                 guile-strict-typing))))))

     (define cross-builds
       (manifest
        (map (lambda (target)
               (package->manifest-entry* guile "x86_64-linux"
                                         #:target target))
             '("i586-pc-gnu"
               "aarch64-linux-gnu"
               "riscv64-linux-gnu"
               "i686-w64-mingw32"
               "x86_64-linux-gnu"))))

     (concatenate-manifests (list native-builds cross-builds))

   Non entreremo nei dettagli di questo manifest; basti dire che
fornisce flessibilità aggiuntiva. Ora dobbiamo dire a Cuirass di
costruire questo manifest, cosa che si fa con una specifica leggermente
diversa dalla precedente:

     ;; File di specifica Cuirass per costruire tutti i pacchetti del canale «guile».
     (list (specification
             (name "guile")
             (build '(manifest ".guix/manifest.scm"))
             (channels
              (append (list (channel
                              (name 'guile)
                              (url "https://git.savannah.gnu.org/git/guile.git")
                              (branch "main")))
                      %default-channels))))

   Abbiamo cambiato la parte ‘(build ...)’ della specifica in
‘'(manifest ".guix/manifest.scm")’ in modo che prelevasse il nostro
manifest, e questo è tutto!


File: guix-cookbook.it.info,  Node: In conclusione,  Prev: Manifesto di build,  Up: Sviluppo software

7.7 In conclusione
==================

Abbiamo scelto Guile come esempio in questo capitolo e puoi vedere il
risultato qui:

   • ‘.guix-channel’
     (https://git.savannah.gnu.org/cgit/guile.git/tree/.guix-channel?id=cd57379b3df636198d8cd8e76c1bfbc523762e79);
   • ‘.guix/modules/guile-package.scm’
     (https://git.savannah.gnu.org/cgit/guile.git/tree/.guix/modules/guile-package.scm?id=cd57379b3df636198d8cd8e76c1bfbc523762e79)
     con il symlink ‘guix.scm’ di primo livello;
   • ‘.guix/manifest.scm’
     (https://git.savannah.gnu.org/cgit/guile.git/tree/.guix/manifest.scm?id=cd57379b3df636198d8cd8e76c1bfbc523762e79).

   Al giorno d’oggi, i repository sono spesso cosparsi di file nascosti
per vari strumenti: ‘.envrc’, ‘.gitlab-ci.yml’, ‘.github/workflows’,
‘Dockerfile’, ‘.buildpacks’, ‘Aptfile’, ‘requirements.txt’, e così via.
Potrebbe sembrare che stiamo proponendo un mucchio di file _additional_,
ma in realtà questi file sono sufficientemente espressivi da
_sostituire_ la maggior parte o tutti quelli elencati sopra.

   Con un paio di file, otteniamo il supporto per:

   • ambienti di sviluppo (‘guix shell’);
   • build di test pulite, incluse per varianti di pacchetti e per la
     cross-compilazione (‘guix build’);
   • integrazione continua (con Cuirass o con qualche altro strumento);
   • consegna continua agli utenti (_via_ il canale e con binari
     precompilati);
   • generazione di artefatti di build derivati come immagini Docker o
     pacchetti Deb/RPM (‘guix pack’).

   Questo è un bel set di strumenti unificato (a nostro avviso!) per il
deployment riproducibile del software, e un’illustrazione di come tu,
come sviluppatore, puoi trarne beneficio!


File: guix-cookbook.it.info,  Node: Gestione dell'ambiente,  Next: Reproducible Research,  Prev: Sviluppo software,  Up: Top

8 Gestione dell’ambiente
************************

Guix fornisce numerosi strumenti per gestire l’ambiente. Questo capitolo
illustra tali utilità.

* Menu:

* Ambiente Guix tramite direnv::  Configura l’ambiente Guix con direnv


File: guix-cookbook.it.info,  Node: Ambiente Guix tramite direnv,  Up: Gestione dell'ambiente

8.1 Ambiente Guix tramite direnv
================================

Guix fornisce un pacchetto ‘direnv’, che potrebbe estendere la shell
dopo il cambio di directory. Questo strumento potrebbe essere usato per
preparare un ambiente Guix puro.

   L’esempio seguente fornisce una funzione di shell per il file
‘~/.direnvrc’, che potrebbe essere utilizzata dal repository Git di Guix
nel file ‘~/src/guix/.envrc’ per configurare un ambiente di build simile
a quello descritto in *note (guix.it)Costruire da Git::.

   Crea un file ‘~/.direnvrc’ con codice Bash:

     # Grazie a <https://github.com/direnv/direnv/issues/73#issuecomment-152284914>
     export_function()
     {
       local name=$1
       local alias_dir=$PWD/.direnv/aliases
       mkdir -p "$alias_dir"
       PATH_add "$alias_dir"
       local target="$alias_dir/$name"
       if declare -f "$name" >/dev/null; then
         echo "#!$SHELL" > "$target"
         declare -f "$name" >> "$target" 2>/dev/null
         # Notare che aggiungiamo variabili di shell al trigger della funzione.
         echo "$name \$*" >> "$target"
         chmod +x "$target"
       fi
     }

     use_guix()
     {
         # Imposta il token GitHub.
         export GUIX_GITHUB_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

         # Disattiva 'GUIX_PACKAGE_PATH'.
         export GUIX_PACKAGE_PATH=""

         # Ricrea una radice del garbage collector.
         gcroots="$HOME/.config/guix/gcroots"
         mkdir -p "$gcroots"
         gcroot="$gcroots/guix"
         if [ -L "$gcroot" ]
         then
             rm -v "$gcroot"
         fi

         # Pacchetti vari.
         PACKAGES_MAINTENANCE=(
             direnv
             git
             git:send-email
             git-cal
             gnupg
             guile-colorized
             guile-readline
             less
             ncurses
             openssh
             xdot
         )

         # Pacchetti ambiente.
         PACKAGES=(help2man guile-sqlite3 guile-gcrypt)

         # Grazie a <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html>
         eval "$(guix shell --search-paths --root="$gcroot" --pure \
          --development guix ${PACKAGES[@]} ${PACKAGES_MAINTENANCE[@]} "$@")"

         # Predefinisci i flag di configurazione.
         configure()
         {
             ./configure
         }
         export_function configure

         # Esegui make e opzionalmente costruisci qualcosa.
         build()
         {
             make -j 2
             if [ $# -gt 0 ]
             then
                 ./pre-inst-env guix build "$@"
             fi
         }
         export_function build

         # Predefinisci il comando Git push.
         push()
         {
             git push --set-upstream origin
         }
         export_function push

         clear                        # Pulisci lo schermo.
         git-cal --author='Il tuo nome' # Mostra il calendario dei contributi.

         # Mostra l'aiuto dei comandi.
         echo "
     build          costruisce un pacchetto o solo un progetto se non viene fornito alcun argomento
     configure      esegui ./configure con parametri predefiniti
     push           effettua il push al repository Git upstream
     "
     }

   Ogni progetto contenente ‘.envrc’ con la stringa ‘use guix’ avrà
variabili d’ambiente e procedure predefinite.

   Esegui ‘direnv allow’ per configurare l’ambiente per la prima volta.


File: guix-cookbook.it.info,  Node: Reproducible Research,  Next: Installare Guix su un Cluster,  Prev: Gestione dell'ambiente,  Up: Top

9 Using Guix for Reproducible Research
**************************************

Because it supports reproducible deployment, Guix is a solid foundation
for “reproducible research workflows”. This section is targeted at
scientists; it shows how to add Guix to one’s reproducible research
toolbox(1).

   With Guix as the basis of your computational workflow, you can get
what’s in essence _executable provenance meta-data_: it’s like the list
of package name/version pairs some provide as an appendix to their
publication, except more precise and immediately deployable.

   This section is a guide in just four steps on how to make your
computational experiments reproducible using Guix, and how to provide
that information in your research paper.

* Menu:

* Setting Up the Environment::  Step 1: using ‘guix shell’.
* Recording the Environment::  Step 2: using ‘guix describe’.
* Ensuring Long-Term Source Code Archiving::  Step 3: Software Heritage.
* Referencing the Software Environment::  Step 4: SWHIDs.

   ---------- Footnotes ----------

   (1) This chapter is adapted from a blog post published on the
Guix-HPC web site in 2023.
(https://hpc.guix.info/blog/2023/06/a-guide-to-reproducible-research-papers/).


File: guix-cookbook.it.info,  Node: Setting Up the Environment,  Next: Recording the Environment,  Up: Reproducible Research

9.1 Step 1: Setting Up the Environment
======================================

The first step is to identify precisely what packages you need in your
software environment to run your computational experiment.

   Assuming you have a Python script that uses NumPy, you can start by
creating an environment that contains these two packages and to run your
code in that environment (*note (guix)Invoking guix shell::):

     guix shell -C python python-numpy -- python3 ./myscript.py

   The ‘-C’ flag here (or ‘--container’) instructs ‘guix shell’ to
create that environment in an isolated container with nothing but the
two packages you asked for. That way, if ‘./myscript.py’ needs more than
these two packages, it’ll fail to run and you’ll immediately notice. On
some systems ‘--container’ is not supported; in that case, you can
resort to ‘--pure’ instead.

   Perhaps you’ll find that you also need Pandas and add it to the
environment:

     guix shell -C python python-numpy python-pandas -- \
       python3 ./myscript.py

   If you fail to guess the name of the package (this one was easy!),
try ‘guix search’.

   Environments for Python, R, and similar high-level languages are
relatively easy to set up. For C/C++ code, you may need more packages:

     guix shell -C gcc-toolchain cmake coreutils grep sed make -- ...

   Or perhaps you’ll find that you could just as well provide a package
definition for your code—*note (guix)Defining Packages::, to learn more
on how to do that.

   Eventually, you’ll have a list of packages that satisfies your needs.

     What if a package is missing?: Guix and the main scientific
     channels provide about tens of thousands of packages
     (https://hpc.guix.info/browse). Yet, there’s always the possibility
     that the one package you need is missing.

     In that case, you will need to provide a definition for it (*note
     (guix)Defining Packages::) in a dedicated channel of yours (*note
     (guix)Creating a Channel::). For software in Python, R, and other
     high-level languages, most of the work can usually be automated by
     using ‘guix import’ (*note (guix)Invoking guix import::).

     Join the friendly Guix community (https://guix.gnu.org/contact/) to
     get help!


File: guix-cookbook.it.info,  Node: Recording the Environment,  Next: Ensuring Long-Term Source Code Archiving,  Prev: Setting Up the Environment,  Up: Reproducible Research

9.2 Step 2: Recording the Environment
=====================================

Now that you have that ‘guix shell’ command line with a list of
packages, the best course of action is to save it in a _manifest_
file—essentially a software bill of materials—that Guix can then ingest
(*note (guix)Writing Manifests::). The easiest way to get started is by
“translating” your command line into a manifest:

     guix shell python python-numpy python-pandas \
       --export-manifest > manifest.scm

   Put that manifest under version control! From there anyone can
redeploy the software environment described by the manifest and run code
in that environment:

     guix shell -C -m manifest.scm -- python3 ./myscript.py

   Here’s what ‘manifest.scm’ reads:

     ;; What follows is a "manifest" equivalent to the command line you gave.
     ;; You can store it in a file that you may then pass to any 'guix' command
     ;; that accepts a '--manifest' (or '-m') option.

     (specifications->manifest
       (list "python" "python-numpy" "python-pandas"))

   It’s a code snippet that lists packages. Notice that there are no
version numbers! Indeed, these version numbers are specified in package
definitions, located in Guix channels. To allow others to reproduce the
exact same environment as the one you’re running, you need to _pin Guix
itself_ , by capturing the current Guix channel commits with ‘guix
describe’ (*note (guix)Replicating Guix::):

     guix describe -f channels > channels.scm

   This ‘channels.scm’ file is similar in spirit to “lock files” that
some deployment tools employ to pin package revisions. You should also
keep it under version control in your code, and possibly update it once
in a while when you feel like running your code against newer versions
of its dependencies. With this file, anyone, _at any time and on any
machine_, can now reproduce the exact same environment by running:

     guix time-machine -C channels.scm -- \
       shell -C -m manifest.scm -- \
       python3 ./myscript.py

   In this example we rely solely on the ‘guix’ channel, which provides
the Python packages we need. Perhaps some of the packages you need live
in other channels (https://hpc.guix.info/channels)—maybe ‘guix-cran’ if
you use R, maybe ‘guix-science’. That’s fine: ‘guix describe’ also
captures that.

   Of course do include a ‘README’ file giving the exact command to run
the code. Not everyone uses Guix so it can be helpful to also provide
minimal non-Guix setup instructions: which package versions are used,
how software is built, etc. As we have seen, such instructions would
likely be inaccurate and inconvenient to follow at best. Yet, it can be
a useful starting point to someone trying to recreate a _similar_
environment using different tools. It should probably be presented as
such, with the understanding that the only way to get the _same_
environment is to use Guix.


File: guix-cookbook.it.info,  Node: Ensuring Long-Term Source Code Archiving,  Next: Referencing the Software Environment,  Prev: Recording the Environment,  Up: Reproducible Research

9.3 Step 3: Ensuring Long-Term Source Code Archiving
====================================================

We insisted on version control before: for the ‘manifest.scm’ and
‘channels.scm’ files, but of course also for your own code. Our
recommendation is to have these two ‘.scm’ files in the same repository
as the code they’re about.

   Since the goal is enabling reproducibility, source code availability
is a prime concern. Source code hosting services come and go and we
don’t want our code to vanish in a whim and render our published
research work unverifiable. Software Heritage
(https://www.softwareheritage.org/) (SWH for short) is _the_ solution
for this: SWH archives public source code and provides unique intrinsic
identifiers to refer to it—“SWHIDs” (https://swhid.org). Guix itself is
connected to SWH (https://doi.org/10.1145/3641525.3663622) to (1) ensure
that the source code of its packages is archived, and (2) to fall back
to downloading from the SWH archive should code vanish from its original
site.

   Once your own code is available in a public version-control
repository, such as a Git repository on your lab’s hosting service, you
can ask SWH to archive it by going to its Save Code Now
(https://archive.softwareheritage.org/save/) interface. SWH will process
the request asynchronously and eventually you’ll find your code has made
it into the archive (https://archive.softwareheritage.org/).


File: guix-cookbook.it.info,  Node: Referencing the Software Environment,  Prev: Ensuring Long-Term Source Code Archiving,  Up: Reproducible Research

9.4 Step 4: Referencing the Software Environment
================================================

This brings us to the last step: referring to our code _and_ software
environment in our beloved paper. We already have all our code and Guix
files in the same repository, which is archived on SWH. Thanks to SWH,
we now have a SWHID, which uniquely identifies the relevant revision of
our code.

   Following SWH’s own guide
(https://www.softwareheritage.org/howto-archive-and-reference-your-code/),
we’ll pick an ‘swh:dir’ kind of identifier, which refers to the
directory of the relevant revision/commit of our repository, and we’ll
keep _contextual info_ for clarity—that includes the original URL.
Putting it all together, we’ll conclude our paper with a sentence along
these lines:

     Example: The source code used to produce this study, as well as
     instructions to run it in the right software environment using
     GNU Guix, is archived on Software Heritage as
     ‘swh:1:dir:cc8919d7705fbaa31efa677ce00bef7eb374fb80;origin=https://gitlab.inria.fr/lcourtes-phd/edcc-2006-redone;visit=swh:1:snp:71a4d08ef4a2e8455b67ef0c6b82349e82870b46;anchor=swh:1:rev:36fde7e5ba289c4c3e30d9afccebbe0cfe83853a’
     (https://archive.softwareheritage.org/swh:1:dir:cc8919d7705fbaa31efa677ce00bef7eb374fb80;origin=https://gitlab.inria.fr/lcourtes-phd/edcc-2006-redone;visit=swh:1:snp:71a4d08ef4a2e8455b67ef0c6b82349e82870b46;anchor=swh:1:rev:36fde7e5ba289c4c3e30d9afccebbe0cfe83853a).

   With this information, the reader can:

   • get the source code;
   • reproduce its software environment with ‘guix time-machine’ and run
     the code;
   • inspect and possibly modify both the code and its environment.

   Mission accomplished!


File: guix-cookbook.it.info,  Node: Installare Guix su un Cluster,  Next: Gestione del Sistema Guix,  Prev: Reproducible Research,  Up: Top

10 Installare Guix su un Cluster
********************************

Guix è attraente per gli scienziati e i professionisti dell’HPC (calcolo
ad alte prestazioni): semplifica il deployment di stack software
potenzialmente complessi e consente di farlo in modo riproducibile,
permettendo di ridistribuire esattamente lo stesso software su macchine
diverse e in momenti diversi.

   In questo capitolo esaminiamo come un amministratore di sistema di un
cluster può installare Guix per un uso a livello di sistema, in modo che
possa essere utilizzato su tutti i nodi del cluster, e discutiamo i vari
compromessi(1)

     Nota: Qui si assume che il cluster stia eseguendo una distribuzione
     GNU/Linux diversa da Guix System e che installeremo Guix su di
     essa.

* Menu:

* Configurazione di un nodo principale::  Il nodo che esegue il demone.
* Configurazione dei nodi di calcolo::  Nodi client.
* Accesso alla rete del cluster::  Gestione delle restrizioni di accesso
                                     alla rete.
* Utilizzo del disco del cluster::  Considerazioni sull’utilizzo del disco.
* Considerazioni sulla sicurezza del cluster::  Mantenere il cluster sicuro.

   ---------- Footnotes ----------

   (1) Questo capitolo è adattato da un post del blog pubblicato sul
sito web di Guix-HPC nel 2017
(https://hpc.guix.info/blog/2017/11/installing-guix-on-a-cluster/).


File: guix-cookbook.it.info,  Node: Configurazione di un nodo principale,  Next: Configurazione dei nodi di calcolo,  Up: Installare Guix su un Cluster

10.1 Configurazione di un nodo principale
=========================================

L’approccio raccomandato è quello di configurare un _nodo head_ che
esegue ‘guix-daemon’ ed esporta ‘/gnu/store’ tramite NFS ai nodi di
calcolo.

   Ricorda che ‘guix-daemon’ è responsabile dell’avvio dei processi di
costruzione e dei download per conto dei client (*note (guix.it)Invocare
guix-daemon::), e più in generale dell’accesso a ‘/gnu/store’, che
contiene tutti i binari dei pacchetti costruiti da tutti gli utenti
(*note (guix.it)Lo store::). “Client” qui si riferisce a tutti i comandi
Guix che gli utenti vedono, come ‘guix install’. Su un cluster, questi
comandi potrebbero essere eseguiti sui nodi di calcolo e vorremo che
comunicassero con l’istanza ‘guix-daemon’ del nodo head.

   Per iniziare, il nodo head può essere installato seguendo le solite
istruzioni di installazione binaria (*note (guix.it)Installazione
binaria::). Grazie allo script di installazione, questo dovrebbe essere
rapido. Una volta completata l’installazione, dobbiamo apportare alcune
modifiche.

   Poiché vogliamo che ‘guix-daemon’ sia raggiungibile non solo dal nodo
head ma anche dai nodi di calcolo, dobbiamo fare in modo che ascolti le
connessioni su TCP/IP. Per fare ciò, modificheremo il file di avvio di
systemd per ‘guix-daemon’, ‘/etc/systemd/system/guix-daemon.service’, e
aggiungeremo un argomento ‘--listen’ alla riga ‘ExecStart’ in modo che
assomigli a questo:

     ExecStart=/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon \
         --build-users-group=guixbuild \
         --listen=/var/guix/daemon-socket/socket --listen=0.0.0.0

   Affinché queste modifiche abbiano effetto, il servizio deve essere
riavviato:

     systemctl daemon-reload
     systemctl restart guix-daemon

     Nota: Il bit ‘--listen=0.0.0.0’ significa che ‘guix-daemon’
     elaborerà _all_ le connessioni TCP in entrata sulla porta 44146
     (*note (guix.it)Invocare guix-daemon::). Questo di solito va bene
     in una configurazione cluster in cui il nodo head è raggiungibile
     esclusivamente dalla rete locale del cluster — non vuoi che sia
     esposto a Internet!

   Il passo successivo è definire le nostre esportazioni NFS in
‘/etc/exports’ (https://linux.die.net/man/5/exports) aggiungendo
qualcosa del genere:

     /gnu/store    *(ro)
     /var/guix     *(rw, async)
     /var/log/guix *(ro)

   La directory ‘/gnu/store’ può essere esportata in sola lettura poiché
solo ‘guix-daemon’ sul nodo master la modificherà. ‘/var/guix’ contiene
_profili utente_ gestiti da ‘guix package’; quindi, per consentire agli
utenti di installare pacchetti con ‘guix package’, questo deve essere in
lettura-scrittura.

   Gli utenti possono creare tutti i profili che desiderano oltre al
profilo predefinito, ‘~/.guix-profile’. Ad esempio, ‘guix package -p
~/dev/python-dev -i python’ installa Python in un profilo raggiungibile
dal symlink ‘~/dev/python-dev’. Per assicurarsi che questo profilo sia
protetto dalla raccolta della spazzatura — cioè, che Python non venga
rimosso da ‘/gnu/store’ finché questo profilo esiste —, le _directory
home dovrebbero essere montate anche sul nodo head_ in modo che
‘guix-daemon’ sia a conoscenza di questi profili non standard ed eviti
di raccogliere il software a cui si riferiscono.

   Potrebbe essere una buona idea rimuovere periodicamente i bit
inutilizzati da ‘/gnu/store’ eseguendo ‘guix gc’ (*note
(guix.it)Invocare guix gc::). Questo può essere fatto aggiungendo una
voce crontab sul nodo head:

     root@master# crontab -e

... con qualcosa del genere:

     # Ogni giorno alle 5 del mattino, esegui il garbage collector per assicurarti
     # che ci siano almeno 10 GB liberi su /gnu/store.
     0 5 * * 1  /usr/local/bin/guix gc -F10G

   Abbiamo finito con il nodo head! Ora passiamo ai nodi di calcolo.


File: guix-cookbook.it.info,  Node: Configurazione dei nodi di calcolo,  Next: Accesso alla rete del cluster,  Prev: Configurazione di un nodo principale,  Up: Installare Guix su un Cluster

10.2 Configurazione dei nodi di calcolo
=======================================

Innanzitutto, abbiamo bisogno che i nodi di calcolo montino le directory
NFS che il nodo head esporta. Questo può essere fatto aggiungendo le
seguenti righe a ‘/etc/fstab’ (https://linux.die.net/man/5/fstab):

     HEAD-NODE:/gnu/store    /gnu/store    nfs  defaults,_netdev,vers=3 0 0
     HEAD-NODE:/var/guix     /var/guix     nfs  defaults,_netdev,vers=3 0 0
     HEAD-NODE:/var/log/guix /var/log/guix nfs  defaults,_netdev,vers=3 0 0

... dove HEAD-NODE è il nome o l’indirizzo IP del tuo nodo head. Da lì
in poi, supponendo che i punti di montaggio esistano, dovresti essere in
grado di montare ognuno di questi sui nodi di calcolo.

   Successivamente, dobbiamo fornire un comando ‘guix’ predefinito che
gli utenti possano eseguire quando si connettono per la prima volta al
cluster (alla fine invocheranno ‘guix pull’, che fornirà loro il loro
“proprio” comando ‘guix’). Simile a quanto fatto dallo script di
installazione binaria sul nodo head, lo memorizzeremo in
‘/usr/local/bin’:

     mkdir -p /usr/local/bin
     ln -s /var/guix/profiles/per-user/root/current-guix/bin/guix \
           /usr/local/bin/guix

   Dobbiamo quindi dire a ‘guix’ di comunicare con il demone in
esecuzione sul nostro nodo master, aggiungendo queste righe a
‘/etc/profile’:

     GUIX_DAEMON_SOCKET="guix://HEAD-NODE"
     export GUIX_DAEMON_SOCKET

   Per evitare avvisi e assicurarsi che ‘guix’ utilizzi la locale
corretta, dobbiamo dirgli di usare i dati di locale forniti da Guix
(*note (guix.it)Configurazione dell'applicazione::):

     GUIX_LOCPATH=/var/guix/profiles/per-user/root/guix-profile/lib/locale
     export GUIX_LOCPATH

     # Qui dobbiamo usare un nome di locale valido. Prova "ls $GUIX_LOCPATH/*"
     # per vedere quali nomi possono essere usati.
     LC_ALL=fr_FR.utf8
     export LC_ALL

   Per comodità, ‘guix package’ genera automaticamente
‘~/.guix-profile/etc/profile’, che definisce tutte le variabili
d’ambiente necessarie per utilizzare i pacchetti — ‘PATH’,
‘C_INCLUDE_PATH’, ‘PYTHONPATH’, ecc. Allo stesso modo, ‘guix pull’ lo fa
sotto ‘~/.config/guix/current’. Quindi è una buona idea caricare
entrambi da ‘/etc/profile’:

     for GUIX_PROFILE in "$HOME/.config/guix/current" "$HOME/.guix-profile"
     do
       if [ -f "$GUIX_PROFILE/etc/profile" ]; then
         . "$GUIX_PROFILE/etc/profile"
       fi
     done

   Infine, Guix fornisce il completamento della riga di comando, in
particolare per Bash e zsh. In ‘/etc/bashrc’, considera di aggiungere
questa riga:

. /var/guix/profiles/per-user/root/current-guix/etc/bash_completion.d/guix

   Ecco fatto!

   Puoi verificare che tutto sia a posto accedendo a un nodo di calcolo
ed eseguendo:

     guix install hello

   Il demone sul nodo principale dovrebbe scaricare i binari
precompilati per tuo conto e decomprimerli in ‘/gnu/store’, e ‘guix
install’ dovrebbe creare ‘~/.guix-profile’ contenente il comando
‘~/.guix-profile/bin/hello’.


File: guix-cookbook.it.info,  Node: Accesso alla rete del cluster,  Next: Utilizzo del disco del cluster,  Prev: Configurazione dei nodi di calcolo,  Up: Installare Guix su un Cluster

10.3 Accesso alla Rete
======================

Guix richiede l’accesso alla rete per scaricare il codice sorgente e i
binari precompilati. La buona notizia è che solo il nodo principale ne
ha bisogno, poiché i nodi di calcolo si limitano a delegare a esso.

   È consuetudine che i nodi del cluster abbiano accesso, nella migliore
delle ipotesi, a una _white list_ di host. Il nostro nodo principale ha
bisogno almeno di ‘ci.guix.gnu.org’ in questa white list, poiché è da
qui che ottiene i binari precompilati per impostazione predefinita, per
tutti i pacchetti presenti in Guix.

   Per inciso, ‘ci.guix.gnu.org’ funge anche da _mirror con
indirizzamento per contenuto_ del codice sorgente di tali pacchetti. Di
conseguenza, è sufficiente avere _only_ ‘ci.guix.gnu.org’ in quella
white list.

   I pacchetti software mantenuti in un repository separato, come uno
dei vari canali HPC (https://hpc.guix.info/channels), non sono
disponibili da ‘ci.guix.gnu.org’. Per questi pacchetti, potresti voler
estendere la white list in modo che il sorgente e i binari precompilati
(supponendo che i server di terze parti forniscano binari per questi
pacchetti) possano essere scaricati. Come ultima risorsa, gli utenti
possono sempre scaricare il sorgente sulla propria workstation e
aggiungerlo a ‘/gnu/store’ del cluster, in questo modo:

GUIX_DAEMON_SOCKET=ssh://compute-node.example.org \
  guix download http://starpu.gforge.inria.fr/files/starpu-1.2.3/starpu-1.2.3.tar.gz

   Il comando sopra scarica ‘starpu-1.2.3.tar.gz’ _and_ lo invia
all’istanza ‘guix-daemon’ del cluster tramite SSH.

   I cluster isolati richiedono più lavoro. Al momento, il nostro
suggerimento sarebbe quello di scaricare tutto il codice sorgente
necessario su una workstation che esegue Guix. Ad esempio, usando
l’opzione ‘--sources’ di ‘guix build’ (*note (guix.it)Invocare guix
build::), l’esempio seguente scarica tutto il codice sorgente da cui
dipende il pacchetto ‘openmpi’:

     $ guix build --sources=transitive openmpi

     ...

     /gnu/store/xc17sm60fb8nxadc4qy0c7rqph499z8s-openmpi-1.10.7.tar.bz2
     /gnu/store/s67jx92lpipy2nfj5cz818xv430n4b7w-gcc-5.4.0.tar.xz
     /gnu/store/npw9qh8a46lrxiwh9xwk0wpi3jlzmjnh-gmp-6.0.0a.tar.xz
     /gnu/store/hcz0f4wkdbsvsdky3c0vdvcawhdkyldb-mpfr-3.1.5.tar.xz
     /gnu/store/y9akh452n3p4w2v631nj0injx7y0d68x-mpc-1.0.3.tar.gz
     /gnu/store/6g5c35q8avfnzs3v14dzl54cmrvddjm2-glibc-2.25.tar.xz
     /gnu/store/p9k48dk3dvvk7gads7fk30xc2pxsd66z-hwloc-1.11.8.tar.bz2
     /gnu/store/cry9lqidwfrfmgl0x389cs3syr15p13q-gcc-5.4.0.tar.xz
     /gnu/store/7ak0v3rzpqm2c5q1mp3v7cj0rxz0qakf-libfabric-1.4.1.tar.bz2
     /gnu/store/vh8syjrsilnbfcf582qhmvpg1v3rampf-rdma-core-14.tar.gz
     ...

   (Nel caso ti stia chiedendo, si tratta di più di 320 MiB di codice
sorgente _compressed_.)

   Possiamo quindi creare un grande archivio contenente tutto questo
(*note (guix.it)Invocare guix archive::):

$ guix archive --export \
    `guix build --sources=transitive openmpi` \
    > openmpi-source-code.nar

   ... e possiamo eventualmente trasferire quell’archivio al cluster su
memoria rimovibile e decomprimerlo lì:

$ guix archive --import < openmpi-source-code.nar

   Questo processo deve essere ripetuto ogni volta che è necessario
portare nuovo codice sorgente al cluster.

   Mentre scriviamo, gli istituti di ricerca coinvolti in Guix-HPC non
hanno cluster isolati. Se hai esperienza con tali configurazioni, ci
piacerebbe ricevere il tuo feedback e suggerimenti.


File: guix-cookbook.it.info,  Node: Utilizzo del disco del cluster,  Next: Considerazioni sulla sicurezza del cluster,  Prev: Accesso alla rete del cluster,  Up: Installare Guix su un Cluster

10.4 Utilizzo del Disco
=======================

Una preoccupazione comune degli amministratori di sistema è se tutto
questo consumerà molto spazio su disco. Semmai, se qualcosa esaurirà lo
spazio su disco, saranno i set di dati scientifici piuttosto che il
software compilato — questa è la nostra esperienza con quasi dieci anni
di utilizzo di Guix sui cluster HPC. Ciononostante, vale la pena dare
un’occhiata a come Guix contribuisce all’utilizzo del disco.

   Innanzitutto, avere diverse versioni o varianti di un dato pacchetto
in ‘/gnu/store’ non costa necessariamente molto, perché ‘guix-daemon’
implementa la deduplicazione di file identici, e le varianti dei
pacchetti probabilmente avranno un certo numero di file comuni.

   Come accennato in precedenza, consigliamo di avere un cron job per
eseguire ‘guix gc’ periodicamente, che rimuove il software _unused_ da
‘/gnu/store’. Tuttavia, c’è sempre la possibilità che gli utenti
mantengano molto software nei loro profili, o molte vecchie generazioni
dei loro profili, che è “vivo” e non può essere eliminato dal punto di
vista di ‘guix gc’.

   La soluzione a questo è che gli utenti rimuovano regolarmente le
vecchie generazioni del loro profilo. Ad esempio, il seguente comando
rimuove le generazioni più vecchie di due mesi:

     guix package --delete-generations=2m

   Allo stesso modo, è una buona idea invitare gli utenti ad aggiornare
regolarmente il proprio profilo, il che può ridurre il numero di
varianti di un dato pezzo di software memorizzato in ‘/gnu/store’:

     guix pull
     guix upgrade

   Come ultima risorsa, è sempre possibile per gli amministratori di
sistema fare parte di questo per conto dei loro utenti. Tuttavia, uno
dei punti di forza di Guix è la libertà e il controllo che gli utenti
ottengono sul loro ambiente software, quindi raccomandiamo vivamente di
lasciare gli utenti in controllo.


File: guix-cookbook.it.info,  Node: Considerazioni sulla sicurezza del cluster,  Prev: Utilizzo del disco del cluster,  Up: Installare Guix su un Cluster

10.5 Considerazioni sulla Sicurezza
===================================

Su un cluster HPC, Guix è tipicamente usato per gestire software
scientifico. Software critici per la sicurezza come il kernel del
sistema operativo e i servizi di sistema come ‘sshd’ e lo scheduler di
batch rimangono sotto il controllo degli amministratori di sistema.

   Il progetto Guix ha un buon track record nel fornire aggiornamenti di
sicurezza in modo tempestivo (*note (guix.it)Aggiornamenti di
sicurezza::). Per ottenere gli aggiornamenti di sicurezza, gli utenti
devono eseguire ‘guix pull && guix upgrade’.

   Poiché Guix identifica in modo univoco le varianti del software, è
facile vedere se un pezzo di software vulnerabile è in uso. Ad esempio,
per verificare se la variante glibc 2.25 senza la patch di mitigazione
contro “Stack Clash
(https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt)”, si può
controllare se i profili utente vi fanno riferimento in assoluto:

     guix gc --referrers /gnu/store/…-glibc-2.25

   Questo riporterà se esistono profili che fanno riferimento a questa
specifica variante di glibc.


File: guix-cookbook.it.info,  Node: Gestione del Sistema Guix,  Next: Ringraziamenti,  Prev: Installare Guix su un Cluster,  Up: Top

11 Gestione del Sistema Guix
****************************

Poiché Guix non gestisce il packaging, la configurazione del sistema e i
servizi nel modo in cui lo fanno altre distribuzioni (più “classiche”),
alcuni flussi di lavoro tendono a svolgersi in modo leggermente diverso
da come siamo abituati e necessitano di un leggero adattamento. Questo
capitolo intende aiutare con tali questioni.

* Menu:

* Aggiornare Postgres per Cuirass::  Aggiornamento dal postgres predefinito.


File: guix-cookbook.it.info,  Node: Aggiornare Postgres per Cuirass,  Up: Gestione del Sistema Guix

11.1 Aggiornare Postgres per Cuirass
====================================

Con la deprecazione del valore predefinito per il pacchetto postgres in
postgresql-configuration (vedi
b93434e656eba4260df82158a96c295000d3ff44), gli aggiornamenti di sistema
richiedono alcune azioni manuali prima di poter aver luogo. Ecco una
pratica guida su come fare.

   Si prega di notare che questo è un modo diretto per dataset più
piccoli. Per database più grandi ‘pg_upgrade’
(https://www.postgresql.org/docs/current/pgupgrade.html) potrebbe essere
la scelta migliore. La gestione del servizio e l’aggiornamento del
sistema come descritto in questa guida si applicano comunque.

  1. Ferma e disabilita cuirass.

     Impedisci al servizio di avviarsi e fallire dopo una
     riconfigurazione:

     ‘sudo herd stop cuirass && sudo herd disable cuirass’

  2. Scarica il contenuto del database.

     ‘sudo su - postgres -s /bin/sh -c pg_dumpall > /tmp/pg.dump’

  3. Aggiungi o modifica il servizio postgres.

     A seconda che il tuo servizio postgres sia definito implicitamente
     (tramite la dipendenza dal servizio cuirass) o con una propria voce
     nella proprietà ‘(services)’ del tuo sistema operativo, devi
     aggiungere o modificare la configurazione esistente per riflettere
     l’aggiornamento della versione desiderata.

     Fai attenzione a non aggiornare direttamente a postgres-16 – il
     servizio cuirass per qualche motivo non lo gradisce. Ho dovuto
     trovare ed eliminare i file rilevanti e poi reinizializzare dopo un
     aggiornamento fallito a postgres 16.

          (service postgresql-service-type
                   (postgresql-configuration
                    (postgresql (@ (gnu packages databases) postgresql-15))))

     Nota: Se per qualche motivo non hai letto il testo qui ma hai
     seguito ciecamente gli esempi e _hai aggiornato alla versione 16_,
     ecco come reimpostare lo stato:

       1. Elimina i file dell’istanza del database.

          Per impostazione predefinita si trovano in
          ‘/var/lib/postgres/data’.

       2. Reinizializza postgres.

          ‘sudo su - postgres -s /bin/sh -c 'pg_ctl init -D
          /var/lib/postgres/data'’

  4. Riconfigura il tuo sistema.

     ‘sudo guix system reconfigure path/to/your/altered/config.scm’

  5. Ripristina il contenuto del database.

     ‘sudo su - postgres -s /bin/sh -c 'psql -d postgres -f
     /tmp/pg.dump'’

  6. Abilita e avvia il servizio.

          sudo herd enable cuirass
          sudo herd start cuirass


File: guix-cookbook.it.info,  Node: Ringraziamenti,  Next: Licenza di Documentazione Libera GNU,  Prev: Gestione del Sistema Guix,  Up: Top

12 Ringraziamenti
*****************

Guix è basato sul gestore di pacchetti Nix (https://nixos.org/nix/),
progettato e implementato da Eelco Dolstra, con contributi di altre
persone (vedi il file ‘nix/AUTHORS’ in Guix). Nix ha aperto la strada
alla gestione funzionale dei pacchetti e ha promosso funzionalità senza
precedenti, come gli aggiornamenti e i rollback transazionali dei
pacchetti, i profili per utente e i processi di costruzione
referenzialmente trasparenti. Senza questo lavoro, Guix non esisterebbe.

   Le distribuzioni software basate su Nix, Nixpkgs e NixOS, sono state
anche un’ispirazione per Guix.

   GNU Guix stesso è un lavoro collettivo con contributi di diverse
persone. Consulta il file ‘AUTHORS’ in Guix per maggiori informazioni su
queste persone. Il file ‘THANKS’ elenca le persone che hanno contribuito
segnalando bug, curando l’infrastruttura, fornendo grafica e temi, dando
suggerimenti e altro ancora — grazie!

   Questo documento include sezioni adattate da articoli precedentemente
pubblicati sul blog di Guix all’indirizzo <https://guix.gnu.org/blog> e
sul blog di Guix-HPC all’indirizzo <https://hpc.guix.info/blog>.


File: guix-cookbook.it.info,  Node: Licenza di Documentazione Libera GNU,  Next: Indice dei concetti,  Prev: Ringraziamenti,  Up: Top

Appendice A Licenza di Documentazione Libera GNU
************************************************

                     Version 1.3, 3 November 2008

     Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
     <https://fsf.org/>

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

  0. PREAMBLE

     The purpose of this License is to make a manual, textbook, or other
     functional and useful document “free” in the sense of freedom: to
     assure everyone the effective freedom to copy and redistribute it,
     with or without modifying it, either commercially or
     noncommercially. Secondarily, this License preserves for the author
     and publisher a way to get credit for their work, while not being
     considered responsible for modifications made by others.

     This License is a kind of “copyleft”, which means that derivative
     works of the document must themselves be free in the same sense. It
     complements the GNU General Public License, which is a copyleft
     license designed for free software.

     We have designed this License in order to use it for manuals for
     free software, because free software needs free documentation: a
     free program should come with manuals providing the same freedoms
     that the software does. But this License is not limited to software
     manuals; it can be used for any textual work, regardless of subject
     matter or whether it is published as a printed book. We recommend
     this License principally for works whose purpose is instruction or
     reference.

  1. APPLICABILITY AND DEFINITIONS

     This License applies to any manual or other work, in any medium,
     that contains a notice placed by the copyright holder saying it can
     be distributed under the terms of this License. Such a notice
     grants a world-wide, royalty-free license, unlimited in duration,
     to use that work under the conditions stated herein. The
     “Document”, below, refers to any such manual or work. Any member of
     the public is a licensee, and is addressed as “you”. You accept the
     license if you copy, modify or distribute the work in a way
     requiring permission under copyright law.

     A “Modified Version” of the Document means any work containing the
     Document or a portion of it, either copied verbatim, or with
     modifications and/or translated into another language.

     A “Secondary Section” is a named appendix or a front-matter section
     of the Document that deals exclusively with the relationship of the
     publishers or authors of the Document to the Document’s overall
     subject (or to related matters) and contains nothing that could
     fall directly within that overall subject. (Thus, if the Document
     is in part a textbook of mathematics, a Secondary Section may not
     explain any mathematics.) The relationship could be a matter of
     historical connection with the subject or with related matters, or
     of legal, commercial, philosophical, ethical or political position
     regarding them.

     The “Invariant Sections” are certain Secondary Sections whose
     titles are designated, as being those of Invariant Sections, in the
     notice that says that the Document is released under this License.
     If a section does not fit the above definition of Secondary then it
     is not allowed to be designated as Invariant. The Document may
     contain zero Invariant Sections. If the Document does not identify
     any Invariant Sections then there are none.

     The “Cover Texts” are certain short passages of text that are
     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
     that says that the Document is released under this License. A
     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
     be at most 25 words.

     A “Transparent” copy of the Document means a machine-readable copy,
     represented in a format whose specification is available to the
     general public, that is suitable for revising the document
     straightforwardly with generic text editors or (for images composed
     of pixels) generic paint programs or (for drawings) some widely
     available drawing editor, and that is suitable for input to text
     formatters or for automatic translation to a variety of formats
     suitable for input to text formatters. A copy made in an otherwise
     Transparent file format whose markup, or absence of markup, has
     been arranged to thwart or discourage subsequent modification by
     readers is not Transparent. An image format is not Transparent if
     used for any substantial amount of text. A copy that is not
     “Transparent” is called “Opaque”.

     Examples of suitable formats for Transparent copies include plain
     ASCII without markup, Texinfo input format, LaTeX input format,
     SGML or XML using a publicly available DTD, and standard-conforming
     simple HTML, PostScript or PDF designed for human modification.
     Examples of transparent image formats include PNG, XCF and JPG.
     Opaque formats include proprietary formats that can be read and
     edited only by proprietary word processors, SGML or XML for which
     the DTD and/or processing tools are not generally available, and
     the machine-generated HTML, PostScript or PDF produced by some word
     processors for output purposes only.

     The “Title Page” means, for a printed book, the title page itself,
     plus such following pages as are needed to hold, legibly, the
     material this License requires to appear in the title page. For
     works in formats which do not have any title page as such, “Title
     Page” means the text near the most prominent appearance of the
     work’s title, preceding the beginning of the body of the text.

     The “publisher” means any person or entity that distributes copies
     of the Document to the public.

     A section “Entitled XYZ” means a named subunit of the Document
     whose title either is precisely XYZ or contains XYZ in parentheses
     following text that translates XYZ in another language. (Here XYZ
     stands for a specific section name mentioned below, such as
     “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
     To “Preserve the Title” of such a section when you modify the
     Document means that it remains a section “Entitled XYZ” according
     to this definition.

     The Document may include Warranty Disclaimers next to the notice
     which states that this License applies to the Document. These
     Warranty Disclaimers are considered to be included by reference in
     this License, but only as regards disclaiming warranties: any other
     implication that these Warranty Disclaimers may have is void and
     has no effect on the meaning of this License.

  2. VERBATIM COPYING

     You may copy and distribute the Document in any medium, either
     commercially or noncommercially, provided that this License, the
     copyright notices, and the license notice saying this License
     applies to the Document are reproduced in all copies, and that you
     add no other conditions whatsoever to those of this License. You
     may not use technical measures to obstruct or control the reading
     or further copying of the copies you make or distribute. However,
     you may accept compensation in exchange for copies. If you
     distribute a large enough number of copies you must also follow the
     conditions in section 3.

     You may also lend copies, under the same conditions stated above,
     and you may publicly display copies.

  3. COPYING IN QUANTITY

     If you publish printed copies (or copies in media that commonly
     have printed covers) of the Document, numbering more than 100, and
     the Document’s license notice requires Cover Texts, you must
     enclose the copies in covers that carry, clearly and legibly, all
     these Cover Texts: Front-Cover Texts on the front cover, and
     Back-Cover Texts on the back cover. Both covers must also clearly
     and legibly identify you as the publisher of these copies. The
     front cover must present the full title with all words of the title
     equally prominent and visible. You may add other material on the
     covers in addition. Copying with changes limited to the covers, as
     long as they preserve the title of the Document and satisfy these
     conditions, can be treated as verbatim copying in other respects.

     If the required texts for either cover are too voluminous to fit
     legibly, you should put the first ones listed (as many as fit
     reasonably) on the actual cover, and continue the rest onto
     adjacent pages.

     If you publish or distribute Opaque copies of the Document
     numbering more than 100, you must either include a machine-readable
     Transparent copy along with each Opaque copy, or state in or with
     each Opaque copy a computer-network location from which the general
     network-using public has access to download using public-standard
     network protocols a complete Transparent copy of the Document, free
     of added material. If you use the latter option, you must take
     reasonably prudent steps, when you begin distribution of Opaque
     copies in quantity, to ensure that this Transparent copy will
     remain thus accessible at the stated location until at least one
     year after the last time you distribute an Opaque copy (directly or
     through your agents or retailers) of that edition to the public.

     It is requested, but not required, that you contact the authors of
     the Document well before redistributing any large number of copies,
     to give them a chance to provide you with an updated version of the
     Document.

  4. MODIFICATIONS

     You may copy and distribute a Modified Version of the Document
     under the conditions of sections 2 and 3 above, provided that you
     release the Modified Version under precisely this License, with the
     Modified Version filling the role of the Document, thus licensing
     distribution and modification of the Modified Version to whoever
     possesses a copy of it. In addition, you must do these things in
     the Modified Version:

       A. Use in the Title Page (and on the covers, if any) a title
          distinct from that of the Document, and from those of previous
          versions (which should, if there were any, be listed in the
          History section of the Document). You may use the same title
          as a previous version if the original publisher of that
          version gives permission.

       B. List on the Title Page, as authors, one or more persons or
          entities responsible for authorship of the modifications in
          the Modified Version, together with at least five of the
          principal authors of the Document (all of its principal
          authors, if it has fewer than five), unless they release you
          from this requirement.

       C. State on the Title page the name of the publisher of the
          Modified Version, as the publisher.

       D. Preserve all the copyright notices of the Document.

       E. Add an appropriate copyright notice for your modifications
          adjacent to the other copyright notices.

       F. Include, immediately after the copyright notices, a license
          notice giving the public permission to use the Modified
          Version under the terms of this License, in the form shown in
          the Addendum below.

       G. Preserve in that license notice the full lists of Invariant
          Sections and required Cover Texts given in the Document’s
          license notice.

       H. Include an unaltered copy of this License.

       I. Preserve the section Entitled “History”, Preserve its Title,
          and add to it an item stating at least the title, year, new
          authors, and publisher of the Modified Version as given on the
          Title Page. If there is no section Entitled “History” in the
          Document, create one stating the title, year, authors, and
          publisher of the Document as given on its Title Page, then add
          an item describing the Modified Version as stated in the
          previous sentence.

       J. Preserve the network location, if any, given in the Document
          for public access to a Transparent copy of the Document, and
          likewise the network locations given in the Document for
          previous versions it was based on. These may be placed in the
          “History” section. You may omit a network location for a work
          that was published at least four years before the Document
          itself, or if the original publisher of the version it refers
          to gives permission.

       K. For any section Entitled “Acknowledgements” or “Dedications”,
          Preserve the Title of the section, and preserve in the section
          all the substance and tone of each of the contributor
          acknowledgements and/or dedications given therein.

       L. Preserve all the Invariant Sections of the Document, unaltered
          in their text and in their titles. Section numbers or the
          equivalent are not considered part of the section titles.

       M. Delete any section Entitled “Endorsements”. Such a section may
          not be included in the Modified Version.

       N. Do not retitle any existing section to be Entitled
          “Endorsements” or to conflict in title with any Invariant
          Section.

       O. Preserve any Warranty Disclaimers.

     If the Modified Version includes new front-matter sections or
     appendices that qualify as Secondary Sections and contain no
     material copied from the Document, you may at your option designate
     some or all of these sections as invariant. To do this, add their
     titles to the list of Invariant Sections in the Modified Version’s
     license notice. These titles must be distinct from any other
     section titles.

     You may add a section Entitled “Endorsements”, provided it contains
     nothing but endorsements of your Modified Version by various
     parties—for example, statements of peer review or that the text has
     been approved by an organization as the authoritative definition of
     a standard.

     You may add a passage of up to five words as a Front-Cover Text,
     and a passage of up to 25 words as a Back-Cover Text, to the end of
     the list of Cover Texts in the Modified Version. Only one passage
     of Front-Cover Text and one of Back-Cover Text may be added by (or
     through arrangements made by) any one entity. If the Document
     already includes a cover text for the same cover, previously added
     by you or by arrangement made by the same entity you are acting on
     behalf of, you may not add another; but you may replace the old
     one, on explicit permission from the previous publisher that added
     the old one.

     The author(s) and publisher(s) of the Document do not by this
     License give permission to use their names for publicity for or to
     assert or imply endorsement of any Modified Version.

  5. COMBINING DOCUMENTS

     You may combine the Document with other documents released under
     this License, under the terms defined in section 4 above for
     modified versions, provided that you include in the combination all
     of the Invariant Sections of all of the original documents,
     unmodified, and list them all as Invariant Sections of your
     combined work in its license notice, and that you preserve all
     their Warranty Disclaimers.

     The combined work need only contain one copy of this License, and
     multiple identical Invariant Sections may be replaced with a single
     copy. If there are multiple Invariant Sections with the same name
     but different contents, make the title of each such section unique
     by adding at the end of it, in parentheses, the name of the
     original author or publisher of that section if known, or else a
     unique number. Make the same adjustment to the section titles in
     the list of Invariant Sections in the license notice of the
     combined work.

     In the combination, you must combine any sections Entitled
     “History” in the various original documents, forming one section
     Entitled “History”; likewise combine any sections Entitled
     “Acknowledgements”, and any sections Entitled “Dedications”. You
     must delete all sections Entitled “Endorsements.”

  6. COLLECTIONS OF DOCUMENTS

     You may make a collection consisting of the Document and other
     documents released under this License, and replace the individual
     copies of this License in the various documents with a single copy
     that is included in the collection, provided that you follow the
     rules of this License for verbatim copying of each of the documents
     in all other respects.

     You may extract a single document from such a collection, and
     distribute it individually under this License, provided you insert
     a copy of this License into the extracted document, and follow this
     License in all other respects regarding verbatim copying of that
     document.

  7. AGGREGATION WITH INDEPENDENT WORKS

     A compilation of the Document or its derivatives with other
     separate and independent documents or works, in or on a volume of a
     storage or distribution medium, is called an “aggregate” if the
     copyright resulting from the compilation is not used to limit the
     legal rights of the compilation’s users beyond what the individual
     works permit. When the Document is included in an aggregate, this
     License does not apply to the other works in the aggregate which
     are not themselves derivative works of the Document.

     If the Cover Text requirement of section 3 is applicable to these
     copies of the Document, then if the Document is less than one half
     of the entire aggregate, the Document’s Cover Texts may be placed
     on covers that bracket the Document within the aggregate, or the
     electronic equivalent of covers if the Document is in electronic
     form. Otherwise they must appear on printed covers that bracket the
     whole aggregate.

  8. TRANSLATION

     Translation is considered a kind of modification, so you may
     distribute translations of the Document under the terms of section
     4. Replacing Invariant Sections with translations requires special
     permission from their copyright holders, but you may include
     translations of some or all Invariant Sections in addition to the
     original versions of these Invariant Sections. You may include a
     translation of this License, and all the license notices in the
     Document, and any Warranty Disclaimers, provided that you also
     include the original English version of this License and the
     original versions of those notices and disclaimers. In case of a
     disagreement between the translation and the original version of
     this License or a notice or disclaimer, the original version will
     prevail.

     If a section in the Document is Entitled “Acknowledgements”,
     “Dedications”, or “History”, the requirement (section 4) to
     Preserve its Title (section 1) will typically require changing the
     actual title.

  9. TERMINATION

     You may not copy, modify, sublicense, or distribute the Document
     except as expressly provided under this License. Any attempt
     otherwise to copy, modify, sublicense, or distribute it is void,
     and will automatically terminate your rights under this License.

     However, if you cease all violation of this License, then your
     license from a particular copyright holder is reinstated (a)
     provisionally, unless and until the copyright holder explicitly and
     finally terminates your license, and (b) permanently, if the
     copyright holder fails to notify you of the violation by some
     reasonable means prior to 60 days after the cessation.

     Moreover, your license from a particular copyright holder is
     reinstated permanently if the copyright holder notifies you of the
     violation by some reasonable means, this is the first time you have
     received notice of violation of this License (for any work) from
     that copyright holder, and you cure the violation prior to 30 days
     after your receipt of the notice.

     Termination of your rights under this section does not terminate
     the licenses of parties who have received copies or rights from you
     under this License. If your rights have been terminated and not
     permanently reinstated, receipt of a copy of some or all of the
     same material does not give you any rights to use it.

  10. FUTURE REVISIONS OF THIS LICENSE

     The Free Software Foundation may publish new, revised versions of
     the GNU Free Documentation License from time to time. Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns. See
     <https://www.gnu.org/copyleft/>.

     Each version of the License is given a distinguishing version
     number. If the Document specifies that a particular numbered
     version of this License “or any later version” applies to it, you
     have the option of following the terms and conditions either of
     that specified version or of any later version that has been
     published (not as a draft) by the Free Software Foundation. If the
     Document does not specify a version number of this License, you may
     choose any version ever published (not as a draft) by the Free
     Software Foundation. If the Document specifies that a proxy can
     decide which future versions of this License can be used, that
     proxy’s public statement of acceptance of a version permanently
     authorizes you to choose that version for the Document.

  11. RELICENSING

     “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
     World Wide Web server that publishes copyrightable works and also
     provides prominent facilities for anybody to edit those works. A
     public wiki that anybody can edit is an example of such a server. A
     “Massive Multiauthor Collaboration” (or “MMC”) contained in the
     site means any set of copyrightable works thus published on the MMC
     site.

     “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
     license published by Creative Commons Corporation, a not-for-profit
     corporation with a principal place of business in San Francisco,
     California, as well as future copyleft versions of that license
     published by that same organization.

     “Incorporate” means to publish or republish a Document, in whole or
     in part, as part of another Document.

     An MMC is “eligible for relicensing” if it is licensed under this
     License, and if all works that were first published under this
     License somewhere other than this MMC, and subsequently
     incorporated in whole or in part into the MMC, (1) had no cover
     texts or invariant sections, and (2) were thus incorporated prior
     to November 1, 2008.

     The operator of an MMC Site may republish an MMC contained in the
     site under CC-BY-SA on the same site at any time before August 1,
     2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents
====================================================

To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:

       Copyright (C)  YEAR  YOUR NAME.
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.3
       or any later version published by the Free Software Foundation;
       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
       Texts.  A copy of the license is included in the section entitled ``GNU
       Free Documentation License''.

   If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the “with...Texts.” line with this:

         with the Invariant Sections being LIST THEIR TITLES, with
         the Front-Cover Texts being LIST, and with the Back-Cover Texts
         being LIST.

   If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.

   If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.


File: guix-cookbook.it.info,  Node: Indice dei concetti,  Prev: Licenza di Documentazione Libera GNU,  Up: Top

Indice dei concetti
*******************

[index]
* Menu:

* 2FA, autenticazione a due fattori:     Utilizzo di chiavi di sicurezza.
                                                              (line   6)
* amministratore di sistema:             Gestione del Sistema Guix.
                                                              (line   6)
* bluetooth, configurazione ALSA:        Server musicale con audio Bluetooth.
                                                              (line   6)
* calcolo ad alte prestazioni, HPC:      Installare Guix su un Cluster.
                                                              (line   6)
* canale:                                Canali.              (line   6)
* caratteri stumpwm:                     StumpWM.             (line  20)
* chiave di sicurezza, configurazione:   Utilizzo di chiavi di sicurezza.
                                                              (line   6)
* condividere directory, contenitore:    Contenitori Guix.    (line  38)
* disabilitazione OTP yubikey:           Utilizzo di chiavi di sicurezza.
                                                              (line  61)
* DNS dinamico, DDNS:                    Processo mcron per DNS dinamico.
                                                              (line   6)
* esporre directory, contenitore:        Contenitori Guix.    (line  38)
* evitare disallineamento ABI, contenitore: Contenitori Guix. (line  56)
* G-expressions, sintassi:               Un corso intensivo di Scheme.
                                                              (line 123)
* gestione del sistema:                  Gestione del Sistema Guix.
                                                              (line   6)
* gexps, sintassi:                       Un corso intensivo di Scheme.
                                                              (line 123)
* HPC, calcolo ad alte prestazioni:      Installare Guix su un Cluster.
                                                              (line   6)
* impacchettamento:                      Impacchettamento.    (line   6)
* installazione cluster:                 Installare Guix su un Cluster.
                                                              (line   6)
* integrazione continua (CI):            Configurazione dell'integrazione continua.
                                                              (line   6)
* Interfaccia bridge di rete:            Ponte di rete per QEMU.
                                                              (line   6)
* Interfaccia bridge di rete virtuale:   Rete instradata per libvirt.
                                                              (line   6)
* kimsufi, Kimsufi, OVH:                 Eseguire Guix su un Server Kimsufi.
                                                              (line   6)
* libvirt, switch di rete virtuale:      Rete instradata per libvirt.
                                                              (line   6)
* licenza, GNU Free Documentation License: Licenza di Documentazione Libera GNU.
                                                              (line   6)
* linode, Linode:                        Eseguire Guix su un Server Linode.
                                                              (line   6)
* lock files, for reproducibility:       Recording the Environment.
                                                              (line  39)
* mappare posizioni, contenitore:        Contenitori Guix.    (line  38)
* mpd:                                   Server musicale con audio Bluetooth.
                                                              (line   6)
* nascondi librerie di sistema, contenitore: Contenitori Guix.
                                                              (line  56)
* networking del contenitore:            Networking dei contenitori.
                                                              (line   6)
* networking, bridge:                    Ponte di rete per QEMU.
                                                              (line   6)
* networking, bridge virtuale:           Rete instradata per libvirt.
                                                              (line   6)
* nginx, lua, openresty, resty:          Configurazione di NGINX con Lua.
                                                              (line   6)
* qemu, bridge di rete:                  Ponte di rete per QEMU.
                                                              (line   6)
* reproducible research:                 Reproducible Research.
                                                              (line   6)
* S-expression:                          Un corso intensivo di Scheme.
                                                              (line 100)
* Scheme, corso intensivo:               Un corso intensivo di Scheme.
                                                              (line   6)
* server musicale, headless:             Server musicale con audio Bluetooth.
                                                              (line   6)
* sessionlock:                           Blocco sessione.     (line   6)
* sicurezza, su un cluster:              Considerazioni sulla sicurezza del cluster.
                                                              (line   6)
* stumpwm:                               StumpWM.             (line   6)
* sviluppo software, con Guix:           Sviluppo software.   (line   6)
* sviluppo, con Guix:                    Sviluppo software.   (line   6)
* U2F, Secondo Fattore Universale:       Utilizzo di chiavi di sicurezza.
                                                              (line   6)
* uscire da un contenitore:              Contenitori Guix.    (line  34)
* utilizzo del disco, su un cluster:     Utilizzo del disco del cluster.
                                                              (line   6)
* wm:                                    Personalizzazione di un Window Manager.
                                                              (line   6)
* yubikey, integrazione keepassxc:       Utilizzo di chiavi di sicurezza.
                                                              (line  78)



Tag Table:
Node: Top1343
Node: Tutorial di Scheme9617
Node: Un corso intensivo di Scheme10345
Node: Impacchettamento18711
Node: Tutorial sull'Impacchettamento19386
Node: Un pacchetto "Hello World"21945
Node: Configurazione30468
Node: File locale31280
Node: Canali32109
Node: Modifica diretta dal checkout36208
Node: Esempio esteso39060
Node: Altri sistemi di build56999
Node: Definizione di pacchetto programmabile e automatizzata58031
Node: Importatori ricorsivi58751
Node: Aggiornamento automatico61187
Node: Ereditarietà61847
Node: Ottenere aiuto62997
Node: Conclusione63836
Node: Riferimenti65043
Node: Packaging Workflows65561
Node: Packaging Rust Crates65979
Node: Common Workflow for Rust Packaging66618
Node: Cargo Workspaces and Development Snapshots73244
Node: Using Rust Libraries in Other Build Systems77518
Node: Configurazione di sistema80596
Node: Accesso automatico a una TTY specifica82743
Node: Personalizzazione del kernel84568
Node: API immagine di Sistema Guix95005
Node: Utilizzo di chiavi di sicurezza102344
Node: Processo mcron per DNS dinamico107670
Node: Connessione a una VPN Wireguard110068
Node: Personalizzazione di un Window Manager113226
Node: StumpWM113597
Node: Blocco sessione115222
Node: Xorg115731
Node: Eseguire Guix su un Server Linode117191
Node: Eseguire Guix su un Server Kimsufi125841
Node: Configurazione di un bind mount133137
Node: Ottenere sostituti da Tor135545
Node: Configurazione di NGINX con Lua138442
Node: Server musicale con audio Bluetooth140712
Node: Contenitori148832
Node: Contenitori Guix150339
Node: Contenitori di Sistema Guix155979
Node: Un contenitore Database158063
Node: Networking dei contenitori162455
Node: Macchine virtuali164668
Node: Ponte di rete per QEMU165550
Node: Rete instradata per libvirt170618
Node: Rete personalizzata basata su NAT per libvirt174733
Node: Riferimenti VM179954
Node: Gestione avanzata dei pacchetti180497
Node: Profili Guix in pratica181186
Node: Configurazione di base con i manifesti185073
Node: Pacchetti richiesti189739
Node: Profilo predefinito190806
Node: I benefici dei manifesti191484
Node: Profili riproducibili195761
Node: Sviluppo software197234
Ref: Sviluppo software-Footnote-1199047
Node: Per iniziare199295
Node: Costruire con Guix203777
Node: Il repository come canale207163
Node: Varianti di pacchetto212792
Node: Configurazione dell'integrazione continua214777
Node: Manifesto di build218354
Node: In conclusione222347
Node: Gestione dell'ambiente224224
Node: Ambiente Guix tramite direnv224588
Node: Reproducible Research228158
Ref: Reproducible Research-Footnote-1229363
Node: Setting Up the Environment229535
Node: Recording the Environment231959
Node: Ensuring Long-Term Source Code Archiving235106
Node: Referencing the Software Environment236744
Node: Installare Guix su un Cluster238659
Ref: Installare Guix su un Cluster-Footnote-1240017
Node: Configurazione di un nodo principale240186
Node: Configurazione dei nodi di calcolo244324
Node: Accesso alla rete del cluster247619
Node: Utilizzo del disco del cluster251350
Node: Considerazioni sulla sicurezza del cluster253486
Node: Gestione del Sistema Guix254782
Node: Aggiornare Postgres per Cuirass255404
Node: Ringraziamenti258083
Node: Licenza di Documentazione Libera GNU259408
Node: Indice dei concetti284753

End Tag Table


Local Variables:
coding: utf-8
End:
