Passare al contenuto

Stato delle build

Ditana mantiene un proprio repository pacman che si appoggia su Arch – 59 pacchetti, elencati integralmente in ogni esecuzione portata a termine. Un’esecuzione interrotta elenca ciò che aveva raggiunto. Ogni notte un host di build scarica la ricetta di ogni pacchetto, decide che cosa va ricompilato e lo compila in un container pulito. La regola che stabilisce che cosa succede dopo è l’unica che conta qui:

Se anche un solo pacchetto non può essere compilato, o se i suoi sorgenti non possono essere verificati, non viene pubblicato nulla.

Non «il resto viene distribuito e quel pacchetto verrà ritentato domani». Nulla. Il repository da cui installate è o l’insieme completo e coerente uscito da un’unica esecuzione, oppure l’insieme completo e coerente del giorno prima. Un repository più piccolo può garantirlo; uno grande, che si aggiorna pacchetto per pacchetto, non può – motivo per cui Ditana mantiene il proprio abbastanza piccolo da poterne rispondere come di un unico insieme.

Un’affermazione del genere vale esattamente quanto le sue prove, per cui il registro qui sotto è scritto dalla pipeline stessa, comprese le esecuzioni in cui non è stato distribuito nulla. Questa pipeline è ditana-build, ed è pubblica: il controllo di revisione è bin/pkgbuild-review-gate, e il test di installazione è bin/test-install-in-qemu.

Caricamento del registro delle build in corso…

Ogni esecuzione attraversa le stesse fasi, e il suo outcome indica quale ha raggiunto. Questi sono i quattro stati, e i colori qui sopra:

outcome Che cosa significa per voi
released È ciò che installate. Ogni pacchetto è stato compilato, ogni firma verificata, e l’intero insieme ha sostituito il repository da cui si aggiorna il vostro sistema.
in-testing L’insieme, compilato e firmato, si trova in un repository di test separato mentre viene verificato. Il vostro sistema installa ancora la versione precedente.
built L’host di build ha terminato, ma non dispone di alcuna chiave di firma – la firma avviene in seguito su un’altra macchina. Finora non si è mosso nulla.
held-back Qualcosa non ha superato i controlli, per cui non è stato distribuito nulla. Il repository da cui installate è intatto e ancora coerente.

Solo released significa che i pacchetti vi hanno raggiunto. Gli altri tre sono tappe lungo il percorso, oppure un arresto.

All’interno di un’esecuzione, ogni pacchetto riceve uno status:

status Significato
current La ricetta non è cambiata da quando è stato compilato il pacchetto esistente, e per un pacchetto -git non si è mosso nemmeno il commit upstream. Nulla da fare.
rebuilt I sorgenti sono stati scaricati e verificati sull’host, poi il pacchetto è stato compilato in un container nuovo.
review-stopped La ricetta è cambiata in un modo che deve essere esaminato da una persona. L’esecuzione termina qui.
build-failed La compilazione del pacchetto non è riuscita, o non ha prodotto alcun artefatto. L’esecuzione termina qui.

Gli ultimi due sono il motivo per cui un’esecuzione termina come held-back: basta un solo pacchetto.

La maggior parte di ciò che Ditana ricompila sono ricette AUR di terzi, pacchettizzate in un repository di cui i suoi utenti si fidano tramite la configurazione delle firme di pacman. L’AUR è una catena di approvvigionamento, ed è stato attaccato come tale: pacchetti orfani sono stati adottati e hanno ricevuto commit malevoli, motivo per cui ad agosto 2026 l’AUR ha disattivato le adozioni e i push.

Per questo ogni git pull nella pipeline viene classificato prima di compilare qualsiasi cosa. Gli incrementi di versione, i commenti, gli spazi bianchi e le somme di controllo che accompagnano un cambio di versione vengono lasciati passare. Una modifica a source=, a un url=, a una revisione VCS, a qualsiasi cosa all’interno di una funzione, a install=, a provides=, conflicts=, replaces= o validpgpkeys=, una somma di controllo che cambia senza che cambi la versione, una nuova dipendenza che pacman non conosce, una riga # Maintainer: modificata o svuotata – ognuna di queste ferma l’esecuzione. Per farlo, la ricetta non viene mai caricata dalla shell: eseguire il file sospetto è proprio ciò che va evitato, per cui l’analisi è statica, e quando non è certa blocca anziché lasciar passare.

Misurato sugli ultimi dodici mesi di storia reale dei pacchetti, questo ferma un’esecuzione circa una volta ogni tre giorni e mezzo. Non è un difetto da eliminare con una regolazione; è il prezzo della regola del tutto o niente, pagato in anticipo.

Alcune delle ricette che Ditana ricompila non hanno alcun manutentore upstream – la loro riga # Maintainer: è vuota. Per questo una riga del manutentore svuotata ferma un’esecuzione anziché essere lasciata passare: una ricetta orfana è quella che qualcuno può adottare.

La revisione riguarda i metadati di pacchettizzazione, non il codice sorgente upstream. Quando una ricetta compila a partire da una revisione git, il contenuto di quella revisione non viene esaminato da nessuna parte di questa pipeline. Il vantaggio di Ditana rispetto a un servizio di ricompilazione senza revisione è reale ma limitato, e dichiararne il limite fa parte dell’affermazione.

Compilare e firmare un repository non equivale a poterlo usare per installare. Tra il repository di test e il rilascio c’è un ulteriore passaggio: l’host di build installa proprio quel repository in una propria macchina virtuale, senza presidio, guidato da un file di risposte su una piccola unità di configurazione – lo stesso meccanismo che un provider di hosting userebbe tramite PXE, motivo per cui non viene simulata alcuna pressione di tasti.

Due condizioni devono essere soddisfatte, e il registro indica quale di esse è stata raggiunta.

fase Che cosa era successo
installing Il supporto è in esecuzione. Non è ancora stato installato nulla.
installed Il programma di installazione ha raggiunto il riavvio finale.
booted Il sistema installato si è avviato da solo e ha risposto sulla porta 22. Il test è superato.

La distinzione è importante, perché i due fallimenti sono bug diversi. Un’esecuzione che si ferma a installing ha prodotto un repository da cui nessuno può installare. Una che si ferma a installed ha prodotto un sistema scritto correttamente che però non si avvia, ed è il tipo di difetto che nessuna quantità di compilazioni riesce a individuare.

Arrivare a booted significa molto più di quanto l’espressione lasci intendere. Il bootloader è stato eseguito, l’immagine initramfs ha trovato e importato il pool ZFS, systemd ha raggiunto la modalità multiutente, la rete è diventata attiva e un servizio si è avviato. Nel sistema guest non viene iniettato nulla per predisporre una qualsiasi di queste azioni: install-openssh è attivato per impostazione predefinita, per cui un banner sulla porta 22 è opera del sistema installato stesso.

Quando il test fallisce, il registro contiene un’immagine dello schermo del sistema guest nel momento in cui l’ambiente di test ha rinunciato. Il supporto di installazione non scrive nulla su una console seriale una volta che il suo bootloader ha ceduto il controllo, per cui tutto ciò che il programma di installazione disegna si trova su quello schermo e da nessun’altra parte – un programma di installazione in attesa di una risposta è visibile lì e in nessun log.

Un test fallito non rilascia nulla. I pacchetti restano nel repository di test, e il repository da cui installate rimane intatto.

La macchina che compila dispone di una sottochiave di firma, non della chiave primaria.

Compila, firma con quella sottochiave, carica nel repository di test, installa quel repository in una macchina virtuale e rilascia in produzione solo se l’installazione è riuscita. Tenere la chiave lontana dall’host di build è una possibilità che la pipeline supporta ancora, ed era il modo in cui Ditana funzionava fino ad agosto 2026; vi si è rinunciato perché un rilascio subordinato a un’installazione di prova deve avvenire sulla macchina che ha appena compilato, e la separazione inseriva nel mezzo una seconda macchina e un passaggio manuale. Ciò che la sottochiave offre in cambio: può essere revocata e sostituita separatamente, non può certificare altre chiavi, e l’impronta digitale con cui gli utenti effettuano la verifica non cambia mai.

Ciò che questo protegge è la chiave, non i pacchetti: la macchina di firma appone la propria firma a ciò che l’host di build ha prodotto, senza esaminarlo. Ciò che impedisce è che la macchina che esegue script di build altrui possa far firmare dati arbitrari in qualsiasi momento.

Il registro è in semplice JSON e non viene generato da questo sito web:

  • /build-history/index.json – l’indice continuamente aggiornato delle esecuzioni più recenti.
  • /build-history/<timestamp>.json – un file per esecuzione: outcome, message, counts, un oggetto test-install se l’esecuzione è stata testata, e un array packages le cui voci contengono name, status, seconds, un eventuale detail e i percorsi dei log di quel pacchetto.
  • L’oggetto test-install contiene result, lo stage raggiunto dal sistema guest, l’iso e l’answer-file con cui è stato guidato e, se l’installazione non è riuscita, un percorso screenshot sotto /build-history/logs/<timestamp>/test-install/ che contiene lo schermo del sistema guest nel momento in cui l’ambiente di test ha rinunciato.
  • /build-history/logs/<timestamp>/<package>/ – ciò che makepkg ha registrato durante la compilazione di quel pacchetto, suddiviso per fase (prepare, build, check, package). Ogni pacchetto ricompilato in un’esecuzione è collegato dalla sua riga qui sopra, e anche un pacchetto la cui compilazione non è riuscita viene registrato – è proprio quello che vale la pena leggere.

I nomi dei server, gli indirizzi, i percorsi e il nome di login dell’account di build vengono rimossi dai registri e dai log prima che vengano scritti. Nessun altro elemento viene filtrato; il testo d’errore che vedete è il testo d’errore che ha visto la pipeline.

Ogni pacchetto qui presente è compilato a partire da una ricetta pubblicamente disponibile che indica la propria sorgente upstream. Licenze spiega dove trovare entrambe, e tratta l’unico caso in cui la licenza stessa è contestata: i pacchetti ZFS, di cui Ditana distribuisce i sorgenti e gli strumenti in spazio utente, ma mai un modulo del kernel compilato.

Questa traduzione è stata realizzata automaticamente. I lettori la migliorano su Weblate.