Bucket & Code Server IDE: guida utente
Bucket & Code Server IDE (QPKG bucketvs) conserva codice sorgente e file su un NAS QNAP e vi compila software. Porta con sé un proprio server web, propri strumenti e propri account.
Questa guida descrive il pacchetto così come funziona sul NAS.
Indice
- Che cosa gira sul NAS
- Installare il pacchetto
- Primo accesso
- Lavorare nel pannello
- Account
- La cartella dei dati
- Rete
- Dietro un reverse proxy (Plesk)
- Nomi host dei moduli
- Pubblicare su internet (Cloudflare Tunnel)
- Moduli
- Git
- Runner CI
- SVN e Bucket
- Editor e strumenti IA
- Toolchain e ambienti
- App Builder
- Repository dei pacchetti
- Officina del kernel
- Job cron e operazioni
- Backup
- Notifiche
- Log e pacchetto diagnostico
- Aggiornamenti
- Il comando bvs
- File e cartelle
Che cosa gira sul NAS
| Parte | Che cosa fa | Dove ascolta |
|---|---|---|
| nginx | l’unica porta sulla LAN: serve il pannello e passa ogni percorso al suo modulo | 9950 (HTTP), 9951 (HTTPS) |
| bvsd | avvia e sorveglia tutti gli altri processi, tiene account e impostazioni, esegue job e job cron, risponde al pannello | due socket Unix in /usr/bin/bucketvs/var/run/ |
| Git (Forgejo) | hosting Git con un’interfaccia web | un socket Unix in /usr/bin/bucketvs/var/run/forgejo/, e 9952 per Git via SSH |
| SVN e Bucket (httpd) | repository Subversion e cartelle WebDAV con cronologia | 127.0.0.1:9961, o la porta libera successiva quando un altro programma la occupa |
| Editor (code-server) | VS Code nel browser, un’istanza per account | un socket Unix per account in /usr/bin/bucketvs/var/run/ide/ |
| CI | il runner di Forgejo Actions | nessuna porta propria; nginx ascolta per lui su 127.0.0.1:9960 finché il modulo è attivo, o sulla porta libera successiva quando un altro programma occupa 9960 |
Il nucleo (nginx, bvsd, il pannello, i job cron, le toolchain) è sempre attivo. Git, CI, SVN e Bucket e l’Editor sono moduli che un admin attiva e disattiva. Su ogni indirizzo del NAS i moduli rispondono sotto i loro percorsi: /git/, /svn/, /bucket/, /ide/. Il pannello è su /, e questa guida su /guide/.
Mentre il pacchetto è in esecuzione, i suoi programmi sono in /usr/bin/bucketvs/bin. Tutto ciò che il pacchetto conserva (account, impostazioni, repository, ambienti, log) sta in una sola cartella su un volume dati: la cartella dei dati.
Installare il pacchetto
Il pacchetto richiede QTS 6.0 o QuTS hero 6.0 o successivi, su un NAS x86_64 o ARM a 64 bit; c’è un pacchetto per architettura (bucketvs_<versione>_x86_64.qpkg, bucketvs_<versione>_arm_64.qpkg). È firmato: installalo da App Center (da un repository che lo elenca, o con Installazione manuale e il file scaricato). App Center verifica la firma; non serve consentire le app senza una firma valida.
L’installazione crea l’utente di servizio bucketvs (per Forgejo e httpd), il collegamento /usr/bin/bucketvs alla cartella di installazione, e avvia bvsd. I log di sistema indicano la cartella dei dati.
Dove nasce la cartella dei dati
Al primo avvio la cartella dei dati è BucketVS sul volume su cui è installato il pacchetto, per esempio /share/CACHEDEV1_DATA/BucketVS (QTS) o /share/ZFS2_DATA/BucketVS (QuTS hero). In seguito può essere spostata su un altro volume dal pannello (Spostare la cartella dei dati).
Il pacchetto ricorda la sua cartella dei dati in /etc/config/bucketvs-data-root, un file che sopravvive al pacchetto. Rimuovere il pacchetto lascia la cartella dei dati e questo file, quindi un’installazione dopo una rimozione riparte sugli stessi dati e sugli stessi account. Un avvio non dipende mai da una cartella che non c’è. Quando la cartella dei dati non c’è più (eliminata, su un disco sostituito, o su un volume offline in quel momento), l’avvio crea BucketVS sul volume del pacchetto, una cartella nuova a meno che ce ne sia già una con quel nome, e in una cartella nuova il primo accesso imposta la password dell’amministratore. Vale dopo una reinstallazione come per un pacchetto installato, anche all’accensione del NAS. I log di sistema riportano un avviso, e i file .prev conservano il vecchio percorso: /etc/config/bucketvs-data-root.prev e, per un pacchetto installato, anche etc/data-root.prev nella cartella di installazione. Se la vecchia cartella era su un volume che in quel momento era solo offline, rimetti online il volume, ferma il pacchetto, copia quel file sopra etc/data-root nella cartella di installazione (per esempio /share/CACHEDEV1_DATA/.qpkg/bucketvs/etc/data-root) e avvia il pacchetto: riparte sui vecchi dati.
Aprire il pannello da App Center
Apri sul pacchetto in App Center apre il pannello sulla porta 9950 (HTTP) o 9951 (HTTPS). Quando le porte vengono cambiate nel pannello (Porte), il pacchetto comunica le nuove ad App Center al suo avvio successivo.
Avvio automatico da una sessione SSH
Finché l’interruttore del pacchetto in App Center è attivo, il NAS avvia il pacchetto all’accensione. In una sessione SSH sul NAS, come admin, lo script di servizio imposta lo stesso interruttore:
/etc/init.d/bucketvs.sh disable # il prossimo avvio viene rifiutato, anche all’accensione del NAS
/etc/init.d/bucketvs.sh enable # il pacchetto torna ad avviarsi all’accensione
Ciascuno dei due comandi scrive solo l’interruttore (Enable in /etc/config/qpkg.conf), stampa che cosa ha impostato e scrive la stessa riga nei log di sistema. Dopo disable un pacchetto in esecuzione continua a girare, ed enable non avvia nulla: lo fanno stop e start, e start rifiuta finché il pacchetto è disattivato. status dice se bvsd è in esecuzione.
Primo accesso
Apri il pannello su https://<indirizzo del NAS>:9951/ o http://<indirizzo del NAS>:9950/. L’indirizzo HTTPS usa all’inizio un certificato autofirmato, quindi il browser mostra un avviso finché il dispositivo non se ne fida; la sezione Il certificato mostra come confrontarne l’impronta.
Una nuova installazione non ha alcun account. Finché il primo amministratore non ha una password, il pannello si apre su un’unica schermata, “Imposta la password dell’amministratore”, per l’account administrator. Digita una password due volte: almeno 10 caratteri e al massimo 72 byte. Salvarla crea l’account e ti fa accedere.
La schermata accetta una password per 60 minuti dopo l’avvio del pacchetto. Poi dice che la finestra di configurazione si è chiusa; riavviare Bucket & Code Server IDE in App Center apre una nuova finestra di 60 minuti.
Accetta una password solo dalla rete locale: dal NAS stesso, o da un indirizzo di un intervallo privato (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,fc00::/7,fe80::/10).Mentre la schermata è aperta, i log di sistema di QTS mostrano una voce informativa per ogni indirizzo LAN del NAS, per esempio:
bucketvs: no administrator yet: open https://192.168.1.20:9951/ within 60 minutes to set the administrator's passwordRifiuta una richiesta arrivata tramite un proxy (una che porta
X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto,X-Real-IPoForwarded), anche da un proxy sulla LAN: apri il pannello direttamente da un computer della rete locale per impostare la password.
Da una sessione SSH sul NAS, /usr/bin/bucketvs/bin/bvs user password administrator crea l’account quando non ce n’è ancora nessuno e stampa una password casuale; il pannello chiede poi una tua password al primo accesso (Quando un admin è bloccato fuori).
Dopo il primo accesso la Panoramica dice che è attivo solo il nucleo. Il riquadro di ogni modulo dice che cosa offre e ha un pulsante che lo attiva, per esempio Attiva Git: attiva quelli che ti servono (Moduli).
Lavorare nel pannello
Il pannello funziona come un editor di codice: ogni pagina si apre in una scheda, e una tavolozza dei comandi raggiunge le pagine e le azioni per nome.
- Barra delle attività (le icone a sinistra). Ogni icona apre la sua pagina e mostra il suo albero nella barra laterale: i moduli, i repository e i bucket, le app, i pacchetti, gli ambienti, i job e i backup. Un punto su un’icona segnala un modulo in difficoltà, una build non riuscita o un backup non riuscito. Un clic sull’icona della pagina in primo piano nasconde la barra laterale; Ctrl+B fa lo stesso.
- Schede. Una pagina aperta con un solo clic è un’anteprima, in corsivo: la pagina successiva si apre al suo posto. Modifica la pagina o fai doppio clic sulla sua scheda per tenerla. Le schede tornano dopo un ricaricamento, per ogni account in ogni browser. In una finestra larga almeno 1280 pixel, Sposta la scheda sull’altro lato (
Ctrl+\) mostra due pagine affiancate. - Gli oggetti e i loro menu. Un clic su una riga della barra laterale, una riga di tabella o una scheda apre quell’oggetto: la sua pagina passa in primo piano, con l’oggetto cerchiato di verde o con i dettagli aperti. L’indirizzo nomina l’oggetto, quindi indietro, avanti e un link copiato ci riportano. Un doppio clic tiene la scheda. Un clic destro, Maiusc+F10 o una pressione prolungata su uno schermo tattile apre il menu dell’oggetto: i modi di aprirlo (in questa scheda, in una scheda tenuta, sull’altro lato, in una nuova scheda del browser), ciò che la sua pagina può farne, e la copia del nome e dell’indirizzo. Il menu di una scheda la chiude, chiude le altre schede, quelle a destra o tutte. Solo un elemento segnato ↗ lascia il pannello. L’icona Amministrazione apre la pagina Sistema.
- Tavolozza dei comandi. Ctrl+Maiusc+P (o Ctrl+K, o F1) elenca i comandi che il tuo ruolo può eseguire: aprire una pagina, compilare o pubblicare un’app, avviare un backup, riavviare un modulo, aprire una shell in un ambiente. Ctrl+P va a una pagina, un’app, un repository, un ambiente o un pacchetto con poche lettere del suo nome.
- Pannello inferiore (Ctrl+J). Job mostra i job in corso e recenti con il loro avanzamento e il loro log. Problemi elenca ciò che segnalano i moduli: build fallite, destinazioni di backup disattivate, moduli in difficoltà, un certificato in scadenza, e i rilievi dell’ispettore ELF per l’app in primo piano. Output segue il job che hai avviato per ultimo.
- Spostare e ridimensionare. Trascina un bordo per cambiare la dimensione di ciò che delimita: la barra laterale, il pannello inferiore, due pagine affiancate, o due parti di una pagina affiancate, come una procedura guidata e il suo riepilogo o l’elenco dei file di un progetto e il file. Un doppio clic su un bordo lo rimette a posto. Una finestra di dialogo si sposta dal titolo e si ridimensiona da un bordo o dall’angolo in basso a destra; un doppio clic sul titolo la rimette al centro. Per mettere il pannello inferiore accanto alle pagine, trascina la sua intestazione sul bordo destro dell’editor o fai clic sul pulsante accanto alla sua ×; trascinalo sul bordo inferiore, o fai di nuovo clic sul pulsante, per rimetterlo in basso. Una scheda si può trascinare in un altro punto della barra delle schede o sull’altro lato. Il pannello tiene ogni dimensione e posizione per il tuo account in questo browser, e Ripristina il layout (nella tavolozza dei comandi, o sotto il pulsante del tuo account in fondo alla barra delle attività) le rimette tutte. Da tastiera, le frecce spostano un bordo selezionato (con Maiusc a passi più lunghi, Home lo rimette a posto), Ctrl+Maiusc+Sinistra e Destra spostano una scheda selezionata, e una finestra di dialogo ha in alto una barra e in basso a destra una maniglia con cui le frecce la spostano e la ridimensionano. Su un telefono le finestre di dialogo e il pannello inferiore restano dove sono.
- Barra di stato. Stati dei moduli, job in corso, problemi, spazio libero sul volume dati, il certificato, l’account connesso, la lingua (l’editor la adotta al prossimo avvio, in inglese per svedese e olandese; Git la segue, a meno che tu non ne scelga un’altra lì), il tema (scuro, chiaro, come il sistema, blu profondo, grafite o carta: appartiene al tuo account, e l’editor e Git lo seguono, a meno che tu non ne scelga un altro lì) e la versione. Ogni elemento apre il punto in cui guardare meglio.
- Tastiera. Ctrl+/ o ? elenca le scorciatoie. Una scheda del browser tiene Ctrl+W e Ctrl+Tab per sé, quindi il pannello chiude una scheda con Alt+W e cambia scheda con Alt+PagGiù e Alt+PagSu.
- Su un telefono le prime attività sono in basso, Altro apre la barra laterale con il resto, e le pagine aperte sono un elenco in alto.
Account
Il pannello ha i propri account. Gli account di QTS non vi accedono.
Ruoli
| Ruolo | Che cosa può fare |
|---|---|
| viewer | legge il pannello; le pagine Backup, Archiviazione, Utenti e Log sono per gli admin. In Forgejo non crea, non fa fork e non importa alcun repository, non crea alcuna organizzazione e non fa mai push; legge i repository SVN e i bucket su cui ha diritti e non scrive in nessuno |
| member | legge ciò che legge un viewer, e scrive: fa push nei repository Git in cui riceve l’accesso in scrittura, scrive nei repository SVN e nei bucket su cui ha lettura e scrittura, e vi ripristina versioni precedenti dei file. In Forgejo non crea, non fa fork e non importa alcun repository e non crea alcuna organizzazione, e non può fare push in un repository che un account con ruolo inferiore a developer possiede o amministra, né, finché il modulo CI è attivo, in un repository con le Actions attive. Non ha editor, job cron né build |
| developer | inoltre apre l’editor, legge le righe bvs use delle toolchain installate, crea, modifica ed esegue i propri job cron, crea e compila app, pubblica pacchetti nel repository (un admin li elenca), verifica moduli del kernel, e crea repository Git i cui workflow girano sul NAS finché il modulo CI è attivo |
| admin | tutto: account, impostazioni, archiviazione, rete, moduli, toolchain, ambienti, ogni job cron, attivazione delle app, caricamento dei moduli del kernel, elenco dei pacchetti nel repository |
Il ruolo developer è root sul NAS: i suoi comandi cron girano come root, così come il terminale del suo editor e, finché il modulo CI è attivo, i workflow dei repository in cui può fare push. Dallo solo a chi daresti la password admin del NAS. A chi scrive soltanto nei repository basta il ruolo member.
In Il tuo account ognuno vede il proprio ruolo e ciò che consente, con un link a questa sezione. Una pagina sopra il ruolo di qualcuno dice quale ruolo richiede, e ciò che cambia solo un admin è indicato come tale dove compare. Rete, Git e CI mostrano agli altri le loro impostazioni come valori, con «Non impostato» dove un valore manca.
I workflow girano come root sul NAS, quindi bvsd tiene le Actions disattivate in ogni repository Git che un member o un viewer possiede o in cui un tale account può scrivere: dare a un tale account l’accesso in scrittura a un repository ne disattiva le Actions entro un minuto, e la pagina Git elenca questi repository per gli admin. Per usare le Actions in uno di essi, togli prima quell’accesso in scrittura in Forgejo, oppure trasferisci un repository che un tale account possiede all’account di un developer.
Creare e modificare account
Un admin gestisce gli account nella pagina Utenti.
- Un nuovo account parte con il ruolo viewer. Developer e admin si scelgono di proposito: il ruolo developer è root sul NAS (sopra).
- Un nuovo account parte senza job cron, anche quando un account con lo stesso nome ne aveva.
- Un nome ha da 2 a 32 caratteri: prima una lettera minuscola, poi lettere minuscole, cifre,
.,_o-. Due tra.,_,-di seguito, o uno alla fine, sono rifiutati. Lo sono anche i nomi che Forgejo riserva (admin,api,usere altri),bucketvs(l’utente di sistema del pacchetto),cliesystem(bvsd li usa entrambi). - “Deve scegliere la propria password al primo accesso” fa sì che l’account imposti la propria password prima di poter fare qualunque altra cosa.
- Disattivare un account chiude subito le sue sessioni e ferma i suoi token API. I suoi dati restano. Anche i suoi job cron restano, ma non girano finché è disattivato, e un’esecuzione in corso di uno di essi viene fermata.
- Dare a un account il ruolo member o viewer fa lo stesso con i suoi job cron: restano, non girano finché il suo ruolo è inferiore a developer, e un’esecuzione in corso viene fermata.
- Un viewer non fa mai push in Git, nemmeno dove ha ricevuto l’accesso in scrittura in Forgejo. Un account che deve fare push riceve il ruolo member.
- Eliminare un account lo rimuove con le sue sessioni e i suoi token API. La sua cartella home va in
trash/home/<nome>-<ora>nella cartella dei dati, dove il job “Svuota il cestino” la rimuove dopo 7 giorni, e la sua cartellatmp/tmux-<nome>viene rimossa. I suoi job cron vengono eliminati con le loro esecuzioni e i loro log. - L’ultimo admin attivo non può essere declassato, disattivato o eliminato.
- “Imposta una nuova password” chiude le sessioni dell’account e revoca i suoi token API.
Password e sessioni
- Una password ha almeno 10 caratteri e al massimo 72 byte.
- Cambiare la propria password (in Il tuo account) chiude le altre tue sessioni e revoca i tuoi token API. La sessione in cui l’hai cambiata resta connessa.
- Una sessione termina 12 ore dopo la sua ultima richiesta, e in ogni caso 7 giorni dopo l’accesso. Un account tiene al massimo 32 sessioni; un accesso in più chiude quella usata meno di recente.
- Il cookie di sessione è
HttpOnlyeSameSite=Lax. È marcatoSecurequando il browser ha raggiunto il NAS via HTTPS, direttamente o tramite un proxy attendibile.
Password errate
- Cinque accessi falliti entro 15 minuti da un indirizzo bloccano quell’indirizzo per 15 minuti, anche con la password giusta. Un client IPv6 conta come la sua rete /64.
- Cinque errori per un account da un indirizzo bloccano quell’account da quell’indirizzo per 15 minuti.
- Gli errori per un account da molti indirizzi rallentano i suoi accessi successivi: 125 ms dopo un errore, raddoppiando fino a 2 secondi. Dalla rete locale non lo bloccano mai.
- Da internet (qualsiasi indirizzo fuori dalla rete locale), 20 accessi falliti per un account dall’ultimo riuscito lo bloccano lì, da qualunque indirizzo siano arrivati; allora lì viene rifiutata anche la password giusta. L’account accede ancora dalla rete locale. Un admin lo sblocca nella pagina Utenti (Sblocca) o con
bvs user unlock <nome>, oppure gli assegna una nuova password. Il numero si imposta nella pagina Utenti, sotto Accessi da internet; 0 disattiva questo blocco. - I conteggi sono tenuti in memoria, quindi un riavvio di bvsd li azzera; un blocco resta finché non viene tolto.
Dietro un proxy, l’indirizzo contato è quello che il proxy riporta, ma solo quando il proxy è un proxy attendibile. Altrimenti ogni client conta come l’indirizzo stesso del proxy, e cinque password sbagliate di chiunque bloccano tutti per 15 minuti.
Autenticazione a due fattori
Ogni account lo attiva per sé in Il tuo account: scansiona il codice QR con un’app di autenticazione (o digita la chiave), poi inserisci il codice a 6 cifre che l’app mostra. Da quel momento l’accesso chiede un codice dopo la password.
- I codici seguono la RFC 6238: 6 cifre, un nuovo codice ogni 30 secondi. Un codice in anticipo o in ritardo di 30 secondi è accettato. Lo stesso codice non è mai accettato due volte.
- Se un codice appena generato fallisce, l’orologio del telefono è probabilmente sbagliato; impostalo sull’ora automatica.
- Disattivarlo richiede la password dell’account.
- Per un telefono perso, un admin lo disattiva nella pagina Utenti. A quel punto basta la password per accedere.
Token API
Script e CI usano token API invece di una password. In Il tuo account, “Nuovo token” ne crea uno:
- Ha la forma
bvs_seguito da 40 cifre esadecimali, ed è mostrato una sola volta. bvsd ne conserva solo l’hash. - Uno script lo invia come
Authorization: Bearer bvs_.... - I suoi ambiti sono
read,writeeadmin, che corrispondono ai ruoli viewer, developer e admin. Un token agisce con il suo ambito più alto, mai al di sopra del ruolo attuale del suo proprietario, quindi declassare un account declassa anche i suoi token. Nessun ambito corrisponde a member: un member crea tokenread. - Una nuova password revoca tutti i token del proprietario. I token di un proprietario disattivato smettono di funzionare.
- Un token non può cambiare le password né l’autenticazione a due fattori, e non può creare o eliminare token: per questo serve una sessione connessa. Un token trapelato quindi non può chiudere fuori il suo proprietario.
Quando un admin è bloccato fuori
L’admin del NAS può reimpostare qualsiasi account da una sessione SSH sul NAS. Il comando bvs parla con bvsd su un socket che solo root può aprire (/usr/bin/bucketvs/var/run/bvsd-cli.sock, modalità 600):
/usr/bin/bucketvs/bin/bvs user list
/usr/bin/bucketvs/bin/bvs user password administrator
/usr/bin/bucketvs/bin/bvs user totp-reset administrator
/usr/bin/bucketvs/bin/bvs user unlock administrator
bvs user password <nome>imposta una nuova password casuale di 20 caratteri e la stampa. L’account deve sceglierne una propria al prossimo accesso. Le sue sessioni terminano e i suoi token API vengono revocati. Su una nuova installazione senza ancora alcun account,bvs user password administratorcrea l’account.bvs user totp-reset <nome>disattiva l’autenticazione a due fattori per l’account.bvs user unlock <nome>toglie il blocco dell’account dopo troppe password errate da internet.
Ogni richiesta su quel socket agisce come l’admin integrato cli ed è scritta in log/audit.log nella cartella dei dati. Per questi comandi bvsd deve essere in esecuzione.
La cartella dei dati
La cartella dei dati è la cartella che contiene tutto ciò che il pacchetto conserva. Il suo percorso è l’unica riga di /usr/bin/bucketvs/etc/data-root. La pagina Archiviazione la mostra, con il volume su cui si trova e lo spazio libero lì.
bvsd si avvia solo su una cartella dei dati che è una cartella su un volume vero. L’avvio del pacchetto lo controlla prima: una cartella mancante, o una su tmpfs o ramfs, dà una nuova cartella dei dati sul volume di installazione, come descritto in Dove nasce la cartella dei dati. Un volume offline lascia il suo punto di montaggio come cartella vuota nella RAM del NAS, e le impostazioni scritte lì sparirebbero al riavvio successivo. bvsd stesso rifiuta una cartella così solo quando viene avviato a mano, e il motivo va allora nei log di sistema di QTS.
Che cosa bvsd dà a ogni processo
QTS tiene /tmp in un piccolo disco RAM e /root su un disco RAM che un riavvio svuota. Per questo ogni processo che bvsd avvia (programmi dei moduli, job cron, installazioni) riceve i suoi file temporanei e la sua cartella home nella cartella dei dati:
| Variabile | Valore |
|---|---|
HOME | <cartella dei dati>/home/<utente> |
TMPDIR | <cartella dei dati>/tmp |
XDG_CACHE_HOME, XDG_CONFIG_HOME | .cache e .config in quella home |
npm_config_cache | .npm in quella home |
PATH | ~/.local/bin, ~/.npm-global/bin, poi bin, sbin e node/bin del pacchetto, poi le cartelle del sistema |
SSL_CERT_FILE, GIT_SSL_CAINFO, CURL_CA_BUNDLE | il bundle CA del pacchetto, /usr/bin/bucketvs/etc/ssl/cacert.pem |
TZ | il fuso orario del NAS, come impostato in QTS |
SHELL, EDITOR | bash e nano del pacchetto |
LANG, LESSCHARSET | C.UTF-8 e utf-8, così i nomi di file con lettere accentate appaiono come sono |
Spostare la cartella dei dati
La pagina Archiviazione sposta l’intera cartella dei dati in un’altra cartella sotto /share. Scegli una cartella condivisa o un volume; i dati vanno in una nuova cartella chiamata BucketVS al suo interno. Per usare una cartella stessa, apri una cartella vuota chiamata BucketVS. Le cartelle condivise si creano in QTS (Pannello di controllo, Cartelle condivise); dentro una cartella condivisa o un volume, la pagina può creare una nuova cartella. Il selettore si apre dove si trovano ora i dati e lo dice; da lì apri la cartella condivisa o il volume in cui devono essere spostati.
La pagina verifica la destinazione prima che lo spostamento inizi ed elenca ogni motivo per cui ne rifiuta una:
- il percorso deve essere sotto
/share, e non/sharestesso; - nessun
:,&,|o carattere di controllo in alcuna parte del percorso, né nel percorso a cui porta un collegamento; - non la cartella dei dati attuale, non una cartella al suo interno, non una cartella che la contiene;
- una cartella nuova, o una vuota;
- un file system che conserva proprietari e permessi Unix (FAT, exFAT e NTFS sono rifiutati: Forgejo e SVN hanno bisogno di proprietari e modalità);
- un volume montato con
exec,devesuid, di cui gli ambienti di build hanno bisogno; - scrivibile, con spazio libero per i dati più il 10 %.
Mentre lo spostamento è in corso:
- Git, CI, SVN e Bucket e l’Editor non rispondono. Il pannello resta attivo e mostra l’avanzamento.
- Nessuna nuova esecuzione cron parte. Un’esecuzione già in corso continua.
- Attivare o disattivare un modulo è rifiutato finché lo spostamento non termina.
Dopo il cambio, bvsd si ferma e riparte sulla nuova radice, quindi il pannello sparisce per qualche secondo.
Quando lo spostamento fallisce, la vecchia cartella dei dati resta in uso e i moduli ripartono. L’errore del job dice che cosa è andato storto e che fine ha fatto la copia:
- Un volume pieno, o un annullamento, rimuove ciò che lo spostamento ha creato.
- Qualsiasi altro errore (la copia, la verifica, la scrittura su disco) conserva la copia, marcata con un file chiamato
INCOMPLETE, e la elenca nella pagina Archiviazione sotto “Copie rimaste da spostamenti non riusciti”. - Un arresto del pacchetto durante lo spostamento tiene la vecchia radice come cartella dei dati. All’avvio successivo bvsd segnala lo spostamento incompiuto nei log di sistema ed elenca la copia.
La vecchia copia e le copie rimaste
Dopo uno spostamento riuscito, la vecchia cartella dei dati resta dov’era, con un file chiamato MOVED-TO al suo interno. Niente la usa. “Rimuovi la vecchia copia” nella pagina Archiviazione la elimina, e “Rimuovi questa copia” elimina una copia rimasta da uno spostamento non riuscito. Entrambe le rimozioni restano su un solo file system e non seguono mai un collegamento. Una cartella che è un punto di montaggio o la cartella stessa di una cartella condivisa viene svuotata e conservata.
Rete
La pagina Rete contiene le porte, la modalità HTTP semplice, i nomi host dei moduli, i proxy attendibili, l’URL pubblico e il certificato. Il salvataggio riavvia ciò di cui la modifica ha bisogno e lo elenca.
Porte
| Impostazione | Predefinito | Che cos’è |
|---|---|---|
| HTTPS | 9951 | il pannello e i moduli via TLS |
| HTTP | 9950 | il pannello e i moduli via HTTP semplice |
| Git via SSH | 9952 | Git via SSH |
| Porta SSH negli URL di clonazione | 0 | la porta mostrata negli indirizzi di clonazione SSH; 0 significa la porta SSH qui sopra. Impostala quando un router inoltra un’altra porta al NAS. |
| Host SSH negli URL di clonazione | vuoto | il nome o l’indirizzo mostrato negli indirizzi di clonazione SSH. Vuoto significa il nome host Git, altrimenti l’host dell’URL pubblico, altrimenti l’indirizzo LAN del NAS; per un nome pubblicato tramite il Cloudflare Tunnel, l’indirizzo LAN e la porta Git via SSH. Impostalo su un nome solo DNS o sull’indirizzo del router quando il router inoltra la porta SSH. |
Le porte vanno da 1024 a 65535 e sono diverse tra loro. Le porte dei moduli su 127.0.0.1 (9960 e 9961) sono rifiutate, e così la porta che usa httpd o il server del runner CI quando un altro programma ha preso 9960 o 9961 (il messaggio la nomina). Quando il salvataggio lascia nginx sulle vecchie porte perché non ha potuto usarne una nuova, una notifica dice perché. nginx ascolta anche su IPv6 quando il NAS lo ha.
HTTP semplice
- “Servi” (il predefinito): il pannello e i moduli rispondono anche su HTTP semplice. Tienilo quando un proxy sulla LAN parla HTTP semplice alla porta 9950.
- “Reindirizza a HTTPS”: una richiesta su HTTP semplice riceve un reindirizzamento (307) alla porta HTTPS. Una richiesta da un proxy attendibile che dice che il suo client ha usato HTTPS è servita su HTTP semplice, così un tale proxy non va in loop.
La pagina di accesso avvisa quando è arrivata via HTTP semplice: la password attraversa allora la rete in chiaro.
Il certificato
Al primo avvio bvsd crea un certificato autofirmato (ECDSA P-256) per:
- il nome host del NAS, i nomi host dei moduli e
localhost; - gli indirizzi LAN del NAS e
127.0.0.1.
È valido 825 giorni, il massimo che i dispositivi Apple accettano, anche per un certificato reso attendibile a mano. bvsd lo controlla all’avvio e una volta al giorno, e ne crea uno nuovo quando restano 30 giorni o meno, quando cambia l’insieme dei nomi, o quando la sua chiave non corrisponde. Uno nuovo invia una notifica. La pagina Rete mostra i suoi nomi, la sua validità e la sua impronta SHA-256: confronta l’impronta prima che un dispositivo se ne fidi.
“Aggiungi il tuo certificato” accetta una catena di certificati e la sua chiave privata in formato PEM:
- prima il certificato del server, poi i certificati intermedi;
- una chiave senza passphrase (nginx si avvia senza intervento);
- la chiave deve appartenere al primo certificato, ogni certificato deve essere firmato dal successivo, nessuno può essere scaduto, e il primo deve nominare i suoi host come subject alternative name.
La coppia è salvata in etc/tls/ nella cartella dei dati con modalità 600. Quando un certificato caricato scade o smette di superare questi controlli, nginx serve al suo posto quello autofirmato e una notifica dice perché. Anche un certificato caricato con 30 giorni o meno rimasti invia una notifica. “Nuovo certificato autofirmato” crea una nuova coppia autofirmata e torna a essa.
I client che passano per un proxy vedono il certificato del proxy, non questo.
Scarica il certificato nella pagina Rete salva il certificato che il pannello serve, senza la sua chiave, come <nome>.crt. Aggiungilo ai certificati attendibili di un dispositivo e i browser di quel dispositivo si fidano del pannello; le viste delle estensioni dell’editor ne hanno bisogno (Estensioni). Di un nuovo certificato autofirmato bisogna fidarsi di nuovo.
Proxy attendibili
Un elenco di indirizzi IP o intervalli CIDR, come 192.168.1.5, l’indirizzo del proxy davanti al NAS. Solo per una richiesta la cui connessione TCP arriva da uno di essi nginx prende:
- l’indirizzo del client da
X-Forwarded-For; - lo schema usato dal client da
X-Forwarded-Proto(contano solohttpohttps).
Una richiesta da qualsiasi altro indirizzo conta come proveniente direttamente dal suo client, e nginx sostituisce le sue intestazioni X-Forwarded-* con i propri valori. Un intervallo rende attendibile ogni host che contiene: ognuno di essi può allora impostare l’indirizzo del client e lo schema, quindi indica l’indirizzo proprio del proxy. Un intervallo di tutti gli indirizzi (0.0.0.0/0, ::/0) è rifiutato.
URL pubblico
Solo l’indirizzo, come https://git.example.com, senza percorso. Le sezioni dei moduli dicono quali collegamenti iniziano con esso.
Dietro un reverse proxy (Plesk)
La configurazione abituale mette TLS su un proxy con un certificato pubblico e lo lascia parlare HTTP semplice alla porta 9950 sulla LAN. Gli esempi qui sotto usano bvs.example.com per il nome pubblico, 192.168.1.20 per il NAS e 192.168.1.5 per il server Plesk; metti i tuoi al loro posto.
Sul NAS
- Nella pagina Rete, aggiungi l’indirizzo del server Plesk (come lo vede il NAS) ai proxy attendibili.
- HTTP semplice può restare su “Servi”. Anche “Reindirizza a HTTPS” funziona, una volta che il server Plesk è un proxy attendibile.
In Plesk
Metti queste direttive nelle impostazioni di Apache e nginx del dominio, nel campo “Direttive nginx aggiuntive” (nell’interfaccia inglese “Additional nginx directives”):
location ~ ^/ {
proxy_pass http://192.168.1.20:9950;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket: l'editor e il suo terminale
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
# push e caricamenti grandi: nessun limite di dimensione, in streaming, un'ora di silenzio consentita
client_max_body_size 0;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
location ~ ^/ è una location con espressione regolare. nginx preferisce un’espressione regolare che corrisponde a un semplice location / (Plesk ne scrive una propria), quindi questo blocco serve ogni percorso del sito, e proxy_pass senza percorso passa il percorso della richiesta senza cambiarlo. Nella stessa pagina delle impostazioni, disattiva “Servi i file statici direttamente tramite nginx”: se è attivo, Plesk risponde alle richieste di file .js, .css e immagini dalla cartella del dominio, e il pannello non si carica.
Nelle impostazioni di hosting del dominio, attiva il reindirizzamento permanente 301 da HTTP a HTTPS adatto alla SEO (nell’interfaccia inglese “Permanent SEO-safe 301 redirect from HTTP to HTTPS”). Le direttive nginx aggiuntive valgono anche per il sito del dominio su HTTP semplice alla porta 80; senza il reindirizzamento, il sito risponde anche lì, e le password attraversano internet senza cifratura.
Perché ogni riga conta:
| Direttiva | Che cosa non funziona senza |
|---|---|
Host $http_host | nginx sul NAS sceglie il blocco server in base a Host, quindi un nome host di modulo non corrisponde mai. bvsd confronta l’Origin della pagina con Host, porta compresa, quindi ogni modifica nel pannello fallisce con 403 csrf; $host perderebbe una porta pubblica diversa da 443 e fallirebbe allo stesso modo. |
X-Forwarded-For | ogni client conta come il server Plesk: cinque password sbagliate di una sola persona bloccano tutti per 15 minuti |
X-Forwarded-Proto $scheme | il cookie di sessione non è marcato Secure, e in modalità “Reindirizza a HTTPS” ogni richiesta viene mandata alla porta 9951 del nome pubblico |
Upgrade, Connection | la pagina dell’editor si apre ma l’editor e il suo terminale non si collegano mai |
client_max_body_size 0, proxy_request_buffering off, i timeout | ai push e caricamenti grandi si applicano il limite di dimensione e i timeout propri del proxy |
X-Forwarded-For e X-Forwarded-Proto contano solo quando il server Plesk è tra i proxy attendibili. Quando non c’è, nginx sul NAS li ignora.
Git via SSH
Un proxy HTTP non trasporta SSH. Git via SSH va direttamente alla porta 9952 del NAS, o tramite un inoltro di porta TCP sul router. “Porta SSH negli URL di clonazione” nella pagina Rete imposta la porta che mostrano gli indirizzi di clonazione, e “Host SSH negli URL di clonazione” il nome o l’indirizzo, quando il nome pubblico raggiunge solo il proxy.
Verificare la configurazione
- Il pannello si apre su
https://bvs.example.com/, e l’accesso e il salvataggio di un’impostazione funzionano. - Gli strumenti per sviluppatori del browser mostrano il cookie di sessione
bvs_sessioncon l’attributoSecure. - La pagina Log mostra
nginx-access: il primo campo di ogni riga è l’indirizzo proprio del client, non quello del server Plesk.
Nomi host dei moduli
Un modulo può avere un proprio nome host (pagina Rete, Nomi host). nginx serve allora quel modulo da solo alla radice del nome. Il nome deve puntare al NAS, o al proxy davanti a esso. Su un proxy, ogni nome host ha bisogno di un proprio sito, con le stesse direttive viste sopra.
| Modulo | Alla radice del suo nome host | Presente anche lì |
|---|---|---|
| Git | Forgejo | /git/ su ogni altro nome risponde 302 verso il nome host Git, con lo stesso percorso, la stessa query e la stessa porta |
| Editor | code-server | la pagina di accesso del pannello e /api/, così un utente può accedere su quel nome |
| SVN e Bucket | httpd | i repository restano su /svn/<nome> e i bucket su /bucket/<nome> |
Un modulo disattivato risponde 503 con una frase che lo dice, sui suoi percorsi e sul suo nome host.
Un solo accesso per tutti i nomi host
Il cookie di sessione appartiene al nome su cui è stato impostato, a meno che l’impostazione network.cookie_domain non indichi un dominio padre di tutti i nomi host dei moduli. Con example.com, un accesso su bvs.example.com raggiunge anche git.example.com e ide.example.com. bvsd rifiuta un suffisso pubblico (com, com.pl, co.uk, myqnapcloud.com), un dominio che non è padre di tutti i nomi host dei moduli, e qualsiasi dominio finché non è impostato alcun nome host di modulo. Ogni sito sotto quel dominio riceve il cookie, quindi imposta il padre comune più ristretto.
La pagina Rete non mostra questa impostazione. L’admin del NAS la imposta tramite il socket CLI con il curl del pacchetto:
/usr/bin/bucketvs/bin/curl --unix-socket /usr/bin/bucketvs/var/run/bvsd-cli.sock \
-X PUT -H 'Content-Type: application/json' \
-d '{"network":{"cookie_domain":"example.com"}}' \
http://bvsd/api/v1/settings
Un valore vuoto ("") tiene di nuovo il cookie su ciascun nome.
Pubblicare su internet (Cloudflare Tunnel)
La pagina Pubblicazione (Amministrazione, solo admin) mette il pacchetto su internet con nomi di un dominio il cui DNS è su Cloudflare. cloudflared, fornito dal pacchetto, apre la connessione dal NAS verso Cloudflare: non si apre alcuna porta del router, e Cloudflare tiene i certificati dei nomi. Ogni richiesta passa per il nginx del pacchetto: il pannello e la sua API richiedono l’accesso, e senza account si apre solo ciò che hai reso pubblico (repository pubblici, la loro vista web, il repository dei pacchetti).
Ci sono due tipi di nome, al massimo uno per tipo:
| Tipo | Esempio | Che cosa serve |
|---|---|---|
| Nome host principale | code.example.com | il pannello e la sua API, Forgejo su /git/, la vista web su /svn-web/ e /bucket-web/, il repository dei pacchetti su /repo/ (in sola lettura) e la guida. /svn/ e /bucket/ lì rispondono 404, e anche /ide/ finché non pubblichi l’editor (sotto) |
| Nome host dei pacchetti | qpkg.example.com | solo GET e HEAD di /repo/, per App Center su altri NAS; tutto il resto risponde 404 |
Che cosa serve al token
Crea un token API su dash.cloudflare.com (My Profile, API Tokens) con questi permessi, per la zona dei nomi:
- Account, Cloudflare Tunnel, Edit
- Zone, DNS, Edit
- Zone, Cache Rules, Edit
- Zone, Cache Purge, Purge
Il pacchetto conserva il token sul NAS in un file che solo root legge, e non lo mostra mai più.
Se il token ha Client IP Address Filtering, inseriscici entrambi gli indirizzi pubblici del NAS, IPv4 e IPv6: il NAS contatta Cloudflare via IPv6 quando ha un indirizzo IPv6. Altrimenti la pagina Pubblicazione rifiuta con token_ip_filter e indica l’indirizzo che Cloudflare ha visto.
Pubblicare
Inserisci i nomi e il token, poi Pubblica. Il pacchetto prima verifica tutto su Cloudflare e non cambia nulla lì quando una verifica fallisce; il messaggio dice che cosa correggere:
- un permesso che manca al token, con il suo nome;
- un nome in una zona che il token non vede;
- un record DNS che il nome ha già (il suo tipo e dove punta): eliminalo su Cloudflare o scegli un altro nome;
- un nome host principale mentre Navigazione pubblica (pagina Git) è disattivata, perché i suoi visitatori non hanno un account;
- nomi in zone di due account Cloudflare.
Poi crea il tunnel (chiamato bucketvs-<nome del NAS> a meno che tu non dia un nome; un tunnel con quel nome già presente su Cloudflare viene ripreso), fa puntare ogni nome al tunnel con un record CNAME proxato, aggiunge le regole di cache e avvia cloudflared. Pubblica di nuovo con gli stessi valori non cambia nulla. Imposta l’URL pubblico (Rete) sull’indirizzo https:// del nome host principale, così i collegamenti e gli indirizzi di clonazione HTTPS di Forgejo lo nominano; la pagina te lo ricorda finché sono diversi.
Git via SSH non passa per il tunnel: verso un nome pubblicato Cloudflare trasporta solo HTTP. L’indirizzo di clonazione SSH è quindi l’indirizzo LAN del NAS con la sua porta Git via SSH (9952), nel pannello e nel riquadro di clonazione di Forgejo, e la pagina Git e la Panoramica dicono “La clonazione via SSH funziona nella rete locale; da internet clona via HTTPS.” Per SSH da internet, inoltra la porta SSH sul router e imposta Host SSH negli URL di clonazione (Rete) sull’indirizzo pubblico del router o su un nome solo DNS che punta a esso, con Porta SSH negli URL di clonazione quando il router usa un’altra porta.
Il nome host principale risponde 404 a /ide/ finché un admin non accende Pubblica l’editor sul nome host principale nella pagina Pubblicazione. Il terminale dell’editor è una shell root sul NAS, e chiunque vi acceda da internet come developer o admin la ottiene: attiva quindi prima l’autenticazione a due fattori per quegli account. Con l’interruttore acceso l’editor passa per lo stesso accesso della LAN, il suo proxy delle porte (/ide/proxy/<port>/) lì resta spento e Cloudflare non tiene mai le sue pagine in cache. Finché è acceso, la Panoramica mostra Editor su internet.
Finché il modulo CI è attivo, un workflow inviato con push a qualsiasi repository di questo Forgejo viene eseguito come root sul NAS tramite il runner del NAS stesso, sia che sia stato inviato da Internet sia dalla LAN: lo stesso potere del terminale dell’editor. La pagina Pubblicazione lo dice sotto Cosa raggiunge internet. Concedi l’accesso in push solo a chi daresti la password di amministratore del NAS.
La cache
Con Preimpostazioni di cache attive, Cloudflare tiene i pacchetti (*.qpkg) per un anno, le icone per un giorno, repo.xml per 5 minuti e i file del pannello per un anno; non tiene mai l’API, le pagine di Forgejo, le pagine di accesso né la vista web. Una pubblicazione nel repository dei pacchetti toglie subito repo.xml (e un’icona cambiata o i file di una versione eliminata) dalla cache di Cloudflare. Il pacchetto aggiunge le proprie regole in fondo alle regole di cache della zona e non cambia mai le altre.
Accesso da internet
La prima password non può mai essere impostata tramite un nome pubblicato: la configurazione iniziale accetta solo un client locale. Le password errate contano per client internet, come sulla LAN. Conta anche una password inviata a Forgejo con git; un token di accesso di Forgejo funziona come sempre. Cloudflare accetta richieste fino a 100 MB, quindi un push o un caricamento più grande passa dall’indirizzo LAN.
Fermare e rimuovere
Ferma termina cloudflared; i nomi mostrano allora la pagina di errore di Cloudflare, e su Cloudflare non cambia nulla. Rimuovi da Cloudflare elimina i record DNS, le regole di cache e il tunnel creati dal pacchetto (un tunnel ripreso resta) e dimentica il token. Mentre ci sono nomi pubblicati, la Panoramica mostra un’etichetta Internet con lo stato del tunnel.
Moduli
La Panoramica mostra ogni modulo con i suoi processi, la memoria e la CPU, e lo attiva e disattiva (solo admin). Un modulo disattivato dice che cosa offre; un admin lo attiva con il suo pulsante (Attiva Git, Attiva Editor e così via) sul suo riquadro, sulla sua pagina o, per l’Editor, nella scheda Editor.
- Attivare un modulo esegue un job: il modulo si prepara, l’interruttore viene salvato, e i suoi processi si avviano. Il job li attende fino a 30 secondi.
- CI ha bisogno di Git: Git non può essere disattivato mentre CI è attivo. Mentre Git è disattivato, il pulsante di CI dice Attiva Git e CI e attiva prima Git.
- Un modulo disattivato non esegue alcun processo e non usa memoria.
- Il nucleo è sempre attivo.
| Stato | Significato |
|---|---|
| in esecuzione | ogni processo del modulo è in esecuzione |
| in avvio | un processo è partito meno di un secondo fa |
| degradato | un processo attende di essere riavviato, i file del modulo non si sono potuti scrivere, o il suo controllo di salute fallisce |
| si riavvia in un ciclo continuo | un processo è uscito 5 volte in 10 minuti; bvsd lo riavvia ogni 15 minuti, ed è partita una notifica |
| fermo | i processi del modulo non sono in esecuzione (uno spostamento dei dati li ha fermati, o non sono riusciti ad avviarsi) |
| disattivato | il modulo è disattivato |
Un processo che esce viene riavviato dopo 1 secondo, poi 2, 4 e così via fino a 60 secondi. Dopo 10 minuti di esecuzione l’attesa riparte da 1 secondo. Un processo che si riavvia in un ciclo continuo riparte subito quando il suo modulo viene disattivato e riattivato.
Git
Il modulo Git esegue Forgejo, un’interfaccia web per repository git con issue, pull request, release, wiki, LFS, mirror e webhook. Un admin lo attiva con Attiva Git nella Panoramica o nella pagina Git. Il job prepara le cartelle e il database di Forgejo in <dati>/forgejo, aggiunge ogni account del pannello a Forgejo, e lo avvia. Forgejo si apre poi su /git/ all’indirizzo del pannello, o su / del nome host Git quando è impostato (vedi Nomi host dei moduli).
Nuovo repository nella pagina Git, e nel riquadro Git della Panoramica finché non ce n’è nessuno, apre il modulo di Forgejo per un repository. Il pannello lo offre, insieme a Migra o fai il mirror di un repository, dal ruolo developer in su: Forgejo non lascia creare repository a un viewer o a un member.
Repository e account
- Un solo accesso. Forgejo non ha un accesso proprio:
/git/user/loginporta all’accesso del pannello, con il codice di autenticazione quando l’account ne ha uno, e poi di nuovo a Forgejo. - Gli account vengono dal pannello. Ogni account del pannello ha un account Forgejo con lo stesso nome e la stessa password. Il ruolo
adminè amministratore del sito in Forgejo. Un account disattivato, o uno che deve prima cambiare la password, non può accedere neanche a Forgejo. Una modifica nel pannello raggiunge Forgejo in pochi secondi. Le pagine Utenti e Git mostrano lo stato di ogni account in Forgejo, e Sincronizza ora tutti gli account nella pagina Git esegue di nuovo la sincronizzazione. - Eliminare un account nel pannello ritira il suo account Forgejo: non può più accedere, e i suoi token e le sue chiavi SSH vengono rimossi, ma i suoi repository restano. Il nome non può essere dato a un nuovo account del pannello finché un admin non rinomina o elimina il vecchio account Forgejo nell’amministrazione del sito di Forgejo (Account utente).
- Un account creato in Forgejo stesso non viene mai modificato dal pannello. Un account del pannello con lo stesso nome mostra il motivo e attende finché uno dei due non viene rinominato.
- Autenticazione a due fattori e git. Forgejo non accetta password per un account con l’autenticazione a due fattori attiva. git via HTTP o HTTPS richiede allora un token di accesso di Forgejo (in Forgejo, Impostazioni, Applicazioni) al posto della password. Le chiavi SSH funzionano come prima.
- I repository si creano, si importano e si mettono in mirror nelle pagine di Forgejo. Le importazioni da indirizzi sulla LAN sono consentite per impostazione predefinita (impostazione:
git.allow_local_networks), perché un NAS di solito fa mirror dalla propria rete.
Clonare via HTTPS e SSH
Nella pagina Git, Clona un repository scrive entrambi i comandi per un proprietario e un repository:
| Via | Indirizzo | Accesso |
|---|---|---|
| HTTPS (o HTTP) | https://<indirizzo del NAS>:9951/git/<proprietario>/<repo>.git | nome utente e password del pannello, o un token di accesso |
| SSH | ssh://git@<indirizzo del NAS>:9952/<proprietario>/<repo>.git | una chiave SSH aggiunta in Forgejo in Impostazioni, Chiavi SSH / GPG |
- Con un URL pubblico (dietro un proxy, URL pubblico) l’indirizzo HTTPS lo usa; con un nome host Git il percorso è
/<proprietario>/<repo>.gitsu quel nome. - La porta SSH è
network.ssh_port(9952), onetwork.public_ssh_portquando un router vi inoltra un’altra porta. Il proxy non trasporta SSH: inoltra la porta sul router (vedi Git via SSH). - Un nome pubblicato tramite il Cloudflare Tunnel non trasporta SSH, quindi l’indirizzo di clonazione SSH indica allora l’indirizzo LAN del NAS, a meno che
network.public_ssh_host(Rete, «Host SSH negli URL di clonazione») non indichi un nome solo DNS o l’indirizzo del router. - I push grandi non vengono tagliati: nginx non imposta alcun limite alla dimensione del corpo su
/git/.
Mostrare repository a persone senza account
Navigazione pubblica nella pagina Git permette a chiunque raggiunga Forgejo di leggerne i repository pubblici senza account. In Forgejo ogni repository è pubblico o privato (le sue Impostazioni, Visibilità). Con l’interruttore attivo, un visitatore senza account può:
- aprire un repository pubblico, le sue cartelle e i suoi file, e scaricare un file così com’è;
- leggere la cronologia, aprire un commit con il suo diff (anche come file
.diffo.patch) e confrontare due commit; - vedere le sue release, scaricare un archivio, e clonarlo via HTTP (
git clone https://<indirizzo del NAS>:9951/git/<proprietario>/<repo>.git); - trovare i repository pubblici in Esplora e nel profilo del loro proprietario.
Un repository privato resta nascosto: il suo indirizzo risponde “non trovato”. Mentre l’interruttore è attivo, Forgejo inoltre non elenca alcun account (la scheda Utenti di Esplora e la ricerca utenti sono disattivate, anche per gli utenti connessi), così un visitatore non può raccogliere i nomi degli account. Push, issue, pull request e impostazioni richiedono comunque un account. Con l’interruttore disattivato, ogni pagina chiede prima al visitatore di accedere.
Per condividere un repository, rendilo pubblico in Forgejo, attiva Navigazione pubblica e invia l’indirizzo. Su un nome host Git l’indirizzo è https://<nome host Git>/<proprietario>/<repo>.
Nuovo progetto
Nuovo progetto è una pagina che porta un progetto, passo dopo passo, dal nulla a una prima versione compilata e pubblicata. Si apre in una scheda tutta sua dalla tavolozza dei comandi (Ctrl+Maiusc+P, Nuovo progetto), dalla cima della barra laterale dell’Editor, dall’intestazione della barra laterale Git, dalla pagina Git e dalla pagina Progetti; un esempio in Progetti Editor nella pagina Esempi ha Nuovo progetto da questo. Richiede il ruolo sviluppatore, i moduli Git ed Editor e il tuo account in Forgejo (la pagina Git ne mostra la sincronizzazione). Finché Git o l’Editor è disattivato, la pagina lo dice sopra i passi, e un admin li attiva lì con un solo pulsante.
- Modello. I modelli sono raggruppati: Programmi (C, C++ con CMake, Go, Rust, Node, Python, Java), Pacchetti per QTS (un pacchetto QPKG, un’app di App Builder, un pacchetto dai sorgenti), Kernel (un modulo del kernel, il driver USB-seriale ch341), Siti web (un sito statico: pagine in
src/, un Makefile che compilapublic/, un controllo dei link comemake test) ed Esempi. Ogni scheda dice cosa produce una compilazione e segna cosa manca ancora a questo NAS (QDK, un ambiente di compilazione, un modulo spento), con un link alla pagina che lo aggiunge. - Nome e visibilità. Il nome dà il nome al repository e alla cartella
projects/<nome>; la pagina lo controlla mentre scrivi. Poi il proprietario (il tuo account, o un’organizzazione in cui Forgejo ti lascia creare repository), privato o pubblico, e una descrizione se vuoi. Per un’app di App Builder, il preset da cui parte e la destinazione. - Servizio, per un pacchetto QPKG e un pacchetto dai sorgenti: come il pacchetto si avvia e si ferma, costruito a blocchi. Scegli un preset (Strumento da riga di comando collega il programma in
/usr/bin; Servizio in background aggiunge un account, una cartella dati sul volume, il programma avviato come quell'account, un'attesa della sua porta e un arresto con timeout; App web aggiunge il pulsante Apri di App Center; Vuota ha solo i verbi), poi cambia i suoi blocchi. La scheda di ogni blocco mostra le righe che scrive nello script mentre digiti, e un valore rifiutato è segnato sotto il suo campo. L'avvio non attiva mai l'Enable di App Center, e l'arresto non lo tocca mai. La vista Progetto cambia i blocchi in seguito. - Compilazione. L’ambiente in cui si compila il progetto, conservato per il progetto (la vista Progetto lo cambia in seguito), oppure nessuno, e bvsd ne sceglie uno a ogni compilazione. Il passo propone prima quello che bvsd sceglierebbe da sé, dove compilano
bvs qbuilde la CI: l’Ubuntu 24.04 builder, altrimenti il Debian 12 builder, altrimenti un altro ambiente Debian o Ubuntu. Quando il Makefile del modello dà a ogni app il suo ambiente in una riga ENV, il passo lo dice e non ne chiede nessuno, e il progetto non ne conserva nessuno. Per un pacchetto dai sorgenti il passo dice anche che l’indirizzo della sorgente e lo sha256 della ricetta iniziale sono provvisori: la prima compilazione fallisce finché la ricetta non indica la vera sorgente del programma e lo sha256 di quel file. La pagina mostra il workflow che la CI esegue a ogni push. Compila subito dopo la creazione resta attivo finché non lo spegni; per un pacchetto dai sorgenti parte spento, e puoi accenderlo. Se sul NAS non c’è un ambiente Debian o Ubuntu, il passo lo dice: un admin vi crea l’ambiente di compilazione con Crea questo ambiente, e poi il passo lo propone; altrimenti disattiva Compila subito dopo la creazione e compila il progetto più tardi. - Pubblicazione, per un pacchetto QPKG, un’app di App Builder o un sito web: Deploy di prova su questo NAS (admin, solo pacchetti firmati; per un’app, Attiva su questo NAS), Pubblica nel repository di App Center di questo NAS e Pubblica sul mio server web (admin) su una delle destinazioni web; Aggiungi una destinazione ne salva una nuova. Ognuna è facoltativa. La scelta di pubblicazione diventa anche l’interruttore Pubblica nel repository di App Center del progetto (vista Progetto, Impostazioni): finché è acceso, la CI del progetto vi pubblica a ogni esecuzione.
- Revisione elenca ogni risposta e i passi che verranno eseguiti. Crea il progetto li invia.
- Avanzamento segue il job di ogni passo: il repository e il suo primo commit, la prima compilazione, poi il deploy di prova, la pubblicazione in App Center e quella sul web, uno dopo l’altro. Una riga mostra il suo stato e la fine del suo log; un clic mostra il log. Un passo fallito dice perché e offre Riprova, e i passi successivi aspettano. Alla fine, Apri il progetto, Apri nell’editor e Apri in Forgejo. Ricaricare la pagina o tornare alla sua scheda rilegge i job e non invia nessun passo due volte. Lasciare la pagina ferma la catena; la vista Progetto ha gli stessi passi.
Quando bvsd rifiuta il progetto (un nome preso da una cartella, un’app o un repository, un proprietario in cui non puoi creare), la pagina torna al passo con quella risposta, mostra il motivo sotto il suo campo e conserva tutte le altre risposte. Un modulo spento (un admin lo accende dalla pagina), nessun account Forgejo e nessun ambiente Debian o Ubuntu per un’app di App Builder sono spiegati in Revisione.
Cosa fa il primo job:
- Crea il repository a tuo nome, privato a meno che tu non abbia scelto pubblico.
- Crea la cartella
projects/<nome>della cartella dei dati con il primo commit: ogni file del modello e il workflow.forgejo/workflows/build.yml, sumain. Il commit è tuo (nome e indirizzo sono impostati come autore nella cartella), e gli script del modello vi sono eseguibili. Invia questo commit al repository a tuo nome.originè l’indirizzo HTTPS del repository, quindi il tuo prossimo push va lì. Il commit contiene anche la skill per gli assistenti IA,.claude/skills/qnap-dev/eAGENTS.md. La cartella è nella cartella condivisa dell’editor: l’editor di ogni sviluppatore apreprojects/, che il repository sia privato o pubblico. - Conserva per il progetto l’ambiente scelto, a meno che il Makefile del modello dia a ogni app il suo ambiente. Per un’app di App Builder, crea l’app con il nome del progetto e le ricette del preset e la lega al progetto, così l’app può compilare anche le ricette che aggiungi alla cartella
recipes/del progetto. Conserva anche la tua scelta di pubblicazione come interruttore Pubblica nel repository di App Center del progetto, prima che la prima esecuzione del workflow lo legga.
Il workflow gira sul runner del NAS a ogni push una volta acceso il modulo CI, nell’ambiente che il workflow nomina. Il workflow QPKG pubblica il pacchetto nel repository dei pacchetti, che accetta solo pacchetti firmati. Se il primo commit o il suo push fallisce dopo la creazione del repository, il job rimuove la cartella, elimina di nuovo il repository e dice perché. Finché l’interruttore Pubblica nel repository di App Center del progetto è spento, bvs repo publish nel workflow stampa un avviso invece di pubblicare, e l’esecuzione prosegue.
La vista Progetto
Ogni cartella di projects/ nella cartella dei dati ha una sua pagina: un progetto della procedura guidata, la copia di un esempio da Progetti Editor o un repository che vi hai clonato. Si apre dal ramo Progetti della barra laterale dell’Editor, dalla pagina Progetti, con Apri il progetto alla fine di Nuovo progetto e dalla tavolozza dei comandi (Apri il progetto …, o Ctrl+P e il suo nome). Richiede il ruolo sviluppatore. Il menu di un progetto nella pagina Progetti ha anche Compila, Ricompila, Pubblica e la pubblicazione sulle destinazioni web. Lo stesso menu accende o spegne la pubblicazione della CI in App Center.
La pagina legge la cartella e da sola non vi cambia nulla. Ricava il tipo del progetto dai suoi file: un’app di App Builder con il nome della cartella, un qpkg.cfg in cima (un pacchetto QPKG), un Makefile in cima, o nessuno di questi, quando lo compila il workflow CI del progetto. Quando un’app di App Builder ha il nome della cartella, un progetto con un qpkg.cfg in cima, o con un Makefile e un qpkg.cfg in qpkg/, mantiene la propria compilazione, e Deploy di prova e Pubblica prendono ancora il suo QPKG.
La striscia in alto contiene i passi. Un passo che non può partire tiene il suo pulsante, disattivato, e dice perché accanto e sotto la striscia. Un passo che il progetto non può proprio fare esce dalla striscia, e una frase sotto dice che cosa crea il progetto e dove va il risultato della compilazione: la cartella del progetto per un programma, la pagina Kernel per un modulo del kernel, la pagina di ogni app per un Makefile che compila solo app di App Builder.
- Compila gira come job nel pannello inferiore. Un pacchetto QPKG si compila con
qbuilddi QDK, un progetto con Makefile conmake, entrambi nell’ambiente di compilazione del progetto. Il log nomina ogni.qpkgche la compilazione ha scritto inbuild/e se porta una firma del codice. Un’app di App Builder si compila come nella sua pagina. Quando il target predefinito di un Makefile esegue solo righe./bvsapp.sh createe./bvsapp.sh build, Compila fa lo stesso tramite App Builder: crea ogni app di una rigacreateche ancora non c’è, poi compila le app una dopo l’altra. Una rigacreateè./bvsapp.sh create NOME FILE-DELLE-RICETTE [ENV] [LINK] [TARGET] [OTHERS]. Un tale Makefile nomina il target predefinito e i suoi prerequisiti in.PHONYe contiene solo assegnazioni semplici, ogni variabile impostata una volta, e regole semplici; uno con altro (una condizione, un include) si compila con make. TARGET ènative,aarch64oarmv7, quindi una sola compilazione può fare un’app per questo NAS e una per ARM a 64 bit. OTHERS dice cosa fa un’app statica con le ricette che non si possono collegare in statico (refuseobundle). Un’app creata così prende anche le ricette proprie del progetto darecipes/, a meno che il nome della cartella non sia un nome di progetto (per esempio un nome con uno spazio). Quando un’app con quel nome c’è già con un altro target, o con un altro progetto mentre la cartella ha ricette proprie, Compila resta disattivato e dice come rimediare. Prima della prima compilazione il passo indica le app che compila. Un progetto con Makefile e il pacchetto inqpkg/crea il file di pacchetto conmake qpkgnel terminale dell’editor; finché manca, Deploy di prova, Pubblica e Pubblica sul web dicono «Richiede un file di pacchetto». - Ricompila compila da zero:
make clean, poimake; per un pacchetto QPKG prima se ne vanno i vecchi.qpkgdibuild/. Un Makefile senza targetcleannon può ricompilare, e la pagina lo dice. Un’app di App Builder non ha Ricompila, e nemmeno un Makefile che crea e compila solo app di App Builder. - Esporta come QPKG (admin) c’è per un’app di App Builder, come nella pagina dell’app. Pubblica aspetta allora un’esportazione, come nella pagina dell’app, e Apri l’app nell’intestazione apre quella pagina.
- Deploy di prova è per gli admin. Installa il
.qpkgpiù recente su questo NAS conqpkg_cli, come App Center installa un file, e il job aspetta la conferma di App Center. Il pacchetto resta installato finché non lo rimuovi in App Center. Un pacchetto senza firma del codice viene rifiutato: il deploy di prova installa solo pacchetti firmati e non salta mai il controllo della firma di App Center (in App Center stesso il proprietario di un NAS può consentire app senza firma; questa pagina no). Firmalo con un certificato in file (caso 1 in Firmare il codice di un QPKG). Il pacchetto di Bucket & Code Server IDE stesso viene rifiutato, perché installarlo sostituirebbe il pacchetto in esecuzione. Per un’app di App Builder, il deploy di prova attiva la sua compilazione su questo NAS. - Pubblica mette il
.qpkgpiù recente nel repository dei pacchetti, con le sue regole: la pubblicazione di un admin diventa la versione in elenco, quella di uno sviluppatore aspetta un admin, e un pacchetto senza firma viene rifiutato a meno che il repository non accetti pacchetti non firmati. Una riga sotto dice se anche la CI del progetto pubblica nel repository di App Center; questo pulsante pubblica in ogni caso. - Pubblica sul web (admin) copia il
.qpkgpiù recente, o la cartella del sitopublic/(altrimentidist/), in una destinazione web e lo rilegge dall’indirizzo pubblico della destinazione. Per un sito web creato dalla procedura guidata, il passo aspetta la prima compilazione, che scrivepublic/.
Un progetto con Makefile sceglie un target accanto a Compila (il target predefinito di make, il primo, a meno che tu non ne scelga un altro); un progetto CMake si compila, o si compila ed esegue i suoi test. Un progetto di modulo del kernel si compila nell’area di lavoro dell’officina del kernel per il kernel in esecuzione, e quella compilazione spetta a un admin. Un passo in esecuzione ha Annulla, e il job di solito finisce subito. Esegui il workflow esegue a mano il workflow CI del progetto quando ha un trigger workflow_dispatch; altrimenti il pulsante è spento e la pagina dice perché. Il workflow di ogni modello ha quel trigger. Installato su questo NAS elenca i pacchetti installati dai deploy di prova del progetto, con Rimuovi da questo NAS per un admin. Elimina il progetto, nel menu accanto ai pulsanti dell’intestazione o nel menu del progetto nella pagina Progetti, è per un admin o per lo sviluppatore il cui account Forgejo contiene il repository. Prima digiti il nome del progetto; la cartella se ne va, e il repository Forgejo, un’app di App Builder con quel nome e i pacchetti installati restano. La pagina poi dà il link al repository.
Impostazioni contiene ciò che bvsd conserva per il progetto fuori dalla sua cartella. Per un progetto Makefile, CMake o QPKG mostra l’ambiente in cui girano Compila e Ricompila, e lo cambia. Per un Makefile che crea e compila solo app di App Builder, elenca ogni app con l’ambiente che la sua riga nel Makefile indica. Un progetto che crea un pacchetto, o il cui workflow esegue bvs repo publish, vi ha l’interruttore Pubblica nel repository di App Center: acceso, bvs repo publish nella CI del progetto aggiunge i suoi pacchetti al repository; spento, l’esecuzione CI salta quel passo con un avviso. Un progetto senza una scelta conservata (la copia di un esempio, un clone) lo ha acceso. Git mostra il ramo, quanto è avanti o indietro rispetto al remoto come l’ha lasciato l’ultimo fetch (la pagina non fa mai fetch), l’ultimo commit e i percorsi modificati. File elenca una cartella alla volta; scegli un file per leggerlo, un .qpkg si scarica. Le modifiche restano nell’editor, e la cartella .git è esclusa.
Ricette, per un progetto con una propria cartella recipes/, elenca le ricette che prendono le sue app: ognuna con la sua versione, la versione della libreria che sostituisce quando ha il nome di una ricetta della libreria, e sotto ciò che il controllo delle ricette ha trovato, con file e riga. Una ricetta che bvsd esclude ha una riga con il motivo; oltre tre escluse nello stesso modo, una riga conta le altre. Ciò che il controllo ha trovato sulla cartella recipes nel suo insieme ha una riga propria. Un clic apre la cartella della ricetta nell’editor; il menu copia anche il comando che esegue lo stesso controllo in un terminale del NAS: bvs recipe lint con la cartella del progetto. La scheda compare anche quando recipes del progetto è un link, un file, una cartella che bvsd non può leggere o una cartella con soli link, e dice perché non ne viene letta nessuna ricetta.
Servizio e pacchetto (un pacchetto QPKG, o un progetto Makefile con il pacchetto in qpkg/, come un pacchetto dai sorgenti) contiene lo script di avvio e arresto del pacchetto come blocchi, i campi del suo qpkg.cfg (Pacchetto) e i file scritti da essi (Script). Salva mostra le differenze di ogni file, poi ne esegue il commit nel repository del progetto; se nel frattempo il progetto è cambiato, pianifica di nuovo. Modifica a mano disattiva i blocchi, così modifichi lo script nell'editor; Ricollega i blocchi mostra cosa sostituirebbe una nuova scrittura. Aggiorna la libreria porta nel pacchetto il bvs-qpkg.sh di questo Bucket & Code Server IDE, con le sue differenze. Un progetto creato prima dei blocchi offre Usa i blocchi per questo script.
Versioni elenca le versioni a cui il progetto può passare, e Passa a questa versione lo fa:
| Versione | Cosa fa il passaggio |
|---|---|
Un .qpkg in build/, o un’esportazione di App Builder | un deploy di prova di quel file (admin) |
| La compilazione di App Builder | la attiva (admin); App Builder ne conserva una |
| Una versione nel repository dei pacchetti | la rende la versione in elenco (admin) |
| Un tag git | fa il checkout del tag nella cartella |
Un clic sceglie una versione; il suo menu fa anche il deploy di prova, la pubblica, la pubblica su una destinazione web o scarica un .qpkg. Un tag viene preso come HEAD staccato, e Torna a main nella scheda Git torna al ramo. Il passaggio viene rifiutato finché la cartella ha modifiche non committate; il messaggio le elenca, e tu prima le committi o le metti da parte nell’editor. Spunta due versioni e Confronta le due elenca i file che una ha e l’altra no, e i file cambiati. Due tag, o due pacchetti, si confrontano per contenuto; un pacchetto con un commit solo per dimensione. Nella pagina Pacchetti un admin installa anche una versione del repository su questo NAS (Installa su questo NAS), con i controlli del deploy di prova.
Il tuo server web (destinazioni web)
Una destinazione web è dove un admin pubblica un pacchetto o un sito web sul proprio server web: una cartella di questo NAS (la condivisione Web di QTS, servita dal Web Server di QTS, o un’altra cartella condivisa) o un remote rclone (SFTP, FTP, WebDAV, S3, configurato nel rclone.conf dei backup), con l’indirizzo pubblico che la serve. Sono nella pagina Pubblicazione, sotto Destinazioni web: Aggiungi una destinazione, Cambia, Rimuovi e Prova, che vi copia un piccolo file, lo recupera dall’indirizzo pubblico e lo elimina di nuovo.
Una destinazione cartella è una cartella a sé dentro una condivisione (/share/Web/miosito, mai un’intera condivisione né un volume), fuori dalla cartella dei dati, perché la pubblicazione di un sito toglie dalla destinazione ciò che il sito non contiene più. L’indirizzo inizia con http:// o https:// e non contiene utente né password.
Ogni pubblicazione rilegge il file dall’indirizzo pubblico: il .qpkg di un pacchetto con il suo .sha256, confrontato per sha256, o l’index.html di un sito, confrontato byte per byte. Quando l’indirizzo non serve ciò che è stato copiato, il job fallisce con web_check: ed entrambi i valori.
Runner CI
Il modulo CI esegue Forgejo Actions: un file di workflow in .forgejo/workflows/ di un repository gira su un runner quando viene fatto un push. Richiede il modulo Git. Un admin lo attiva in Moduli, CI, Attiva. Il job registra il runner proprio del NAS presso Forgejo, riavvia Forgejo con Actions attivo, e avvia il runner; termina quando il runner ha raggiunto Forgejo.
Il runner sul NAS
- Le sue etichette sono
bucketvs,qnap-x86_64(oqnap-aarch64) eself-hosted, più le etichette aggiuntive che un admin imposta nella pagina CI. Un job il cuiruns-onne nomina una gira qui, per esempioruns-on: bucketvs. - Esegue ogni job sul NAS stesso, come admin, non in un container. Un job ha gli strumenti del pacchetto (git, curl, make e gli altri), Node per le azioni JavaScript come
actions/checkout, ebvs env run <env> -- <command>per una build dentro un ambiente. Chi può fare push di un workflow in un repository può quindi eseguire comandi come admin sul NAS. Un member o un viewer non può creare, fare fork o importare repository, né creare organizzazioni, in Forgejo; developer e admin possono. Un viewer non fa mai push. Mentre la CI è attiva, il push di un member in un repository con le Actions attive viene rifiutato con il motivo, e così un push con una deploy key. Anche il push di un member, o con una deploy key, in un repository che un account con ruolo inferiore a developer possiede o amministra viene rifiutato, pure con la CI disattivata: un tale account potrebbe attivare da sé le Actions. bvsd disattiva le Actions entro un minuto in ogni repository che un member o un viewer possiede o in cui un tale account può scrivere, e prima dell’avvio del runner quando la CI viene attivata. - Ciò che resta è un atto proprio di un developer o di un admin: attivare le Actions, o avviare un workflow, in un repository in cui un member ha scritto prima, oppure dare a un tale account l’accesso admin a un repository in cui ha scritto prima. Un developer che unisce o compila i commit di un member li esegue anch’egli come admin.
- Job contemporanei è
ci.capacity(1 per impostazione predefinita). Un job che nessun runner online può prendere attende in Forgejo. - I repository creati prima che CI fosse attivo hanno le Actions di Forgejo disattivate, quindi un workflow inviato con push non avvia nulla: attivale nelle Impostazioni del repository, Unità (Actions). I repository creati mentre CI è attivo le hanno.
- Le azioni come
actions/checkout@v4vengono scaricate dahttps://data.forgejo.org, quindi il NAS ha bisogno di accesso a internet per i workflow che le usano. Il runner non ha cache:actions/cachenon trova nulla e il job prosegue. - Gli artefatti (
actions/upload-artifact) vengono caricati all’indirizzo proprio di Forgejo (quello della pagina Git), quindi il NAS deve raggiungere quell’indirizzo, e fidarsi del suo certificato quando è HTTPS. - Lo stato del runner è in
<dati>/runner; il suo log è runner in Log. Disattivare il modulo ferma il runner e disattiva Actions in Forgejo.
Runner esterni
Una macchina di build altrove (un server, una VM) può prendere job anche da questo Forgejo. Nella pagina CI, in Registra un runner esterno, un admin le dà un nome e ottiene i comandi per Linux x86_64 e aarch64. Questi scaricano forgejo-runner 13.2.0 da code.forgejo.org, ne verificano lo sha256, tengono il token del runner in runner-token (leggibile solo dal suo proprietario) e avviano il runner con l’etichetta linux-amd64 (o linux-arm64). Il runner compare subito nell’elenco, offline finché i comandi non vengono eseguiti. Il token è mostrato solo in quel momento. Un runner del genere esegue i suoi job sulla propria macchina, come l’utente che lo ha avviato, e raggiunge Forgejo al suo indirizzo pubblico.
SVN e Bucket
Il modulo SVN e Bucket serve i repository Subversion su /svn/<nome> e i bucket su /bucket/<nome>. Un bucket è un’unità di rete (WebDAV) in cui ogni file salvato diventa una revisione, così qualsiasi versione precedente di un file può essere letta o ripristinata. Un admin attiva il modulo in Moduli; la pagina SVN e Bucket crea, elenca ed elimina poi entrambi i tipi.
- Gli account sono quelli del pannello. I permessi si impostano per repository: lettura e scrittura, lettura, o nessuno, per ogni account, più un predefinito per ogni account non elencato. Gli admin leggono e scrivono sempre; member e developer scrivono dove hanno lettura e scrittura; i viewer al massimo leggono. Un nuovo repository non dà alcun accesso a nessuno tranne gli admin finché un admin non lo imposta (l’icona delle persone sulla sua riga, Permessi per
<name>). Sotto admin, la pagina mostra a ciascuno il proprio accesso a ogni repository e bucket. - Le password errate contano come all’accesso del pannello: 5 password errate entro 15 minuti bloccano quell’account da quell’indirizzo, e l’indirizzo stesso, per 15 minuti.
- Autenticazione a due fattori. Un account con l’autenticazione a due fattori non usa la sua password per SVN o WebDAV. Crea una password per app nella pagina del suo account (Password per app per WebDAV e SVN): 25 caratteri casuali, mostrati una sola volta. Una nuova sostituisce la vecchia; un cambio di password o la disattivazione dell’autenticazione a due fattori la rimuove.
- Eliminare un repository lo sposta in
<dati>/trash, dove il jobtrashlo rimuove dopo 7 giorni.
Repository SVN
svn checkout "https://<indirizzo del NAS>:9951/svn/<nome>"
svn commit -m "…"
La pagina mostra il comando di checkout con l’indirizzo del repository. Dietro un proxy l’indirizzo segue l’URL pubblico, e con un nome host SVN è /svn/<nome> su quel nome. La Cronologia di un repository elenca le sue revisioni; un file può essere letto a qualsiasi revisione, confrontato con un’altra, e ripristinato come nuova revisione (Ripristina questa versione, per gli account con lettura e scrittura).
Bucket
- Salvare è fare commit. Un client che salva un file crea una revisione con il nome dell’account e l’ora; la revisione è marcata come fatta tramite WebDAV. Molti client scrivono prima un file vuoto e poi i dati, quindi un salvataggio può creare due revisioni.
- File di macOS. Un bucket creato con Rifiuta i file ._\* e .DS_Store di macOS (il predefinito) non conserva i file
._*e.DS_Storeche il Finder scrive accanto a ciò che copia. Il client non riceve alcun errore, ma il file non diventa mai una revisione. Eliminare un file del genere è consentito. - Tornare indietro. La cronologia del bucket mostra le versioni di ogni file; Ripristina questa versione salva il vecchio contenuto come nuova revisione, così non si perde nulla.
Client WebDAV e i loro limiti
| Client | Come collegarsi | Note |
|---|---|---|
| Finder di macOS | Vai, Connessione al server, https://<indirizzo del NAS>:9951/bucket/<nome> | il Finder blocca un file mentre lo scrive; il bucket risponde ai lock WebDAV |
| rclone | un remote webdav con vendor = other e l’indirizzo del bucket | adatto a copie tramite script |
| davfs2 (Linux) | mount -t davfs https://<indirizzo del NAS>:9951/bucket/<nome> /mnt/<cartella> | il nome utente del pannello e la password o la password per app |
| Cyberduck, WinSCP | una connessione WebDAV (HTTPS) alla porta 9951, percorso /bucket/<nome> | |
| curl | curl -T file -u <utente> https://<indirizzo del NAS>:9951/bucket/<nome>/file | un caricamento, una revisione (o due, vedi sopra) |
| Esplora file di Windows | Connetti unità di rete | il WebClient di Windows invia una password solo via HTTPS con un certificato di cui Windows si fida: metti il bucket dietro un proxy con un certificato vero (Dietro un reverse proxy); il certificato autofirmato non basta |
- I file grandi non vengono tagliati: nginx non imposta alcun limite alla dimensione del corpo su
/bucket/e passa il caricamento man mano che arriva. - A un file che il bucket rifiuta di conservare (un file di macOS, vedi sopra) il server WebDAV risponde comunque
201, quindi un client non mostra alcun errore; il file non è nel bucket.
Mostrare un repository o un bucket a persone senza account
Un admin può rendere pubblico un repository SVN o un bucket con l’interruttore nella sua riga della pagina SVN e Bucket (Sul web). Chiunque abbia l’indirizzo può allora leggerlo in un browser, senza account:
| Indirizzo | Che cosa mostra |
|---|---|
https://<indirizzo del NAS>:9951/svn-web/<nome>/ | un repository SVN |
https://<indirizzo del NAS>:9951/bucket-web/<nome>/ | un bucket |
Il collegamento Vedi sul web della riga apre quella pagina. Elenca i file e le cartelle alla revisione più recente o a una più vecchia, mostra un file di testo con i numeri di riga (fino a 1 MiB) o un’immagine, e offre ogni file da scaricare. La Cronologia elenca le revisioni con i loro autori, messaggi e file modificati. La pagina di una revisione mostra il diff di ogni file che ha modificato (fino a 20 file di al massimo 1 MiB; gli altri sono collegamenti); qualsiasi file può essere confrontato tra due revisioni.
- Sola lettura. Le pagine non possono modificare nulla. I client WebDAV e
svnrichiedono comunque un account, anche per un repository pubblico. - Solo ciò che è pubblico. Un repository non pubblico e un nome che non esiste rispondono entrambi “There is no public repository at this address”, così le pagine non rivelano quali nomi esistono.
- Limiti. Un indirizzo può aprire 60 pagine in una volta e poi 2 al secondo, e scaricare 2 file alla volta; oltre, la pagina chiede di riprovare tra un momento. Un diff viene tagliato a 2 MiB.
- Ai motori di ricerca viene chiesto di non indicizzare le pagine. Le pagine sono in inglese. Hanno l’aspetto del pannello, scuro o chiaro a seconda di come è impostato il browser del visitatore.
- Dietro un proxy o con un nome host SVN, l’indirizzo segue quello del repository stesso (l’URL pubblico, o il nome host SVN con gli stessi percorsi).
Editor e strumenti IA
Il modulo Editor esegue VS Code nel browser (code-server) per ogni account developer e admin. Un admin lo attiva in Moduli. Ogni account riceve una propria istanza, avviata quando l’account apre l’editor e fermata dopo un periodo senza traffico.
Il terminale dell’editor è una shell root sul NAS. Su QTS i processi del pacchetto girano come admin (uid 0), tranne Forgejo e httpd. Dai il ruolo developer solo a chi daresti la password admin del NAS.
Aprire l’editor
- Apri l’editor nella pagina Impostazioni Editor (o
/ide/all’indirizzo del pannello, o il nome host dell’Editor) apre il workbench in una nuova scheda. La prima richiesta avvia l’istanza; quando non c’è una sessione, prima viene l’accesso del pannello. - Tramite il nome host principale pubblicato, finché l’editor non vi è pubblicato, la pagina Impostazioni Editor, la scheda Editor, la Panoramica e Apri una shell dicono che l’editor si apre solo dalla rete locale e danno il link al suo indirizzo LAN (
https://<indirizzo del NAS>:<porta HTTPS>/ide/); a un admin danno anche il link all’interruttore nella pagina Pubblicazione. - L’editor apre
<dati>/projects, dove gli esempi in Progetti Editor mettono i loro progetti. Le impostazioni, le estensioni e la cronologia del terminale dell’account sono tenute in<dati>/ide/<account>e la sua cartella home in<dati>/home/<account>. - Il terminale ha gli strumenti del pacchetto per primi nel
PATH: git, svn, node, npm, rsync, curl, bash e gli altri.bvs env shell <nome>entra in un ambiente di Toolchain eeval "$(bvs use <id>)"prepara una toolchain o un runtime. Apri una shell nella pagina Toolchain apre l’editor con un terminale già dentro quell’ambiente. - L’attività Editor, e la tavolozza dei comandi, aprono l’editor con una shell in un ambiente o con la cartella di un’app. L’editor appare dentro la scheda Editor del pannello; su un telefono si apre in una propria finestra del browser. Solo le pagine dell’indirizzo del pannello stesso possono mostrare l’editor al loro interno: il pacchetto lo dice ai browser in ogni risposta dell’editor, così un altro sito non può mettere il terminale root dell’editor sotto una pagina propria.
- Tempo di inattività (predefinito 30 minuti) ferma un’istanza senza traffico del browser, ma mai mentre un programma avviato dai suoi terminali, un agente IA avviato da un’estensione (il
claudedi Claude Code for VS Code, Codex, Gemini CLI) o qualcosa lasciato in esecuzione da lì è ancora in esecuzione. 0 disattiva l’arresto per inattività. Un account può fermare la propria istanza nella pagina Impostazioni Editor; un admin può fermarne qualsiasi. - Memoria e processi, nella pagina Impostazioni Editor, mostra cosa esegue un’istanza e quanta memoria occupa rispetto a quella del NAS, segna ciò che la tiene attiva, termina un processo con Termina e dice perché è arrivato l’ultimo arresto e cosa ha terminato. Anche un agente IA in attesa al prompt tiene attiva l’istanza: terminalo lì quando non serve più.
- La vista Ports di VS Code raggiunge un server di sviluppo sul NAS su
/ide/proxy/<port>/; le porte loopback proprie del pacchetto lì sono rifiutate. - New recipe, nel menu della cartella
recipesdi un progetto, o di una cartella di ricetta al suo interno, in Explorer, chiede un nome e vi scrive una nuova ricetta:recipe.jsonebuild.shdalla ricetta iniziale del pacchetto. Nella tavolozza dei comandi è Bucket: New recipe, che funziona mentre è aperto un file di un progetto con una cartellarecipes. A ogni salvataggio di un file di una ricetta, l’editor controlla le ricette del progetto conbvs recipe linted elenca i risultati nella vista Problems. Avvisa dello sha256 della ricetta iniziale finché non inserisci quello vero della tua sorgente.
L’editor risponde solo alle proprie pagine. Un WebSocket, un modulo o la richiesta di uno script che un’altra pagina invia con la sessione dell’account, da un altro sito o da un’altra porta del NAS, riceve 403 e non avvia alcuna istanza; così un’altra pagina non raggiunge nemmeno un server di sviluppo dietro la vista Ports.
Estensioni
- Le estensioni si installano nella vista Extensions dell’editor (Ctrl+Maiusc+X). Vengono da Open VSX: il browser cerca su open-vsx.org e mostra la pagina e l’icona di ogni estensione da openvsx.eclipsecontent.org, e il NAS scarica l’estensione stessa da open-vsx.org. Per questo sia il browser sia il NAS devono raggiungere internet.
- La prima estensione di ogni editore chiede «Do you trust the publisher …?». Trust Publisher & Install la installa; fino ad allora l’estensione mostra «Installing».
- Ogni account tiene le sue estensioni in
<dati>/ide/<account>/extensions, e un aggiornamento del pacchetto le conserva. - Il pacchetto porta un insieme di estensioni e formattatori, che l’editor installa per ogni account al suo primo avvio, e di nuovo dopo un aggiornamento del pacchetto che porta un nuovo insieme. Con esso l’editor evidenzia e formatta (Format Document nella tavolozza dei comandi) Markdown, script di shell, C, C++, Rust, Go, Pascal, Python, Perl, PHP, JSON, YAML, TOML, configurazione nginx, CSS, HTML, JavaScript e TypeScript. ShellCheck segnala i problemi negli script di shell, i file di unità systemd hanno evidenziazione e completamento, il
.editorconfigdi un progetto stabilisce il rientro, i codici colore come#ff8800orgb(0, 128, 0)appaiono nel loro colore in ogni file, e Hex Editor: Open Active File in Hex Editor nella tavolozza dei comandi mostra i byte di un file. - Rust viene formattato quando il runtime Rust è installato nella pagina Toolchain e l’editor dell’account è ripartito; fino ad allora Format Document in un file Rust segnala che la richiesta non è riuscita.
- Su un NAS ARM (il pacchetto aarch64) Pascal, Perl e PHP sono evidenziati ma non formattati: il pacchetto non ha per esso una build di Free Pascal, Perl o Mago.
- Un’estensione dell’insieme che l’account rimuove nella vista Extensions resta rimossa, anche dopo un aggiornamento del pacchetto, e una che aggiorna mantiene la versione più recente. Un formattatore predefinito scelto per un linguaggio (Format Document With…, poi Configure Default Formatter…) resta la scelta dell’account.
- Ogni file
.confsi apre come configurazione nginx. Il nome del linguaggio nella barra di stato passa un file a un altro linguaggio. - Ruff, che formatta Python, segnala una volta che non è installata un’estensione per gli ambienti Python. Formatta anche senza.
- Nel terminale dell’editor,
code-server --install-extension <editore.nome>installa anch’esso un’estensione da Open VSX. - Alcune estensioni disegnano viste proprie, come il pannello di Claude Code for VS Code, l’editor esadecimale e l’anteprima Markdown. Il browser mostra queste viste solo se si fida del certificato del pannello. Con il certificato autofirmato accettato solo tramite la pagina di avviso del browser restano vuote, e la scheda Editor e la pagina Impostazioni Editor lo dicono. Lo risolve una qualsiasi di queste strade:
- fidarsi del certificato del NAS sul dispositivo: Scarica il certificato nella pagina Rete o in quell’avviso, poi aggiungerlo ai certificati attendibili del sistema o del browser (Il certificato);
- un admin aggiunge un certificato per il nome del NAS nella pagina Rete;
- aprire l’editor tramite il nome host principale pubblicato, quando un admin ve lo pubblica.
- Claude Code for VS Code (editore Anthropic) si installa dalla vista Extensions, e il suo pannello chiede come accedere ad Anthropic. Claude Code: Open in Terminal nella palette dei comandi avvia Claude Code in un terminale, e questo funziona con qualsiasi certificato. Le funzioni di chat proprie di VS Code partono spente (
chat.disableAIFeatures); quell’impostazione non riguarda questa estensione.
Claude Code, Gemini CLI e Codex CLI
In Strumenti IA a riga di comando nella pagina Impostazioni Editor ogni account installa, aggiorna e rimuove questi strumenti per sé:
| Strumento | Installato con | Comando |
|---|---|---|
| Claude Code | l’installer di Anthropic (claude.ai/install.sh), npm se fallisce | claude |
| Gemini CLI | npm install -g @google/gemini-cli | gemini |
| Codex CLI | npm install -g @openai/codex | codex |
- Finiscono nella cartella home dell’account (
~/.local/bin,~/.npm-global/bin), che è nelPATHdel terminale; un altro account non li vede. - Ogni installazione è un job con il suo log nella pagina Job. L’accesso a ogni strumento (un account o una chiave API) avviene nello strumento stesso, nel terminale dell’editor.
Programmare con un assistente IA
Ogni progetto creato da Nuovo progetto contiene uno skill per gli assistenti IA: .claude/skills/qnap-dev/ e un AGENTS.md che vi rimanda. Lo skill, in inglese, raccoglie le linee guida per tutto ciò che riguarda un NAS QNAP: cos’è nella shell (una root su disco RAM, BusyBox, niente systemd, nessun gestore di pacchetti, getcfg e setcfg), archiviazione e percorsi, come compilare, firmare e pubblicare con questo pacchetto (bvs env run, bvs ldd, bvs qbuild, l’App Builder, l’officina del kernel, il repository dei pacchetti), porte, backup e cosa non deve suggerire, come apt sul NAS o consentire app non firmate in App Center. Dice chiaramente che la firma con un token hardware non è supportata né testata.
- Avvia l’assistente nella cartella del progetto (
cd <dati>/projects/<nome>), non inprojects/: ogni strumento cerca nella cartella in cui parte. - Claude Code carica la skill da
.claude/skills/quando un compito ne ha bisogno. Codex CLI leggeAGENTS.md. Gemini CLI leggeAGENTS.mduna volta che il.gemini/settings.jsondel progetto contiene{"context": {"fileName": ["AGENTS.md", "GEMINI.md"]}}. - Il pacchetto tiene la skill attuale in
/usr/bin/bucketvs/share/skills/qnap-dev. Un progetto creato prima che il pacchetto l’avesse, o un progetto copiato dalla galleria Esempi, la riceve copiando quella cartella in.claude/skills/del progetto. - La skill cita la knowledge base di QNAP Club Poland (forum.qnap.net.pl) per ciò che il NAS ha e ciò che gli manca.
- La build del pacchetto scrive lo skill anche come
qnap-skill-<versione>.zip, gli stessi file, da usare fuori dall’editor: estrailo in.claude/skills/di un progetto o in~/.claude/skills/. Il testo dello skill è sotto licenza CC BY 4.0 (il suoLICENSE): puoi condividerlo e adattarlo con la dicitura "QNAP guidelines skill by QNAP Club Poland / qnaputilities.com, CC BY 4.0".
Toolchain e ambienti
La pagina Toolchain scarica ciò che serve per compilare software sul NAS:
| Tipo | Che cos’è | Esempi |
|---|---|---|
| Filesystem radice | un sistema Linux da decomprimere in un ambiente | Debian 12 e 13, Ubuntu 22.04 e 24.04, Alpine 3.22 |
| Toolchain incrociata | un compilatore che compila per un altro processore | toolchain Bootlin per aarch64, x86-64 e armv7, con glibc o musl |
| Runtime | un linguaggio o uno strumento di build | Python, Go, Node.js, Zig, Rust, CMake, Ninja, Java (JDK) |
| QNAP | gli strumenti propri di QNAP | QDK 2.5.0, per bvs qbuild ed Esporta come QPKG |
| Sorgenti del kernel | un albero del kernel Linux per l’officina del kernel | Linux 6.6.129 da kernel.org; il rilascio GPL del kernel di QNAP per QTS 5.2.3 |
Le voci per un altro processore sono nascoste; “Mostra le voci per altri processori” le elenca, ma non si possono installare. Le toolchain Bootlin girano su x86_64, quindi un NAS ARM non ha toolchain incrociate.
Il catalogo
Il pacchetto contiene un catalogo integrato. Il catalogo remoto firmato su https://pub.qnaputilities.com/bucketvs/catalog.json può aggiungere voci senza un nuovo pacchetto. bvsd lo usa solo quando la sua firma ed25519 corrisponde alla chiave integrata nel pacchetto e non è più vecchio del catalogo in uso. “Aggiorna il catalogo” lo scarica subito, e il job cron integrato “Aggiornamento del catalogo delle toolchain” lo scarica ogni giorno alle 04:15.
Installare e rimuovere
Installare è compito di un admin, mostrato con il suo avanzamento nella pagina Job:
- L’archivio viene scaricato in
toolchains/cache/nella cartella dei dati. Un download interrotto riprende quando l’installazione viene riavviata. - Il suo sha256 viene confrontato con il catalogo. Una differenza elimina il file.
- Una toolchain incrociata o un runtime viene decompresso in
toolchains/<kind>/<id>e il suo archivio eliminato. Un filesystem radice o delle sorgenti del kernel restano come archivio; ogni ambiente o area di lavoro del kernel ne decomprime una propria copia. QNAP pubblica il suo rilascio GPL del kernel in due parti: entrambe vengono scaricate, ciascuna verificata con il proprio sha256, e unite.
Un volume pieno fa fallire l’installazione con “no space left on” e il punto di montaggio del volume.
“Rimuovi” elimina una voce installata. Gli ambienti creati da un filesystem radice sono copie e restano.
Usare una toolchain o un runtime
bvs use <id> stampa le righe export (come PATH) che rendono utilizzabile in una shell una toolchain incrociata o un runtime installato:
eval "$(bvs use bootlin-aarch64-glibc-stable)"
La pagina Toolchain mostra le stesse righe in “bvs use” per ogni voce installata.
Ambienti
Un ambiente è un sistema Linux decompresso da un filesystem radice in envs/<nome> nella cartella dei dati. È modificabile: apt install build-essential funziona dentro un ambiente Debian o Ubuntu, e ciò che installi resta lì.
- “Nuovo ambiente” (admin) scarica prima il filesystem radice quando non è installato, poi lo decomprime.
- Finché non c’è nessun ambiente, l’elenco propone l’Ubuntu 24.04 builder, quello in cui si compilano gli esempi di app, con un solo pulsante (admin): il suo job compare nell’elenco, e l’ambiente appare quando il job è finito. Niente viene creato da solo.
- Un nome ha da 1 a 64 caratteri: lettere minuscole, cifre,
.,_o-, iniziando con una lettera o una cifra. - Un modello della galleria Esempi installa anche pacchetti con apt-get prima che l’ambiente compaia: il builder Ubuntu 24.04 (il builder predefinito) e il builder Debian 12, entrambi completi, con gli strumenti di build di App Builder e patchelf; Clang/LLVM (LLVM 18), Fortran (gfortran 13), Kernel builder, .NET 8 SDK e Kotlin (Kotlin 1.3.31), tutti su Ubuntu 24.04. La glibc di ogni modello è al massimo 2.39, quindi ciò che vi si compila gira su ogni NAS su cui gira il pacchetto (Su quali modelli di NAS gira un’app). Quando apt-get fallisce, non resta alcun ambiente. Da una shell:
bvs env create <nome> --from <rootfs-id> --package <nome> --package <nome>. - “Clona” fa una copia completa con un nuovo nome, per esempio per provare una modifica senza toccare l’originale.
- “Esporta” impacchetta l’ambiente in
toolchains/exports/<nome>-<ora>.tar.zst. - “Elimina” lo rimuove. bvsd rifiuta finché una shell o un processo gira al suo interno. I file in
projects/non sono nell’ambiente e restano.
Dentro un ambiente:
projects/della cartella dei dati è visibile come/projects, e una shell parte lì;HOMEè/rootdell’ambiente, eLANGèC.UTF-8;- sono montati
/proc, un/sysin sola lettura e un piccolo/devproprio, e vi vengono copiatiresolv.confehostsdel NAS; - i montaggi appartengono allo spazio dei nomi di montaggio proprio della shell e spariscono quando essa termina, quindi sul NAS non resta montato nulla.
Lo stesso da una shell (gli esempi chiamano bvs per nome, come possono fare un job cron e una sessione SSH sul NAS mentre il pacchetto è in esecuzione):
bvs env list
bvs env create deb12 --from debian-12-x86_64
bvs env shell deb12
bvs env run deb12 -- make -C /projects/hello
bvs env shell e bvs env run partono nella cartella da cui li esegui. Una cartella sotto projects/ della cartella dei dati è la stessa cartella sotto /projects dentro l’ambiente. Qualsiasi altra cartella (il checkout di un job CI, una cartella in una condivisione) viene montata su /work e il comando parte lì. Da / partono in /projects.
Compilare un QPKG con bvs qbuild
bvs qbuild compila un QPKG dalla cartella in cui lo esegui (una cartella con qpkg.cfg, come quella che crea il modello QPKG di Nuovo progetto). Esegue il qbuild di QNAP dentro un ambiente Debian o Ubuntu. qbuild chiama i programmi di sistema con i loro percorsi completi, e nell’ambiente quei percorsi portano ai programmi dell’ambiente invece che a quelli del NAS. Il pacchetto finisce in build/ della cartella.
bvs tc install qdk-2.5.0-x86_64 # una volta; qdk-2.5.0-aarch64 su un NAS ARM
cd /share/CACHEDEV1_DATA/BucketVS/projects/MyTool
bvs qbuild # --env <nome> sceglie l'ambiente
Usa l’ambiente ubuntu2404-builder (l’esempio “Ubuntu 24.04 builder”), altrimenti debian12-builder, altrimenti un altro ambiente Debian o Ubuntu, e vi ha bisogno di rsync. Quando manca qualcosa, si ferma e indica il comando che lo aggiunge, per esempio bvs env run ubuntu2404-builder -- apt-get install -y rsync. Gli argomenti dopo bvs qbuild vanno a qbuild. Prima che qbuild parta, bvs qbuild dice quale caso di firma del codice vale per la cartella.
Un ambiente ha propri file e strumenti. Tutto ciò che contiene gira come root, vede ogni processo del NAS e usa la rete del NAS.
Firmare il codice di un QPKG
App Center controlla la firma del codice di un pacchetto quando lo installa. Per firmare serve un certificato di firma del codice rilasciato da QNAP. bvs qbuild indica uno dei tre casi nella prima riga, per esempio bvs: code signing, case 1 (a certificate as files): …:
| Caso | La cartella contiene | Cosa succede |
|---|---|---|
| 1, un certificato come file | certificate e private_key, facoltativamente ca_certs (la catena) | qbuild firma il pacchetto con openssl; l’ambiente ha bisogno di openssl e bsdextrautils |
| 2, un certificato su un token hardware | certificate_hsm | non supportato e non testato: bvs qbuild si ferma prima di compilare qualsiasi cosa |
| 3, nessun certificato | nessuno di questi file | il pacchetto viene compilato senza firma |
- Caso 1. Metti i tre file accanto a
qpkg.cfg. Se all’ambiente manca un programma,bvs qbuildindica il comando, per esempiobvs env run ubuntu2404-builder -- apt-get install -y openssl bsdextrautils. Rifiuta una cartella con uno solo dei filecertificateeprivate_key(qbuild avviserebbe e compilerebbe un pacchetto non firmato) e una in cui uno dei due è vuoto. Tieni questi file fuori da git: il.gitignoredel modello QPKG li elenca. In CI conservali come secret del repository e scrivili nella cartella solo per la build. - Caso 2. qbuild leggerebbe la posizione della chiave sul token da variabili che dentro l’ambiente non gli arrivano, e il pacchetto non è stato testato con un token. Compila senza
certificate_hsme firma il pacchetto sulla macchina che ha il token con gli strumenti di QDK; lo skill QNAP per gli assistenti IA (references/signing.md) descrive la via di QDK, che questo pacchetto non ha mai eseguito. - Caso 3. Su un’unità con QTS 6.1,
qpkg_cli -mdi un pacchetto non firmato non ha installato nulla, mentresh <file>.qpkgin una cartella condivisa lo ha installato e avviato. Il repository dei pacchetti lo accetta solo finché un admin consente i pacchetti non firmati, e App Center su un altro NAS lo installa solo se il suo proprietario consente app senza una firma digitale valida, cosa che questo pacchetto non consiglia mai. Esporta come QPKG dà sempre questo caso. qbuild --signaggiunge una firma GnuPG, che non è la firma del codice letta da App Center e dal repository.
App Builder
App Builder compila i programmi scelti in un’unica cartella, il prefisso dell’app (per impostazione predefinita /usr/app/my_app_prefix), dentro un ambiente.
La scheda Esempi di App contiene app pronte, ambienti, workflow CI, job cron e Progetti Editor. Vedi il codice su una scheda mostra cosa crea l’esempio prima di usarlo, per ogni ruolo: i file di un progetto Editor, il file del workflow, il comando del job cron o, per un’app, le sue ricette in ordine di build con build.sh e recipe.json di ciascuna. Il visualizzatore è di sola lettura e mostra i file di testo; un ambiente non ha file, quindi la sua scheda non ha questo pulsante. Usare un esempio richiede il ruolo developer, e un ambiente il ruolo admin: la scheda di un ambiente non offre Usa questo esempio a un developer.
Ricette
Ogni programma viene compilato da una ricetta. Una ricetta indica la sua sorgente con uno sha256, le ricette da cui dipende, gli strumenti di build di cui l’ambiente ha bisogno, e una verifica che dimostra che il risultato funziona (come bin/bash --version). Ci sono ricette per librerie (zlib, openssl, ncurses, readline e altre), shell (bash, zsh, busybox), strumenti (coreutils, curl, git, jq, rsync, tmux, htop, nano e altri), server (nginx, redis, openssh, dropbear) e un linguaggio (lua).
- Una ricetta viene compilata solo dopo le ricette da cui dipende.
- Una nuova build riusa il risultato di una ricetta finché i suoi input non cambiano (la sorgente, la ricetta, le sue dipendenze, il compilatore e la libreria C dell’ambiente, il prefisso, e se il link è dinamico o statico) e ogni file che ha installato è ancora nel prefisso.
- La modalità di collegamento decide come i programmi trovano le loro librerie. dinamico dà a ogni programma un RUNPATH
<prefix>/lib. relocatable lo scrive relativo alla cartella del programma stesso ($ORIGIN/../lib), così l’albero trova le sue librerie in qualsiasi cartella; i percorsi compilati dentro i programmi, come la cartella terminfo, nominano ancora il prefisso. bundle è relocatable e copia inoltre inlible librerie che i programmi caricano dall’ambiente di build (come libstdc++), così l’app ha bisogno solo della libreria C del NAS. statico collega staticamente le ricette che lo supportano. Passare tra dinamico, relocatable e bundle non ricompila nulla. - Un’app statica rifiuta le ricette che non si possono collegare staticamente (openssh, dropbear e tmux), nominando ciascuna con il motivo, a meno che l’app non sia impostata per compilarle come bundle. La pagina Nuova app e Cambia offrono tutte e quattro le modalità e, per un’app statica, quella scelta.
- Un programma statico che cerca utenti, gruppi o nomi host li legge solo da
/etc/passwd,/etc/group,/etc/hostse dal DNS del NAS stesso, qualunque cosa indichi/etc/nsswitch.conf, quindi gli account di un dominio o di LDAP gli sono sconosciuti. Compila questi programmi dinamici quando quegli account contano. Il pannello avvisa quando un’app statica ne include uno. - Dopo l’ultima ricetta, la verifica di ogni ricetta viene eseguita di nuovo sul prefisso finito.
- I file di configurazione sotto
etc/del prefisso sopravvivono a una nuova build: un file modificato resta, e il nuovo predefinito va accanto come<file>.bvs-new.
Aggiornamenti delle ricette
Le ricette nuove e aggiornate arrivano anche come catalogo firmato da pub.qnaputilities.com, così raggiungono il NAS prima della prossima versione di Bucket & Code Server IDE. bvsd cerca un catalogo più recente una volta al giorno. Lo usa solo se la firma corrisponde alla chiave integrata in bvsd, ogni file corrisponde all’elenco del catalogo e le sue ricette sono più recenti di quelle arrivate con il pacchetto; un catalogo che non supera un controllo non viene mai usato. Finché un catalogo è in uso, Nuova app segna le ricette che porta come nuova nel catalogo o aggiornata dal catalogo.
La scheda Libreria di ricette nella pagina App mostra quale libreria usano le build (Libreria del pacchetto con la versione del pacchetto, o Catalogo con la versione del catalogo) e l’ultimo controllo con il suo esito. Un admin vi trova due pulsanti; il secondo compare finché un catalogo è in uso:
- Cerca aggiornamenti delle ricette controlla subito, senza aspettare il controllo giornaliero.
- Usa la libreria del pacchetto torna alle ricette arrivate con Bucket & Code Server IDE. Il catalogo resta messo da parte finché non ne arriva uno più recente; allora le build usano quello più recente.
Dopo un cambio, una nuova build riusa ogni ricetta i cui file non sono cambiati. Prima di ogni build bvsd controlla di nuovo i file del catalogo. Se uno è cambiato sul NAS, la build si ferma prima che parta qualcosa, e le build usano il catalogo precedente o la libreria del pacchetto.
Compilare un’app
App, Nuova app (ruolo developer) chiede un nome, il prefisso (/usr/app/<nome> a meno che tu non ne scelga un altro), l’ambiente in cui l’app si compila (un ambiente Debian o Ubuntu; la galleria Esempi crea l’“Ubuntu 24.04 builder”, che la pagina sceglie per primo), la destinazione (l’architettura di questo NAS, o aarch64 o armv7 come build incrociata), i modelli di NAS su cui gira, la modalità di collegamento e le ricette. Le ricette da cui dipendono vengono aggiunte nell’ordine di build.
Un’app può anche prendere le ricette di un progetto che ha una propria cartella recipes/. Scegli il progetto in Ricette da un progetto, al passo Pacchetti. Le sue ricette sono le prime dell’elenco, sotto il nome del progetto e segnate progetto, e dopo vengono quelle della libreria. Una ricetta del progetto con il nome di una ricetta della libreria la sostituisce in questa app e mostra quale versione della libreria sostituisce. Una ricetta che il progetto esclude è indicata con il motivo. Una ricetta scelta che manca nell’elenco del progetto è indicata sotto la selezione ed esclusa dall’app; torna quando scegli un elenco che la contiene. La pagina dell’app indica il progetto, e da quel nome un developer apre la vista Progetto. Un viewer vede le ricette dell’ultima build dell’app nell’ordine in cui le nomina il suo log, ognuna con il suo stato e il suo log; prima della prima build non c’è un ordine da mostrare.
Ogni modalità di collegamento è una scheda, con un’immagine di dove i programmi trovano le loro librerie, quanto costa la modalità in dimensione, in aggiornamenti e in dove gira l’app, e quali ricette la supportano. Prima che tu scelga le ricette le schede contano l’intera libreria di ricette; quando torni al primo passo contano le ricette della tua build. Per un’app statica scegli che cosa succede alle ricette che non si possono collegare staticamente: compilarle come bundle, o lasciarle fuori.
- Compila (o Ricompila) esegue un job: scarica ogni sorgente e ne verifica lo sha256, installa nell’ambiente gli strumenti di build di cui le ricette hanno bisogno, compila in una copia della build precedente dell’app, e verifica ogni programma.
- Una build che fallisce, viene annullata o viene interrotta lascia l’app com’era: attivazione, download ed esportazione continuano a usare la build più recente che è riuscita.
- Gira una sola build di un’app alla volta, e una build attende mentre girano programmi dell’app attiva (fermali prima).
- La pagina dell’app mostra l’ordine di build, lo stato e il log di ogni ricetta, i file sotto il prefisso, e l’archivio della build riuscita più recente (Scarica, un
.tar.zst). - Cambia nella pagina dell’app imposta un altro ambiente, i modelli di NAS su cui gira, un’altra modalità di collegamento, il progetto da cui prende le ricette o altre ricette; la build successiva lo applica.
- Dipendenze, una scheda della pagina dell’app, mostra ciò di cui ogni file ELF della build più recente ha bisogno e dove il loader del NAS lo trova, letto senza eseguire nulla. Una libreria mancante, una versione che la libreria non definisce, o un RUNPATH che punta fuori dall’app è elencato come rilievo con la sua soluzione. Un developer esegue una soluzione con il suo pulsante: Aggiungi … e compila, Passa a … e compila, Ricompila, Correggi il RUNPATH, Imposta l’interprete, Scegli un altro ambiente o Compila solo per questo NAS. Una soluzione senza pulsante (installare un pacchetto in un ambiente, compilare per un’altra macchina) è una frase da seguire. Sotto i rilievi, ogni file e ciò di cui ha bisogno sono disegnati come grafo (i programmi, le librerie dell’app, quelle del NAS e quelle mancanti in colonne; una linea tratteggiata è una versione che manca alla libreria, una linea punteggiata una libreria non trovata da nessuna parte) o come albero; scegli un file per vederne i dettagli. Sul NAS,
bvs deps <app>stampa la stessa cosa. - Ispettore ELF (Toolchain, ruolo developer) verifica un file: dalla build di un’app, dalla cartella dei progetti o da un ambiente, e per un admin qualsiasi file sul NAS, come girerebbe su questo NAS o dentro un ambiente.
bvs ldd <file>fa lo stesso sul NAS (--env <name>per un ambiente). - Ogni build esegue la stessa verifica sul suo risultato prima di sostituire l’app, e fallisce su un problema che ferma un programma su questo NAS, o su un programma che richiede una glibc più recente di quella che l’app consente, con il problema e la sua soluzione nel messaggio del job.
- Strumento patch (la scheda Dipendenze) imposta il RUNPATH (il
libdell’app, la forma$ORIGIN, o una cartella dell’app) o l’interprete del programma di file scelti della build più recente, con il patchelf dell’ambiente, su una copia che sostituisce la build solo quando riesce. Anteprima mostra ogni file prima e dopo e quali librerie il nuovo RUNPATH non trova nell’app; Applica la patch la esegue. La build successiva riscrive i RUNPATH nella modalità di collegamento dell’app.
Una build di Qt esegue gli strumenti di Qt stesso (moc, rcc e, per le traduzioni, lrelease di Linguist). In una build incrociata le ricette di Qt (qtbase, qttools) compilano quindi prima questi strumenti per questo NAS, in host/ sotto il prefisso, e poi Qt per la destinazione; le ricette compilate su Qt eseguono gli strumenti da lì. Niente sulla destinazione esegue host/. Fa parte della build dell’app, quindi anche l’archivio ed Esporta come QPKG lo contengono.
Le tue ricette
Quando la libreria di ricette non ha una ricetta per un programma, un progetto può averne una sua. Le ricette vanno nella cartella recipes/ del progetto, nel formato della libreria, e le compilano solo le app che nominano il progetto. Un pacchetto si fa così in cinque passi:
- Crea il progetto. In Nuovo progetto, il modello Package from source (pacchetto dai sorgenti) crea una cartella con una ricetta iniziale che porta il nome del progetto, un Makefile per due app (una per il processore di questo NAS, una per aarch64, con una compilazione incrociata su un NAS x86_64) e lo script di avvio e arresto del pacchetto dal passo Servizio.
- Scrivi la ricetta. New recipe nell’editor aggiunge un’altra ricetta dalla stessa ricetta iniziale (Aprire l’editor). Metti in
recipe.jsonil vero indirizzo del sorgente del programma e il suo sha256 (curl -fsSL <indirizzo> | sha256sumnel terminale dell’editor stampa la somma), e i passi di compilazione inbuild.sh. La cartella di una ricetta contienerecipe.json,build.she il file vendor cherecipe.jsonnomina, nient’altro, quindi una patch va inbuild.shcome here-document. - Controllala. Ogni salvataggio di un file di una ricetta controlla le ricette del progetto ed elenca i risultati nella vista Problems;
make lintnel terminale e la scheda Ricette della vista Progetto danno gli stessi risultati. Il controllo leggerecipe.jsone analizzabuild.shconbash -n. Non esegue mai la ricetta. - Compila. Compila nella vista Progetto crea le due app quando mancano e le compila una dopo l’altra. Una build legge le ricette del progetto una volta, all’avvio, quindi un file salvato dopo aspetta la build successiva. Una ricetta del progetto con il nome di una ricetta della libreria la sostituisce solo nelle app di questo progetto, e il log della build lo dice.
- Impacchetta e installa.
make qpkgnel terminale dell’editor mette l’ultima build riuscita di ogni app nel pacchetto, con il QDK delle Toolchain, e tralascia un’app che non ne ha. Con i file di firma del codice inqpkg/accanto aqpkg.cfg, o in una cartella indicata daQPKG_CERT_DIR, il pacchetto è firmato (Firmare il codice di un QPKG), e Deploy di prova nella vista Progetto (admin) lo installa su questo NAS.
Alcune regole valgono per le ricette di un progetto:
- Una ricetta che il progetto esclude (un file in più nella sua cartella, un link, un file oltre il suo limite di dimensione) è indicata con il motivo nella scheda Ricette e dal controllo, e una build che ne ha bisogno viene rifiutata.
- Quando la cartella del progetto viene rinominata o eliminata, le sue app non si compilano: la build risponde “Non esiste un progetto ‘…’” finché Cambia nella pagina dell’app non imposta il nuovo nome del progetto o Nessuno: solo la libreria.
- Le ricette di un progetto girano come root nell’ambiente di compilazione, come quelle della libreria. Ogni developer può scriverle e compilarle, come ogni developer può eseguire il Makefile di un progetto con Compila. Un viewer vede i nomi delle ricette di un’app nel log della sua build, mai i file delle ricette.
- Una ricetta di progetto resta nel suo progetto. Entra nella libreria di ricette, e nel catalogo firmato che ogni NAS riceve, solo con una modifica revisionata di Bucket & Code Server IDE stesso.
- Una ricetta la cui build ha bisogno di pacchetti npm, Go o Cargo li elenca in un file vendor. Questo elenco lo scrivono
npm-vendor.py,go-vendor.pyecargo-vendor.pyin/usr/bin/bucketvs/share/bucketvs/tools/; hanno bisogno di un runtime Python dalle Toolchain.
Su quali modelli di NAS gira un’app
Un programma compilato con la glibc parte solo su un NAS la cui glibc è almeno recente quanto la versione più recente che il programma chiede. Il pacchetto conta su una glibc 2.39 o più recente su ogni NAS su cui gira (QTS 6.0, QuTS hero 6.0 e successivi): è la sua soglia minima di glibc. 2.39 è la glibc di Ubuntu 24.04 e di QuTS hero 6.0.1, letta dal /lib/libc.so.6 di quel firmware; QNAP non pubblica alcuna versione di glibc, e le sue note di rilascio non elencano alcun QTS 6.0. I NAS di prova con QTS 6.1.0 e QuTS hero 6.1.0 hanno 2.43.
Gira su nella nuova app e in Cambia sceglie uno dei due:
- Ogni NAS su cui gira il pacchetto (predefinito): nessun programma può richiedere una glibc sopra 2.39. Compila un’app del genere in un ambiente con glibc 2.39 o precedente, come l’Ubuntu 24.04 builder (2.39) o il Debian 12 builder (2.36). È la scelta per Esporta come QPKG e il repository dei pacchetti.
- Solo questo NAS: i programmi possono richiedere la glibc di questo NAS, per un software che ne richiede una più recente. Un’app del genere si compila per l’architettura di questo NAS e non viene mai esportata come QPKG.
Una compilazione incrociata (aarch64 o armv7) è sempre per ogni NAS. La nuova app avvisa quando la glibc dell’ambiente scelto supera quanto l’app consente. Dopo ogni compilazione, bvsd legge la versione di glibc che chiede ogni programma e ogni libreria, anche in una compilazione incrociata. Un file sopra il limite fa fallire la compilazione, e le soluzioni sono indicate: un altro ambiente (Scegli un altro ambiente), la modalità di collegamento static o Compila solo per questo NAS. La pagina dell’app dice quale glibc richiede la sua compilazione riuscita più recente, e la scheda Dipendenze elenca ogni file sopra il limite.
Sul NAS, bvs tree-deps <prefisso> --tree <cartella> --glibc-max 2.39 esegue la stessa verifica su qualsiasi albero di un’app.
Attivare un’app sul NAS
Attiva (admin) rende il prefisso un collegamento alla build riuscita più recente dell’app, così i suoi programmi girano sul NAS da /usr/app/<nome>/bin. L’attivazione non sostituisce mai nulla che non abbia creato: una cartella, un file o un altro collegamento al prefisso viene rifiutato con il motivo. Il disco di sistema di QTS viene ricostruito a ogni avvio, quindi il pacchetto ricrea i collegamenti a ogni suo avvio. Disattiva (admin) rimuove il collegamento; eliminare l’app prima la disattiva e poi la sposta nel cestino per 7 giorni. Un developer può eliminare un’app solo quando non è attiva. Un’app compilata per un’altra architettura non può essere attivata qui; scarica il suo archivio per un NAS di quel tipo.
Esportare un’app
Esporta come QPKG (admin) impacchetta la build riuscita più recente come un QPKG a sé, che installa l’app su un altro NAS senza questo pacchetto. Rifiuta un’app compilata solo per questo NAS, e si ferma prima di impacchettare quando un programma della build richiede una glibc sopra 2.39 (vedi Su quali modelli di NAS gira un’app). Richiede QDK: installa “QNAP QDK 2.5.0” nella pagina Toolchain, scheda QNAP. Finché QDK non è installato il pulsante non compare e la pagina dell’app dice dove ottenerlo. L’esportazione esegue qbuild nell’ambiente dell’app, allo stesso modo di bvs qbuild. Ogni build vi installa rsync; per un’app compilata l’ultima volta con una versione più vecchia del pacchetto, il rifiuto indica il comando che lo aggiunge. Il pacchetto esportato crea il collegamento del suo prefisso all’avvio e lo rimuove all’arresto. Non è firmato: il log del job indica il caso 3, come una riga sotto il pulsante. In una sessione SSH, /etc/init.d/<nome>.sh disable ed enable impostano l’interruttore del pacchetto esportato in App Center e lasciano com’è il collegamento del prefisso. A ogni avvio il pacchetto esportato aggiunge anche una riga a /etc/profile e a /root/.profile, che mette bin e sbin dell’app nel PATH di un accesso SSH, dopo i comandi propri del NAS, per admin e per ogni altro account che può accedere; la rimozione toglie di nuovo la riga.
Repository dei pacchetti
Il pacchetto gestisce un repository di App Center: i pacchetti QPKG pubblicati lì si possono installare su altri NAS da App Center, come le app di qualsiasi repository.
- L’indirizzo.
bvs repo listlo stampa (eGET /api/v1/repo):<base>/repo/repo.xml, dove<base>è l’host dei pacchetti pubblicato (altrimenti il nome host principale pubblicato) finché il pacchetto è pubblicato su internet (Pubblicare su internet), altrimenti l’URL pubblico quando è impostato, altrimentihttp://<indirizzo del NAS>:9950(https://…:9951quando HTTP semplice si limita a reindirizzare). Sull’altro NAS: App Center, Impostazioni, Repository di app, Aggiungi, e quell’indirizzo. - Pubblicazione.
bvs repo publish <file.qpkg>(sul NAS, come root) oPOST /api/v1/repo/packagescon il file come corpo (ruolo developer). L’architettura viene dal nome del file QDK<name>_<version>_<arch>.qpkg(x86_64,arm_64,arm-x41), o da--arch. Nome, versione, descrizione e autore vengono dal pacchetto stesso;PUT /api/v1/repo/packages/<name>/metae…/icon(un PNG, admin) cambiano ciò che App Center mostra. Un pacchetto non può chiamarsidefault: è il nome dell’icona propria del repository. - Solo pacchetti firmati. Un pacchetto senza firma del codice viene rifiutato, perché App Center installa questi pacchetti solo su un NAS impostato per consentirli. Il repository considera firmato un pacchetto quando il suo blocco di firma del codice è una firma PKCS#7 con un certificato e un firmatario. Non verifica quella firma né i suoi certificati rispetto a quelli di QNAP; lo fa App Center quando installa il pacchetto. Un admin può attivare
repo.accept_unsignednelle impostazioni per una rete in cui questo è noto; quei pacchetti sono marcati nella loro descrizione. I pacchetti che App Builder esporta non sono firmati, quindi hanno bisogno di questa impostazione. - Versioni. Ogni versione resta scaricabile, ma App Center vede una versione per pacchetto, quella che un admin elenca. La prima versione di un pacchetto pubblicata da un admin viene elencata subito; una successiva quando l’admin la sposta (
POST /api/v1/repo/packages/<name>/latest, obvs repo publish --latest). La versione di un developer, compresa la prima di un nuovo pacchetto, non è elencata da nessuna parte finché un admin non rende una versione la più recente: ogni NAS che ha aggiunto il repository installa la versione elencata come root. Eliminare una versione (admin) ne rimuove tutte le architetture; quando era quella elencata, nessuna versione è elencata finché un admin non ne sceglie un’altra. - Caricamenti. Due caricamenti vengono copiati alla volta; il repository rifiuta un caricamento che lascerebbe meno di 256 MiB liberi sul volume dati. Il repository non fa parte di un backup: dopo un ripristino, pubblica di nuovo i pacchetti.
- Nel pannello. La pagina Pacchetti mostra l’indirizzo da copiare, i pacchetti con le loro versioni e se sono firmati; lì un developer carica un QPKG, e un admin elenca una versione come la più recente ed elimina una versione. La sua scheda Firma del codice mostra i tre casi, quante versioni elencate non hanno firma, e l’interruttore dell’admin per i pacchetti non firmati, che chiede conferma prima di attivarsi. La pagina di un’app mostra la sua pipeline (build, esportazione come QPKG, pubblicazione) con un pulsante Pubblica.
Officina del kernel
L’officina del kernel compila moduli per il kernel che il NAS esegue, verifica ciascuno rispetto a quel kernel e lo carica. QNAP non ha pubblicato i sorgenti dei suoi kernel attuali (i suoi rilasci GPL si fermano a QTS 5.2.3), quindi l’officina legge ciò che il kernel in esecuzione mostra di sé e configura un albero del kernel che gli corrisponda.
Che cosa serve
- L’ambiente Kernel builder dalla galleria Esempi (Ubuntu 24.04 con GCC 13 e gli strumenti di build del kernel). Un modulo deve essere compilato con la stessa versione principale di GCC del kernel; l’officina le confronta.
- Il ruolo admin, e root in un terminale: i comandi
bvs kernelusano il socket CLI di bvsd o caricano moduli.
Il profilo
bvs kernel profile mostra che cos’è il kernel in esecuzione: la sua release (6.6.129-qnap), il compilatore con cui QNAP l’ha compilato, il vermagic dei moduli propri di QNAP, la dimensione di struct module in essi e dove si trovano init e exit, se i moduli devono essere firmati, e le impostazioni che un albero del kernel riceve per corrispondergli.
L’area di lavoro
bvs kernel prepare crea l’area di lavoro del kernel in esecuzione in kernels/<release> della cartella dei dati:
- Prende i sorgenti del kernel che il catalogo ha per questa versione (
bvs kernel sources): l’albero GPL proprio di QNAP quando QNAP ne ha pubblicato uno, altrimenti l’albero di kernel.org, a cui mancano le modifiche proprie di QNAP.--sourcene sceglie un altro. - Configura l’albero: con la configurazione di QNAP per questo modello quando l’albero è di QNAP, altrimenti con le impostazioni del profilo.
--option NAME=maggiunge un’impostazione, per esempio un driver. - Prepara l’albero per la build di moduli (
--fullcompila invece l’intero kernel, il che richiede molto più tempo e permette alla verifica di vedere i simboli esportati del kernel). - Verifica che l’albero compili esattamente per la release del kernel in esecuzione.
Gira come job nella pagina Job. Un prepare non riuscito conserva l’albero del precedente.
Compilare un modulo
- Il tuo modulo è una cartella in
projects/con un fileKbuild.bvs kernel makein quella cartella (obvs kernel make --project <folder>) lo compila. L’esempio “Kernel module” è un progetto di questo tipo. - Un driver del kernel che QNAP non fornisce si compila dalla sua directory dell’albero del kernel:
bvs kernel make --dir drivers/usb/serial. L’esempio “USB serial driver ch341” compila così il driver ch341; la sua impostazione viene prima conbvs kernel prepare --option USB_SERIAL=m --option USB_SERIAL_CH341=m.
I moduli prodotti da una build sono conservati in kernels/<release>/modules/. Un modulo che QNAP fornisce per questo kernel non viene conservato: la copia propria di QNAP resta quella che si carica. bvs kernel make --build-only non vi conserva nulla: il modulo resta dove è stato compilato. I workflow CI dei modelli del kernel di Nuovo progetto compilano così.
La verifica e il caricamento
bvs kernel check <module> confronta un modulo con il kernel in esecuzione: il vermagic, la dimensione di struct module e dove si trovano init e exit al suo interno (rispetto ai moduli propri di QNAP), se è richiesta una firma, i moduli da cui dipende, e ogni simbolo di cui ha bisogno. Ogni rilievo dice che cosa non corrisponde e che cosa fare. Lo stato di uscita 3 significa che il modulo non deve essere caricato.
bvs kernel load <module> esegue di nuovo la verifica e carica il modulo, prima i moduli da cui dipende (quelli di QNAP dal NAS, o i tuoi). Un modulo con un errore nella verifica non viene mai caricato. bvs kernel unload <module> lo rimuove; un modulo in uso resta caricato. Ogni caricamento e scaricamento viene scritto in log/kernel-modules.log.
Il kernel di QNAP non elenca i suoi simboli di dati, quindi la verifica non può cercare simboli come jiffies; li nomina come avvisi. Se uno di essi manca, il kernel rifiuta il modulo al caricamento.
Moduli in un’app
Un’app può nominare moduli dell’area di lavoro. Attivare l’app li carica prima che venga creato il suo collegamento, e ogni avvio del pacchetto li carica di nuovo una volta che il pannello è attivo; la pagina Kernel mostra un caricamento ancora in corso. Disattivarla li scarica prima; un modulo in uso tiene l’app attiva.
- Se il NAS si è riavviato mentre i moduli venivano caricati, l’avvio successivo non ne carica nessuno e mostra una notifica: caricali a mano o attiva di nuovo l’app.
- Se il NAS si è fermato senza l’arresto ordinato del pacchetto (un crash, un’interruzione di corrente o un reset forzato) in un avvio in cui il pacchetto aveva caricato moduli, l’avvio successivo non carica quei moduli, perché uno di essi può aver causato il crash. La notifica e la pagina Kernel li nominano. Caricarne uno a mano, o attivare di nuovo la sua app, permette all’avvio di caricarlo di nuovo. Uno spegnimento o un riavvio normale del NAS ferma il pacchetto in ordine e non cambia nulla.
- Un modulo il cui avvio non finisce mai (un driver che aspetta il suo hardware) lascia il pannello funzionante. Una notifica lo nomina dopo un minuto; gli altri caricamenti e scaricamenti lo attendono, e un riavvio del NAS lo termina.
Dopo un aggiornamento di QTS a un altro kernel, i moduli vanno ricompilati nell’area di lavoro del nuovo kernel. Lo stesso vale dopo un ripristino su un’altra cartella dei dati: kernels/ non fa parte di un backup.
Nel pannello
La pagina Kernel mostra il profilo del kernel in esecuzione, i sorgenti del kernel del catalogo, l’area di lavoro e i suoi moduli. Lì un admin prepara l’area di lavoro (una sorgente, l’ambiente, impostazioni aggiuntive, l’intero kernel o no) e compila moduli da una cartella di progetto o da una directory dell’albero; entrambe le cose girano come job. Verifica (developer) mostra ogni rilievo con la sua soluzione; Carica e Scarica dal kernel (admin) fanno ciò che fanno bvs kernel load e unload, e un caricamento rifiutato mostra la verifica che lo ha fermato. Un file .ko in qualsiasi punto sotto la cartella dei dati può essere verificato indicandone il percorso.
Job cron e operazioni
La pagina Job ha due elenchi: i job pianificati (cron) e le operazioni (i job lunghi che bvsd esegue, come installazioni e spostamenti).
Job pianificati
Un developer crea e modifica i propri job; un admin li modifica tutti. Un job ha:
- Pianificazione: cinque campi cron (
0 3 * * *), sei con i secondi per primi, o un descrittore (@daily,@hourly,@every 6h). Un prefissoCRON_TZ=<zone>sceglie un altro fuso orario; senza, il job gira nel fuso orario del NAS, mostrato in cima alla pagina. - Comando: eseguito come root dal
bash -lcdel pacchetto. Più righe girano come un unico script, e il suo output diventa il log dell’esecuzione. - Dove gira: sul NAS, o dentro un ambiente (con il
bashdell’ambiente, o/bin/shdove non ce l’ha). - Cartella di lavoro: relativa a
projects/nella cartella dei dati, o un percorso completo. Dentro un ambiente è visibile soloprojects/, come/projects. - Timeout: in secondi (0: nessuno). Un’esecuzione ancora in corso dopo di esso viene fermata e marcata come scaduta.
- Mentre un’esecuzione è in corso: la successiva viene saltata, o attende (al massimo una attende).
- In caso di errore: un’esecuzione fallita o scaduta invia una notifica.
Ogni job conserva le sue ultime 100 esecuzioni con la fine del loro output (4 KB). Il log completo di un’esecuzione è conservato 30 giorni.
Un job gira come root per conto del suo proprietario, con la cartella home del proprietario come HOME, quindi gira solo finché il suo proprietario è un developer o un admin attivo. Finché il proprietario è disattivato o ha il ruolo member o viewer, ogni orario del job viene registrato come esecuzione saltata che dice perché, per esempio “its owner ola is disabled”, e Esegui ora risponde con lo stesso motivo. Non viene inviata nessuna notifica. Un’esecuzione in corso quando il proprietario viene disattivato o riceve un ruolo inferiore a developer viene fermata. Il job torna a girare quando l’account viene riattivato, o torna developer. Eliminare un account elimina i suoi job. I job integrati girano qualunque cosa succeda a un account.
Quando un comando termina, i processi che ha avviato in background continuano a girare. Al timeout, all’eliminazione del job o all’arresto del pacchetto, l’intero gruppo di processi dell’esecuzione riceve SIGTERM, poi SIGKILL dopo 5 secondi.
Nelle notti in cui cambia l’ora, i job seguono la regola del cron di Debian. Un job con * all’inizio del campo dei minuti o delle ore (anche */N), @hourly o @every segue il tempo trascorso: in autunno gira in entrambi i passaggi dell’ora ripetuta, e in primavera l’ora saltata non arriva. Ogni altro job esegue ciascuno dei suoi orari una volta: un orario nell’ora ripetuta gira una volta, e un orario nell’ora saltata gira subito dopo il cambio.
Ogni account connesso, anche un viewer, legge i comandi delle attività e l’output delle loro esecuzioni. Non mettere password o token in un comando: fai in modo che li legga da un file in <data>/etc che solo root legge (chmod 600).
Job integrati
| Job | Quando | Che cosa fa |
|---|---|---|
| Manutenzione | ogni giorno alle 03:30 | rimuove da tmp/ nella cartella dei dati ciò che nulla ha modificato da 10 giorni; ruota log/audit.log oltre i 10 MB |
| Svuota il cestino | ogni giorno alle 03:45 | rimuove ciò che è stato spostato in trash/ nella cartella dei dati più di 7 giorni fa (come la cartella home di un account eliminato) |
| Aggiornamento del catalogo delle toolchain | ogni giorno alle 04:15 | scarica il catalogo firmato delle toolchain |
| Ruota i log di nginx | ogni ora, al minuto 7 | rinomina nginx-access.log o nginx-error.log in .1 quando supera i 20 MB (cinque vecchi file conservati) e dice a nginx di riaprire i suoi log |
Un admin può cambiare pianificazione, timeout, criterio e notifica di un job integrato, e disattivarlo. Il suo nome e il suo comando restano.
Operazioni
Installazioni, job degli ambienti, spostamenti dei dati e l’attivazione di un modulo girano come operazioni. L’elenco mostra le ultime 50, le più recenti per prime, con il loro avanzamento e il loro log. Le operazioni e i loro log sono conservati 30 giorni. Un’operazione che era in corso quando il pacchetto si è fermato appare come interrupted. Un developer annulla le proprie operazioni; un admin annulla qualsiasi.
Backup
La pagina Backup (admin) imposta che cosa viene salvato, quando, dove vanno le copie e quante ne vengono conservate. Esegui il backup ora avvia un backup in qualsiasi momento. Su una nuova installazione i backup pianificati sono disattivati; una volta attivato Backup pianificati, un backup gira ogni giorno per impostazione predefinita (il job cron integrato backup). Conserva l’esecuzione più recente di ciascuno degli ultimi 7 giorni, 4 settimane e 6 mesi, e sempre l’esecuzione riuscita più recente. Gira un solo backup, verifica, ripristino o eliminazione alla volta.
Due esecuzioni nello stesso giorno contano come un solo giorno: quando la più recente termina, l’esecuzione precedente di quel giorno viene rimossa. Un Esegui il backup ora nel pomeriggio sostituisce quindi l’esecuzione pianificata di quella mattina; copia prima un’esecuzione altrove quando lo stato di quella mattina conta.
Che cosa contiene un backup
Un’esecuzione è una cartella <dati>/backups/<id>/ con un manifest.json che elenca ogni file con il suo sha256:
| Parte | Che cosa |
|---|---|
| impostazioni | etc/: impostazioni, account, segreti TOTP, la chiave TLS, le chiavi di backup |
| Git | il dump di Forgejo: repository, wiki, oggetti LFS, allegati e il suo database |
| SVN, bucket | una copia di ogni repository, fatta in modo incrementale: una revisione già copiata non viene copiata di nuovo |
| impostazioni di VS Code | le impostazioni di VS Code di ogni account, le scorciatoie da tastiera, gli snippet e l’elenco delle sue estensioni (non i file delle estensioni: la vista Extensions le reinstalla) |
| ambienti | gli ambienti di Toolchain (disattivati per impostazione predefinita: si possono ricreare) |
| progetti | ogni cartella di progetto con la sua cronologia Git e i file non ancora inviati con commit, senza node_modules |
| cartelle HOME | la cartella HOME di ogni account, senza cache e senza le installazioni degli strumenti di IA stessi (il loro pulsante Installa le rimette) |
| App Builder | le impostazioni di ogni app e la cronologia delle sue build; una build rifà i file dell’app |
| repository dei pacchetti | i pacchetti pubblicati, le loro icone e l’indice che legge App Center |
Queste quattro parti sono in ogni backup, qualunque cosa sia spuntata nella pagina. Una cartella che non è cambiata dal backup precedente è collegata alla copia di quel backup e non occupa spazio.
L’esecuzione diventa visibile solo quando ogni parte è scritta e verificata; un errore o un volume pieno rimuove la cartella incompiuta e lascia le esecuzioni precedenti come erano. Verifica rilegge completamente un’esecuzione: lo sha256 di ogni archivio, svnadmin verify di ogni revisione, git fsck di ogni repository e un controllo di integrità del database di Forgejo.
Destinazioni
Ogni esecuzione viene copiata su ogni destinazione della pagina:
- Cartella locale su questo NAS: l’esecuzione così com’è, con i file invariati collegati alla copia precedente, così ogni copia costa solo ciò che è cambiato. Non cifrata. Sugli stessi dischi dei dati, protegge dagli errori, non da un volume guasto.
- rsync (
user@host:path) via SSH. Accedi con la chiave di backup del pacchetto: la pagina mostra la chiave pubblica da aggiungere aauthorized_keysdell’altra macchina. - rclone (
remote:path, un remote da<dati>/etc/rclone.conf): archiviazione cloud e tutto ciò che rclone raggiunge.
Una copia che lascia il NAS (rsync, rclone) deve essere cifrata: attiva Cifra le copie che lasciano il NAS e Crea la chiave. Le copie vengono cifrate con age per la sua metà pubblica; la metà segreta è mostrata una sola volta e bvsd non la conserva. Senza di essa nessun NAS, questo compreso, può ripristinare una copia cifrata: conservala lontano da questo NAS. Una nuova chiave cifra le esecuzioni da quel momento in poi; le copie più vecchie richiedono la vecchia chiave segreta.
Una destinazione che fallisce viene nominata nel risultato dell’esecuzione; l’esecuzione stessa resta valida.
rclone.conf contiene le credenziali dei remoti. Prima che una copia o un Test lo usi, bvsd lo rende (insieme alla chiave di backup) leggibile solo da root (modalità 600) se non lo è, e il log dell’attività lo dice.
Ripristinare
Ripristina su un’esecuzione rimette al suo posto tutto, un repository (un repository SVN, un bucket o un repository Git) oppure una cartella di progetto:
- Nulla viene sostituito prima di essere verificato: ogni archivio rispetto al suo sha256, ogni copia SVN con
svnadmin verify. Una copia che non passa ferma il ripristino prima che cambi qualcosa nei dati in uso. - I dati in uso che vengono sostituiti vanno in
<dati>/trashper 7 giorni, così anche un ripristino si può annullare. - Un repository o una cartella di progetto viene rimesso al suo posto mentre i moduli continuano a girare. Una cartella di progetto eliminata per sbaglio torna con la sua cronologia e i file non ancora inviati con commit.
- Tutto ferma i moduli, scambia i dati e riavvia bvsd con le impostazioni ripristinate: ogni sessione termina, e gli account e le password sono quelli del backup. Una cartella di progetto o HOME creata dopo il backup resta.
Notifiche
bvsd scrive ogni notifica nei log di sistema di QTS. Può anche inviarle a servizi di chat e di posta tramite URL shoutrrr (Telegram, Discord, Slack, e-mail, un webhook generico e altri).
| Notifica | Quando | Interruttore per gli URL |
|---|---|---|
| errore di un job | un’esecuzione cron di un job con notifica in caso di errore è fallita o è scaduta; un’operazione è fallita | notify.on_job_failure |
| backup | il risultato di ogni backup, verifica e ripristino, anche di quelli riusciti; un backup pianificato che non è potuto partire | notify.on_backup |
| ciclo di riavvii | un processo ha iniziato a riavviarsi in un ciclo continuo | notify.on_crashloop |
| certificato | a un certificato caricato restano 30 giorni o meno; nginx è tornato al certificato autofirmato; è stato creato un nuovo certificato autofirmato | notify.on_cert_expiry |
| sistema | impostazioni rifiutate all’avvio, trovato uno spostamento dei dati incompiuto, processi rimasti terminati, la configurazione non si è potuta scrivere | inviata sempre |
- Gli interruttori decidono solo che cosa va agli URL. I log di sistema ricevono ogni notifica.
- La stessa notifica parte al massimo una volta ogni 10 minuti. La successiva dopo quel tempo dice quante sono state trattenute.
- Ogni URL riceve il proprio
shoutrrr sendcon un limite di 10 secondi. Un errore viene registrato solo con lo schema dell’URL, perché il resto di un URL contiene il suo token.
Gli URL e gli interruttori si trovano in Notifiche nella pagina Sistema; gli interruttori sono attivi per impostazione predefinita. Un admin li modifica lì. Gli altri account vedono gli interruttori e solo lo schema di ogni URL, perché il resto di un URL contiene il suo token. L’admin del NAS può impostarli anche tramite il socket CLI:
/usr/bin/bucketvs/bin/curl --unix-socket /usr/bin/bucketvs/var/run/bvsd-cli.sock \
-X PUT -H 'Content-Type: application/json' \
-d '{"notify":{"shoutrrr_urls":["telegram://<token>@telegram?chats=<chat id>"]}}' \
http://bvsd/api/v1/settings
Log e pacchetto diagnostico
Ogni log è log/<name>.log nella cartella dei dati. I log di bvsd e di ogni processo che sorveglia vengono ruotati a 20 MB, e cinque vecchi file sono conservati. nginx-access.log e nginx-error.log hanno gli stessi limiti, controllati a ogni avvio di bvsd e ogni ora dal job “Ruota i log di nginx”, quindi uno di essi può superare i 20 MB di al massimo un’ora di traffico. Il job “Manutenzione” ruota audit.log quando supera i 10 MB e conserva tre vecchi file. La pagina Log (admin) mostra le ultime righe di qualsiasi log, le filtra e segue le nuove righe man mano che arrivano:
| Log | Chi lo scrive |
|---|---|
bvsd | bvsd stesso: avvii, arresti, impostazioni applicate, problemi |
nginx | l’output proprio di nginx |
nginx-access, nginx-error | ogni richiesta, e gli errori di nginx |
audit | ogni richiesta sul socket CLI |
| uno per processo di modulo | il programma di ciascun modulo |
La pagina Sistema mostra la versione, la piattaforma, il fuso orario e ogni processo che bvsd sorveglia. “Scarica il pacchetto diagnostico” (admin) crea un archivio per una segnalazione di bug:
- le impostazioni con la password SMTP e ogni URL shoutrrr mascherati;
- il
nginx.confgenerato, i dettagli del certificato senza la sua chiave, i volumi; - lo stato di ogni modulo, processo e operazione recente;
- le ultime 2000 righe di ogni log, con ogni stringa di query al loro interno sostituita da
?(query removed).
Non contiene mai password, sessioni, token o chiavi.
Aggiornamenti
bvsd legge https://pub.qnaputilities.com/bucketvs/latest.json all’avvio e ogni 24 ore. Quando indica una versione più recente, la pagina Sistema la nomina, con il collegamento che il feed fornisce. bvsd si limita a segnalare la nuova versione: non scarica né installa mai un pacchetto. Un controllo non riuscito non cambia nulla nel pannello.
Installare una nuova versione
Installa il nuovo pacchetto sopra il vecchio, da App Center o con Installazione manuale. L’installazione ferma bvsd, sostituisce i file del programma e lo riavvia; la cartella dei dati, le impostazioni, gli account e ogni repository restano, e così le sessioni del pannello. Le istanze dell’editor si fermano con bvsd, quindi i terminali aperti degli editor terminano; un’istanza riparte quando il suo account apre l’editor.
Da una versione che usava le porte 6050, 6051 e 6052. Le versioni precedenti ascoltavano su 6050 (HTTP), 6051 (HTTPS) e 6052 (Git via SSH). Il primo avvio della nuova versione sposta ciascuna di esse su 9950, 9951 e 9952 e lo dice in una notifica; una porta scelta da te resta. Cambia ciò che nomina le vecchie porte: segnalibri, un proxy Plesk verso 6050, e remote git come ssh://git@<NAS>:6052/… (git remote set-url).
Rimuovere, reinstallare e un pacchetto danneggiato
Il tuo lavoro resta quando il pacchetto viene rimosso, reinstallato o si danneggia. Tutto ciò che crei sta nella cartella dei dati: account e impostazioni, repository Git e SVN, bucket, cartelle di progetto, cartelle HOME, impostazioni ed estensioni di VS Code, app dell’App Builder, ambienti, il repository dei pacchetti e i backup. La cartella di installazione (<volume>/.qpkg/bucketvs) contiene solo i programmi e un file che indica la cartella dei dati.
- Rimuovere, poi reinstallare. La rimozione del pacchetto cancella la cartella di installazione e tiene la cartella dei dati e
/etc/config/bucketvs-data-root, il file che la indica. L’installazione successiva legge quel file e parte sulla stessa cartella dei dati: gli stessi account e password, gli stessi progetti e repository, sessioni aperte comprese. - Installare sopra il pacchetto installato. La stessa versione o una più recente sostituisce i file dei programmi; la cartella dei dati non viene toccata.
- Un pacchetto danneggiato. Quando la cartella di installazione è danneggiata (manca un programma, la cartella è stata eliminata a mano), reinstalla il pacchetto da App Center o con Installazione manuale. L’installazione trova la cartella dei dati allo stesso modo. Un bvsd che gira ancora da file eliminati viene fermato all’avvio, e parte quello installato.
- Cosa cancella i dati. Solo l’eliminazione della cartella della cartella dei dati. Per ripartire da zero di proposito, rimuovi il pacchetto, elimina la cartella della cartella dei dati, poi installa: il primo avvio crea una nuova cartella dei dati, come descritto in Dove nasce la cartella dei dati.
Un disco che si guasta è un’altra cosa: la cartella dei dati sta sui dischi del NAS stesso. Tieni i backup su un’altra macchina (Backup); ogni backup contiene le tue cartelle di progetto, le cartelle HOME, le impostazioni dell’App Builder e il repository dei pacchetti.
Il comando bvs
bvs è la riga di comando del pacchetto, in /usr/bin/bucketvs/bin. È nel PATH di ogni processo che bvsd avvia, job cron compresi. Mentre il pacchetto è in esecuzione, /usr/bin/bvs è un link al comando, quindi anche in una sessione SSH sul NAS lo chiami per nome; l’arresto del pacchetto rimuove il link.
Ogni comando che parla con bvsd tramite il suo socket CLI richiede root, perché il socket è solo di root: user, jobs e, mentre bvsd è in esecuzione, tc install, tc remove ed env create, clone, export e delete. Anche env shell, env run e qbuild richiedono root: avviano bvs-chroot. Come altro utente, un comando che ha bisogno del socket si ferma con “bvsd's CLI socket … is open to root only: run bvs as root”.
bvs env list
bvs env create <name> --from <rootfs-id> [--package <name>]...
bvs env shell <name>
bvs env run <name> -- <command> [<arg>...]
bvs env clone <name> <new-name>
bvs env export <name>
bvs env delete <name>
bvs tc list
bvs tc install <id>
bvs tc remove <id>
bvs use <id>
bvs jobs
bvs user list
bvs user password <name>
bvs user totp-reset <name>
bvs guide [--path] [en|pl|de|fr|it|nl|sv|ja|zh-TW]
bvs qbuild [--env <name>] [<qbuild argument>...]
bvs kernel profile [--json]
bvs kernel sources
bvs kernel prepare [--source <id>] [--env <name>] [--option NAME=VALUE]... [--full]
bvs kernel make [--project <folder> | --dir <tree directory>] [--build-only] [<target>...]
bvs kernel check <file.ko | module>
bvs kernel load <module>
bvs kernel unload <module>
- Mentre bvsd è in esecuzione, le installazioni e i job degli ambienti vanno a bvsd tramite il suo socket CLI, così il pannello li mostra, e
bvsli segue finché non terminano. Senza bvsd girano nel processobvsstesso;--localprima del comando lo fa di proposito. bvs jobse i comandiuserrichiedono bvsd.bvs guideapre questa guida con illessdel pacchetto in un terminale, e altrimenti, o con--path, stampa il percorso del suo file. Senza una lingua segue la prima impostata traLC_ALL,LC_MESSAGESeLANG:de_DE.UTF-8apre la guida tedesca,zh_TWezh_HKquella in cinese tradizionale, e una lingua in cui la guida non è scritta (C,zh_CN) quella inglese.
File e cartelle
| Percorso | Che cosa |
|---|---|
/usr/bin/bucketvs | i programmi del pacchetto (un collegamento alla sua cartella di installazione) |
/usr/bin/bucketvs/etc/data-root | il percorso della cartella dei dati |
/usr/bin/bucketvs/var/run/bvsd.sock | il socket API del pannello (lo usa nginx) |
/usr/bin/bucketvs/var/run/bvsd-cli.sock | il socket del comando bvs, solo root |
<cartella dei dati>/etc/ | impostazioni, account, sessioni, token, i certificati, il nginx.conf generato (segreti con modalità 600) |
<cartella dei dati>/log/ | i log |
<cartella dei dati>/tmp/ | file temporanei di ogni processo |
<cartella dei dati>/home/<utente>/ | la cartella home di ogni account |
<cartella dei dati>/jobs/ | operazioni, job cron e le loro esecuzioni, con i log |
<cartella dei dati>/toolchains/ | la cache dei download, toolchain e runtime installati, esportazioni |
<cartella dei dati>/envs/ | ambienti |
<cartella dei dati>/projects/ | aree di lavoro, visibili come /projects dentro gli ambienti |
<cartella dei dati>/trash/ | elementi eliminati, conservati 7 giorni |
I moduli aggiungono cartelle proprie; le loro sezioni le nominano.