English Polski Deutsch Italiano Nederlands Svenska 日本語 繁體中文 · Markdown

Bucket & Code Server IDE : guide de l’utilisateur

Bucket & Code Server IDE (QPKG bucketvs) conserve du code source et des fichiers sur un NAS QNAP et y compile des logiciels. Il apporte son propre serveur web, ses propres outils et ses propres comptes.

Ce guide décrit le paquet tel qu’il fonctionne sur le NAS.

Sommaire

Ce qui tourne sur le NAS

ÉlémentCe qu’il faitOù il écoute
nginxla seule porte sur le réseau local : sert le panneau et transmet chaque chemin à son module9950 (HTTP), 9951 (HTTPS)
bvsddémarre et surveille tous les autres processus, garde les comptes et les réglages, exécute les tâches et les tâches cron, répond au panneaudeux sockets Unix dans /usr/bin/bucketvs/var/run/
Git (Forgejo)hébergement Git avec une interface webun socket Unix dans /usr/bin/bucketvs/var/run/forgejo/, et 9952 pour Git via SSH
SVN et Bucket (httpd)dépôts Subversion et dossiers WebDAV avec historique127.0.0.1:9961, ou le port libre suivant quand un autre programme l’occupe
Éditeur (code-server)VS Code dans le navigateur, une instance par compteun socket Unix par compte dans /usr/bin/bucketvs/var/run/ide/
CIle runner Forgejo Actionspas de port à lui ; nginx écoute pour lui sur 127.0.0.1:9960 tant que le module est activé, ou sur le port libre suivant quand un autre programme occupe 9960

Le cœur (nginx, bvsd, le panneau, les tâches cron, les toolchains) est toujours actif. Git, CI, SVN et Bucket, et l’Éditeur sont des modules qu’un admin active et désactive. Sur chaque adresse du NAS, les modules répondent sous leurs chemins : /git/, /svn/, /bucket/, /ide/. Le panneau est à /, et ce guide à /guide/.

Tant que le paquet tourne, ses programmes sont dans /usr/bin/bucketvs/bin. Tout ce que le paquet conserve (comptes, réglages, dépôts, environnements, journaux) se trouve dans un seul dossier sur un volume de données : le dossier de données.

Installer le paquet

Le paquet demande QTS 6.0 ou QuTS hero 6.0 ou plus récent, sur un NAS x86_64 ou ARM 64 bits ; il existe un paquet par architecture (bucketvs_<version>_x86_64.qpkg, bucketvs_<version>_arm_64.qpkg). Il est signé : installez-le depuis l’App Center (un dépôt qui le propose, ou Installer manuellement avec le fichier téléchargé). L’App Center vérifie la signature ; il n’est pas nécessaire d’autoriser les applications sans signature valide.

L’installation crée l’utilisateur de service bucketvs (pour Forgejo et httpd), le lien /usr/bin/bucketvs vers le dossier d’installation, et démarre bvsd. Les journaux système indiquent le dossier de données.

Où commence le dossier de données

Au premier démarrage, le dossier de données est BucketVS sur le volume où le paquet est installé, par exemple /share/CACHEDEV1_DATA/BucketVS (QTS) ou /share/ZFS2_DATA/BucketVS (QuTS hero). Elle peut ensuite être déplacée sur un autre volume depuis le panneau (Déplacer le dossier de données).

Le paquet retient son dossier de données dans /etc/config/bucketvs-data-root, un fichier qui survit au paquet. Supprimer le paquet laisse en place le dossier de données et ce fichier, si bien qu’une installation après une suppression repart sur les mêmes données et les mêmes comptes. Un démarrage ne dépend jamais d’un dossier absent. Quand le dossier de données a disparu (supprimé, sur un disque remplacé, ou sur un volume hors ligne à ce moment), le démarrage crée BucketVS sur le volume du paquet, un nouveau dossier sauf si un dossier de ce nom s’y trouve déjà, et dans un nouveau dossier la première connexion définit le mot de passe de l’administrateur. Cela vaut après une réinstallation comme pour un paquet installé, au démarrage du NAS aussi. Les journaux système contiennent un avertissement à ce sujet, et des fichiers .prev gardent l’ancien chemin : /etc/config/bucketvs-data-root.prev et, pour un paquet installé, aussi etc/data-root.prev dans le dossier d’installation. Si l’ancien dossier était sur un volume qui n’était que hors ligne à ce moment, remettez le volume en ligne, arrêtez le paquet, copiez ce fichier par-dessus etc/data-root dans le dossier d’installation (par exemple /share/CACHEDEV1_DATA/.qpkg/bucketvs/etc/data-root) et démarrez le paquet : il tourne de nouveau sur les anciennes données.

Ouvrir le panneau depuis l’App Center

Ouvrir sur le paquet dans l’App Center ouvre le panneau sur le port 9950 (HTTP) ou 9951 (HTTPS). Quand les ports sont changés dans le panneau (Ports), le paquet communique les nouveaux à l’App Center à son démarrage suivant.

Démarrage automatique depuis une session SSH

Tant que l’interrupteur du paquet est activé dans l’App Center, le NAS lance le paquet à son démarrage. Dans une session SSH sur le NAS, en admin, le script de service règle le même interrupteur :

/etc/init.d/bucketvs.sh disable   # le prochain démarrage est refusé, y compris celui du NAS
/etc/init.d/bucketvs.sh enable    # le paquet démarre de nouveau avec le NAS

Chacune de ces commandes n’écrit que l’interrupteur (Enable dans /etc/config/qpkg.conf), affiche ce qu’elle a réglé et écrit la même ligne dans les journaux système. Un paquet en marche continue de tourner après disable, et enable ne démarre rien : c’est le rôle de stop et start, et start refuse tant que le paquet est désactivé. status indique si bvsd tourne.

Première connexion

Ouvrez le panneau à https://<adresse du NAS>:9951/ ou http://<adresse du NAS>:9950/. L’adresse HTTPS utilise d’abord un certificat auto-signé, donc le navigateur affiche un avertissement tant que l’appareil ne lui fait pas confiance ; la section Le certificat montre comment comparer son empreinte.

Une nouvelle installation n’a aucun compte. Tant que le premier administrateur n’a pas de mot de passe, le panneau s’ouvre sur un seul écran, « Définir le mot de passe administrateur », pour le compte administrator. Saisissez un mot de passe deux fois : au moins 10 caractères et au plus 72 octets. L’enregistrer crée le compte et vous connecte.

Le paquet démarre sans aucun compte; Définir le mot de passe administrateur 60 minutes, réseau local seulement; administrator connecté; Redémarrer le paquet dans l’App Center : une nouvelle fenêtre de 60 minutes

Depuis une session SSH sur le NAS, /usr/bin/bucketvs/bin/bvs user password administrator crée le compte s’il n’existe pas encore et affiche un mot de passe aléatoire ; le panneau demande alors votre propre mot de passe à la première connexion (Quand un admin est bloqué).

Après la première connexion, la Vue d’ensemble indique que seul le cœur tourne. La tuile de chaque module dit ce qu’il apporte et propose un bouton qui l’active, par exemple Activer Git : activez ceux dont vous avez besoin (Modules).

Travailler dans le panneau

Le panneau fonctionne comme un éditeur de code : chaque page s’ouvre dans un onglet, et une palette de commandes atteint les pages et les actions par leur nom.

Comptes

Le panneau a ses propres comptes. Les comptes QTS ne s’y connectent pas.

Rôles

RôleCe qu’il peut faire
viewerlit le panneau ; les pages Sauvegardes, Stockage, Utilisateurs et Journaux sont réservées aux admins. Dans Forgejo, il ne crée, ne forke et n’importe aucun dépôt, ne crée aucune organisation et ne pousse jamais ; il lit les dépôts SVN et les buckets sur lesquels il a des droits et n’écrit dans aucun
memberlit ce que lit un viewer, et écrit : il pousse vers les dépôts Git où il reçoit l’accès en écriture, écrit dans les dépôts SVN et les buckets où il a lecture et écriture, et y restaure d’anciennes versions de fichiers. Dans Forgejo, il ne crée, ne forke et n’importe aucun dépôt et ne crée aucune organisation, et il ne peut pas pousser vers un dépôt qu’un compte de rôle inférieur à developer possède ou administre, ni, tant que le module CI est activé, vers un dépôt dont les Actions sont activées. Il n’a ni éditeur, ni tâches cron, ni compilations
developerouvre en plus l’éditeur, lit les lignes bvs use des toolchains installées, crée, modifie et lance ses propres tâches cron, crée et compile des apps, publie des paquets dans le dépôt (un admin les liste), vérifie des modules du noyau, et crée des dépôts Git dont les workflows s’exécutent sur le NAS tant que le module CI est activé
admintout : comptes, réglages, stockage, réseau, modules, toolchains, environnements, toutes les tâches cron, activation des apps, chargement des modules du noyau, liste des paquets dans le dépôt

Le rôle developer est root sur le NAS : ses commandes cron s’exécutent en root, tout comme le terminal de son éditeur et, tant que le module CI est activé, les workflows des dépôts où il peut pousser. Ne le donnez qu’aux personnes à qui vous donneriez le mot de passe admin du NAS. Pour quelqu’un qui ne fait qu’écrire dans des dépôts, le rôle member suffit.

Sous Votre compte, chacun voit son propre rôle et ce qu’il permet, avec un lien vers cette section. Une page au-dessus du rôle d’une personne indique le rôle qu’elle nécessite, et ce que seul un admin modifie est signalé comme tel là où il apparaît. Réseau, Git et CI montrent leurs réglages aux autres comme des valeurs, avec « Non défini » là où une valeur manque.

Les workflows s’exécutent en root sur le NAS, donc bvsd garde les Actions désactivées dans chaque dépôt Git qu’un member ou un viewer possède ou dans lequel un tel compte peut écrire : donner à un tel compte l’accès en écriture à un dépôt désactive ses Actions en moins d’une minute, et la page Git liste ces dépôts pour les admins. Pour utiliser les Actions dans l’un d’eux, retirez d’abord cet accès en écriture dans Forgejo, ou transférez un dépôt qu’un tel compte possède au compte d’un developer.

Créer et modifier des comptes

Un admin gère les comptes sur la page Utilisateurs.

Mots de passe et sessions

Mots de passe erronés

Derrière un proxy, l’adresse comptée est celle que le proxy indique, mais seulement quand le proxy est un proxy de confiance. Sinon, chaque client compte comme l’adresse du proxy lui-même, et cinq mauvais mots de passe de n’importe qui bloquent tout le monde pendant 15 minutes.

Authentification à deux facteurs

Chaque compte l’active pour lui-même sous Votre compte : scannez le code QR avec une application d’authentification (ou saisissez la clé), puis entrez le code à 6 chiffres que l’application affiche. Ensuite, la connexion demande un code après le mot de passe.

Jetons d’API

Les scripts et la CI utilisent des jetons d’API au lieu d’un mot de passe. Sous Votre compte, « Nouveau jeton » en crée un :

Quand un admin est bloqué

L’admin du NAS peut réinitialiser n’importe quel compte depuis une session SSH sur le NAS. La commande bvs parle à bvsd par un socket que seul root peut ouvrir (/usr/bin/bucketvs/var/run/bvsd-cli.sock, mode 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

Chaque requête sur ce socket agit en tant qu’admin intégré cli et est écrite dans log/audit.log dans le dossier de données. bvsd doit tourner pour ces commandes.

Le dossier de données

Le dossier de données est le dossier qui contient tout ce que le paquet conserve. Son chemin est l’unique ligne de /usr/bin/bucketvs/etc/data-root. La page Stockage l’affiche, avec le volume où elle se trouve et l’espace libre sur celui-ci.

bvsd ne démarre que sur un dossier de données qui est un dossier sur un vrai volume. Le démarrage du paquet le vérifie avant : un dossier absent, ou un dossier sur tmpfs ou ramfs, donne un nouveau dossier de données sur le volume d’installation, comme le décrit Où commence le dossier de données. Un volume hors ligne laisse son point de montage sous forme de dossier vide dans la RAM du NAS, et les réglages écrits là disparaîtraient au redémarrage suivant. bvsd lui-même ne refuse un tel dossier que s’il est lancé à la main, et la raison est alors écrite dans les journaux système de QTS.

Ce que bvsd donne à chaque processus

QTS garde /tmp dans un petit disque RAM et /root sur un disque RAM qu’un redémarrage vide. Chaque processus que bvsd démarre (programmes des modules, tâches cron, installations) reçoit donc ses fichiers temporaires et son dossier personnel dans le dossier de données :

VariableValeur
HOME<dossier de données>/home/<utilisateur>
TMPDIR<dossier de données>/tmp
XDG_CACHE_HOME, XDG_CONFIG_HOME.cache et .config dans ce dossier personnel
npm_config_cache.npm dans ce dossier personnel
PATH~/.local/bin, ~/.npm-global/bin, puis bin, sbin et node/bin du paquet, puis les dossiers du système
SSL_CERT_FILE, GIT_SSL_CAINFO, CURL_CA_BUNDLEle paquet de certificats CA du paquet, /usr/bin/bucketvs/etc/ssl/cacert.pem
TZle fuseau horaire du NAS, tel que réglé dans QTS
SHELL, EDITORbash et nano du paquet
LANG, LESSCHARSETC.UTF-8 et utf-8, pour que les noms de fichiers avec des lettres accentuées s’affichent tels quels

Déplacer le dossier de données

La page Stockage déplace tout le dossier de données vers un autre dossier sous /share. Choisissez un dossier partagé ou un volume ; les données vont dans un nouveau dossier nommé BucketVS à l’intérieur. Pour utiliser un dossier lui-même, ouvrez un dossier vide nommé BucketVS. Les dossiers partagés se créent dans QTS (Panneau de configuration, Dossiers partagés) ; à l’intérieur d’un dossier partagé ou d’un volume, la page peut créer un nouveau dossier. Le sélecteur s’ouvre là où se trouvent les données et l’indique ; ouvrez de là le dossier partagé ou le volume où elles doivent aller.

La page vérifie la cible avant que le déplacement commence et liste chaque raison pour laquelle elle en refuse une :

Vérifier de nouveau la cible espace libre : les données + 10 %; Arrêter les modules le panneau reste actif; Copier avec rsync -aHAX --numeric-ids; Vérifier la copie fichiers, octets, propriétaires, modes, dates, sha256 de jusqu’à 1000 fichiers; Basculer le dossier de données dans /usr/bin/bucketvs/etc/data-root; bvsd redémarre sur la nouvelle racine et démarre les modules; L’ancienne copie reste, marquée MOVED-TO, jusqu’à ce que vous la supprimiez; L’ancienne racine reste utilisée, les modules redémarrent

Pendant le déplacement :

Après la bascule, bvsd s’arrête et redémarre sur la nouvelle racine, donc le panneau disparaît quelques secondes.

Quand le déplacement échoue, l’ancien dossier de données reste utilisé et les modules redémarrent. L’erreur de la tâche dit ce qui a échoué et ce qu’est devenue la copie :

L’ancienne copie et les copies restantes

Après un déplacement réussi, l’ancien dossier de données reste où il était, avec un fichier nommé MOVED-TO à l’intérieur. Rien ne l’utilise. « Supprimer l’ancienne copie » sur la page Stockage la supprime, et « Supprimer cette copie » supprime une copie restante d’un déplacement échoué. Les deux suppressions restent sur un seul système de fichiers et ne suivent jamais un lien. Un dossier qui est un point de montage ou le dossier propre d’un dossier partagé est vidé et conservé.

Réseau

La page Réseau regroupe les ports, le mode HTTP simple, les noms d’hôte des modules, les proxys de confiance, l’URL publique et le certificat. L’enregistrement redémarre ce dont la modification a besoin et le liste.

Ports

RéglagePar défautCe que c’est
HTTPS9951le panneau et les modules via TLS
HTTP9950le panneau et les modules en HTTP simple
Git via SSH9952Git via SSH
Port SSH dans les URL de clonage0le port affiché dans les adresses de clonage SSH ; 0 signifie le port SSH ci-dessus. Réglez-le quand un routeur redirige un autre port vers le NAS.
Hôte SSH dans les URL de clonagevidele nom ou l’adresse affiché dans les adresses de clonage SSH. Vide signifie le nom d’hôte Git, sinon l’hôte de l’URL publique, sinon l’adresse LAN du NAS ; pour un nom publié par le Cloudflare Tunnel, l’adresse LAN et le port de Git via SSH. Réglez-le sur un nom uniquement DNS ou sur l’adresse du routeur quand le routeur redirige le port SSH.

Les ports vont de 1024 à 65535 et diffèrent les uns des autres. Les ports des modules sur 127.0.0.1 (9960 et 9961) sont refusés, tout comme le port qu’utilise httpd ou le serveur du runner CI quand un autre programme a pris 9960 ou 9961 (le message le nomme). Quand l’enregistrement laisse nginx sur ses anciens ports parce qu’il n’a pas pu utiliser un nouveau, une notification en donne la raison. nginx écoute aussi en IPv6 quand le NAS l’a.

HTTP simple

La page de connexion avertit quand elle est arrivée en HTTP simple : le mot de passe traverse alors le réseau en clair.

Le certificat

Au premier démarrage, bvsd crée un certificat auto-signé (ECDSA P-256) pour :

Il est valide 825 jours, le maximum qu’acceptent les appareils Apple, même pour un certificat approuvé à la main. bvsd le vérifie au démarrage et une fois par jour, et en crée un nouveau quand il reste 30 jours ou moins, quand l’ensemble des noms change, ou quand sa clé ne correspond pas. Un nouveau certificat envoie une notification. La page Réseau affiche ses noms, sa validité et son empreinte SHA-256 : comparez l’empreinte avant qu’un appareil lui fasse confiance.

« Ajouter votre propre certificat » prend une chaîne de certificats et sa clé privée au format PEM :

La paire est stockée dans etc/tls/ dans le dossier de données avec le mode 600. Quand un certificat téléversé expire ou ne passe plus ces vérifications, nginx sert à la place le certificat auto-signé et une notification en donne la raison. Un certificat téléversé à qui il reste 30 jours ou moins envoie aussi une notification. « Nouveau certificat auto-signé » crée une nouvelle paire auto-signée et revient à celle-ci.

Les clients qui passent par un proxy voient le certificat du proxy, pas celui-ci.

Télécharger le certificat sur la page Réseau enregistre le certificat que sert le panneau, sans sa clé, sous le nom <nom>.crt. Ajoutez-le aux certificats de confiance d’un appareil pour que ses navigateurs fassent confiance au panneau ; les vues des extensions de l’éditeur en ont besoin (Extensions). Il faut faire de nouveau confiance à un nouveau certificat autosigné.

Proxys de confiance

Une liste d’adresses IP ou de plages CIDR, comme 192.168.1.5, l’adresse du proxy placé devant le NAS. Seulement pour une requête dont la connexion TCP vient de l’une d’elles, nginx prend :

Une requête venant de toute autre adresse compte comme venant directement de son client, et nginx remplace ses en-têtes X-Forwarded-* par ses propres valeurs. Une plage rend fiable chaque hôte qu’elle contient : chacun peut alors définir l’adresse du client et le schéma, donc indiquez l’adresse propre du proxy. Une plage de toutes les adresses (0.0.0.0/0, ::/0) est refusée.

URL publique

L’adresse seule, comme https://git.example.com, sans chemin. Les sections des modules indiquent quels liens commencent par elle.

Derrière un proxy inverse (Plesk)

La configuration habituelle place TLS sur un proxy avec un certificat public et le laisse parler en HTTP simple au port 9950 sur le réseau local. Les exemples ci-dessous utilisent bvs.example.com pour le nom public, 192.168.1.20 pour le NAS et 192.168.1.5 pour le serveur Plesk ; mettez les vôtres à leur place.

Navigateur, git, client WebDAV; nginx de Plesk bvs.example.com certificat public; nginx sur le NAS 192.168.1.20; / panneau, /api/ bvsd; /git/, /svn/, /bucket/, /ide/; git via SSH

Sur le NAS

  1. Sur la page Réseau, ajoutez l’adresse du serveur Plesk (telle que le NAS la voit) aux proxys de confiance.
  2. Le HTTP simple peut rester sur « Servir ». « Rediriger vers HTTPS » fonctionne aussi une fois que le serveur Plesk est un proxy de confiance.

Dans Plesk

Placez ces directives dans les paramètres Apache et nginx du domaine, dans le champ « Directives nginx supplémentaires » (dans l’interface anglaise, « 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’éditeur et son terminal
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;

    # gros push et téléversements : pas de limite de taille, en flux, une heure de silence permise
    client_max_body_size 0;
    proxy_request_buffering off;
    proxy_buffering off;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
}

location ~ ^/ est une location à expression régulière. nginx préfère une expression régulière qui correspond à un simple location / (Plesk en écrit un à lui), donc ce bloc sert chaque chemin du site, et proxy_pass sans chemin transmet le chemin de la requête sans le changer. Sur la même page de paramètres, désactivez « Servir les fichiers statiques directement par nginx » : s’il est activé, Plesk répond aux requêtes de fichiers .js, .css et images depuis le dossier du domaine, et le panneau ne se charge pas.

Dans les paramètres d’hébergement du domaine, activez la redirection permanente 301 de HTTP vers HTTPS adaptée au référencement (dans l’interface anglaise, « Permanent SEO-safe 301 redirect from HTTP to HTTPS »). Les directives nginx supplémentaires s’appliquent aussi au site du domaine en HTTP simple sur le port 80 ; sans la redirection, le site y répond aussi, et les mots de passe traversent Internet sans chiffrement.

Pourquoi chaque ligne compte :

DirectiveCe qui ne marche pas sans elle
Host $http_hostnginx sur le NAS choisit le bloc serveur d’après Host, donc un nom d’hôte de module ne correspond jamais. bvsd compare l’Origin de la page avec Host, port compris, donc chaque modification dans le panneau échoue avec 403 csrf ; $host supprimerait un port public autre que 443 et échouerait de la même façon.
X-Forwarded-Forchaque client compte comme le serveur Plesk : cinq mauvais mots de passe d’une seule personne bloquent tout le monde pendant 15 minutes
X-Forwarded-Proto $schemele cookie de session n’est pas marqué Secure, et en mode « Rediriger vers HTTPS » chaque requête est envoyée au port 9951 du nom public
Upgrade, Connectionla page de l’éditeur s’ouvre mais l’éditeur et son terminal ne se connectent jamais
client_max_body_size 0, proxy_request_buffering off, les délaisla limite de taille et les délais propres du proxy s’appliquent aux gros push et téléversements

X-Forwarded-For et X-Forwarded-Proto ne comptent que si le serveur Plesk figure parmi les proxys de confiance. Sinon, nginx sur le NAS les ignore.

Git via SSH

Un proxy HTTP ne transporte pas SSH. Git via SSH va directement au port 9952 du NAS, ou passe par une redirection de port TCP sur le routeur. « Port SSH dans les URL de clonage » sur la page Réseau définit le port qu’affichent les adresses de clonage, et « Hôte SSH dans les URL de clonage » le nom ou l’adresse, quand le nom public n’atteint que le proxy.

Vérifier la configuration

Noms d’hôte des modules

Un module peut avoir son propre nom d’hôte (page Réseau, Noms d’hôte). nginx sert alors ce module seul à la racine du nom. Le nom doit pointer vers le NAS, ou vers le proxy placé devant lui. Sur un proxy, chaque nom d’hôte a besoin de son propre site, avec les mêmes directives que ci-dessus.

ModuleÀ la racine de son nom d’hôteAussi présent
GitForgejo/git/ sur tout autre nom répond 302 vers le nom d’hôte Git, avec le même chemin, la même requête et le même port
Éditeurcode-serverla page de connexion du panneau et /api/, pour qu’un utilisateur puisse se connecter sur ce nom
SVN et Buckethttpdles dépôts restent à /svn/<nom> et les buckets à /bucket/<nom>

Un module désactivé répond 503 avec une phrase qui le dit, sur ses chemins et sur son nom d’hôte.

Une seule connexion pour tous les noms d’hôte

Le cookie de session appartient au nom sur lequel il a été posé, sauf si le réglage network.cookie_domain désigne un domaine parent de tous les noms d’hôte des modules. Avec example.com, une connexion sur bvs.example.com atteint aussi git.example.com et ide.example.com. bvsd refuse un suffixe public (com, com.pl, co.uk, myqnapcloud.com), un domaine qui n’est pas parent de tous les noms d’hôte des modules, et tout domaine tant qu’aucun nom d’hôte de module n’est défini. Chaque site sous ce domaine reçoit le cookie, donc choisissez le parent commun le plus étroit.

La page Réseau n’affiche pas ce réglage. L’admin du NAS le définit par le socket CLI avec le curl du paquet :

/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

Une valeur vide ("") garde de nouveau le cookie sur chaque nom.

Publier sur Internet (Cloudflare Tunnel)

La page Publication (Administration, admins seulement) met le paquet sur Internet sous des noms d’un domaine dont le DNS est chez Cloudflare. cloudflared, que le paquet fournit, établit la connexion du NAS vers Cloudflare : aucun port du routeur n’est ouvert, et Cloudflare détient les certificats des noms. Chaque requête passe par le nginx du paquet : le panneau et son API exigent une connexion, et seul ce que vous avez rendu public (dépôts publics, leur vue web, le dépôt de paquets) s’ouvre sans compte.

Il existe deux types de noms, un de chaque au plus :

TypeExempleCe qu’il sert
Nom d’hôte principalcode.example.comle panneau et son API, Forgejo à /git/, la vue web à /svn-web/ et /bucket-web/, le dépôt de paquets à /repo/ (en lecture seule) et le guide. /svn/ et /bucket/ y répondent 404, et /ide/ aussi tant que vous ne publiez pas l’éditeur (plus bas)
Nom d’hôte des paquetsqpkg.example.comseulement GET et HEAD de /repo/, pour l’App Center d’autres NAS ; tout le reste répond 404

Ce dont le jeton a besoin

Créez un jeton d’API sur dash.cloudflare.com (My Profile, API Tokens) avec ces permissions, pour la zone des noms :

Le paquet garde le jeton sur le NAS dans un fichier que seul root lit, et ne l’affiche plus jamais.

Si le jeton a un Client IP Address Filtering, mettez-y les deux adresses publiques du NAS, IPv4 et IPv6 : le NAS appelle Cloudflare en IPv6 quand il a une adresse IPv6. Sinon la page Publication refuse avec token_ip_filter et donne l’adresse que Cloudflare a vue.

Publier

Saisissez les noms et le jeton, puis Publier. Le paquet vérifie d’abord tout chez Cloudflare et n’y change rien quand une vérification échoue ; le message dit quoi corriger :

Ensuite il crée le tunnel (nommé bucketvs-<nom du NAS> sauf si vous donnez un nom ; un tunnel de ce nom que Cloudflare garde est repris), fait pointer chaque nom vers lui par un enregistrement CNAME proxifié, ajoute les règles de cache et démarre cloudflared. Publier à nouveau avec les mêmes valeurs ne change rien. Réglez l’URL publique (Réseau) sur l’adresse https:// du nom d’hôte principal, pour que les liens et les adresses de clonage HTTPS de Forgejo le nomment ; la page vous le rappelle tant qu’elles diffèrent.

Git via SSH ne passe pas par le tunnel : Cloudflare ne transporte que du HTTP vers un nom publié. L’adresse de clonage SSH est donc l’adresse LAN du NAS avec son port de Git via SSH (9952), dans le panneau et dans la zone de clonage de Forgejo, et la page Git et la Vue d’ensemble disent « Le clonage via SSH fonctionne sur le réseau local ; depuis Internet, clonez via HTTPS. » Pour SSH depuis Internet, redirigez le port SSH sur le routeur et réglez Hôte SSH dans les URL de clonage (Réseau) sur l’adresse publique du routeur ou sur un nom uniquement DNS qui pointe vers elle, avec Port SSH dans les URL de clonage quand le routeur utilise un autre port.

Le nom d’hôte principal répond 404 à /ide/ tant qu’un admin n’active pas Publier l’éditeur sur le nom d’hôte principal sur la page Publication. Le terminal de l’éditeur est un shell root sur le NAS, et quiconque s’y connecte depuis Internet comme développeur ou admin l’obtient : activez donc d’abord l’authentification à deux facteurs pour ces comptes. Interrupteur activé, l’éditeur passe par la même connexion que sur le réseau local, son proxy de ports (/ide/proxy/<port>/) y reste désactivé et Cloudflare ne garde jamais ses pages en cache. Tant qu’il est activé, la Vue d’ensemble affiche Éditeur sur Internet.

Tant que le module CI est actif, un workflow poussé dans n’importe quel dépôt de ce Forgejo s’exécute en root sur le NAS par le runner du NAS lui-même, qu’il ait été poussé depuis Internet ou depuis le réseau local : le même pouvoir que le terminal de l’éditeur. La page Publication le dit sous Ce qu’Internet atteint. N’accordez l’accès en push qu’aux personnes à qui vous donneriez le mot de passe admin du NAS.

Le cache

Avec Préréglages de cache activé, Cloudflare garde les paquets (*.qpkg) un an, les icônes un jour, repo.xml 5 minutes et les fichiers du panneau un an ; il ne garde jamais l’API, les pages de Forgejo, les pages de connexion ni la vue web. Une publication dans le dépôt de paquets retire aussitôt repo.xml (et une icône modifiée ou les fichiers d’une version supprimée) du cache de Cloudflare. Le paquet ajoute ses propres règles à la fin des règles de cache de la zone et ne modifie jamais les autres.

Connexion depuis Internet

Le premier mot de passe ne peut jamais être défini par un nom publié : la configuration initiale n’accepte qu’un client local. Les mauvais mots de passe comptent par client Internet, comme sur le réseau local. Un mot de passe envoyé à Forgejo avec git compte aussi ; un jeton d’accès Forgejo fonctionne comme toujours. Cloudflare accepte des requêtes jusqu’à 100 Mo, donc un push ou un envoi plus gros passe par l’adresse du réseau local.

Arrêter et retirer

Arrêter met fin à cloudflared ; les noms affichent alors la page d’erreur de Cloudflare, et rien ne change chez Cloudflare. Retirer de Cloudflare supprime les enregistrements DNS, les règles de cache et le tunnel que le paquet a créés (un tunnel repris reste) et oublie le jeton. Tant que des noms sont publiés, la Vue d’ensemble affiche une étiquette Internet avec l’état du tunnel.

Modules

La Vue d’ensemble affiche chaque module avec ses processus, sa mémoire et son CPU, et l’active ou le désactive (admin seulement). Un module désactivé dit ce qu’il apporte ; un admin l’active avec son bouton (Activer Git, Activer Éditeur, etc.) sur sa tuile, sur sa propre page ou, pour l’Éditeur, dans l’onglet Éditeur.

ÉtatSignification
en courschaque processus du module tourne
démarrageun processus a démarré il y a moins d’une seconde
dégradéun processus attend d’être redémarré, les fichiers du module n’ont pas pu être écrits, ou son contrôle de santé échoue
redémarre en boucleun processus s’est arrêté 5 fois en 10 minutes ; bvsd le redémarre toutes les 15 minutes, et une notification est partie
arrêtéles processus du module ne tournent pas (un déplacement des données les a arrêtés, ou ils n’ont pas pu démarrer)
désactivéle module est désactivé

Un processus qui s’arrête est redémarré après 1 seconde, puis 2, 4 et ainsi de suite jusqu’à 60 secondes. Après 10 minutes de fonctionnement, l’attente repart de 1 seconde. Un processus qui redémarre en boucle repart aussitôt quand son module est désactivé puis réactivé.

Git

Le module Git fait tourner Forgejo, une interface web pour les dépôts git avec tickets, demandes d’ajout (pull requests), versions, wikis, LFS, miroirs et webhooks. Un admin l’active avec Activer Git dans la Vue d’ensemble ou sur la page Git. La tâche prépare les dossiers et la base de données de Forgejo dans <données>/forgejo, ajoute chaque compte du panneau à Forgejo, et le démarre. Forgejo s’ouvre ensuite à /git/ sur l’adresse du panneau, ou à / du nom d’hôte Git quand il en existe un (voir Noms d’hôte des modules).

Nouveau dépôt sur la page Git, et sur la tuile Git de la Vue d’ensemble tant qu’il n’y en a aucun, ouvre le formulaire de Forgejo pour créer un dépôt. Le panneau le propose, ainsi que Migrer ou mettre en miroir un dépôt, à partir du rôle developer : Forgejo ne laisse un viewer ou un member créer aucun dépôt.

Dépôts et comptes

Cloner en HTTPS et en SSH

Sur la page Git, Cloner un dépôt écrit les deux commandes pour un propriétaire et un dépôt :

VoieAdresseConnexion
HTTPS (ou HTTP)https://<adresse du NAS>:9951/git/<propriétaire>/<dépôt>.gitle nom d’utilisateur et le mot de passe du panneau, ou un jeton d’accès
SSHssh://git@<adresse du NAS>:9952/<propriétaire>/<dépôt>.gitune clé SSH ajoutée dans Forgejo sous Paramètres, Clés SSH / GPG

Montrer des dépôts aux personnes sans compte

Navigation publique sur la page Git permet à quiconque atteint Forgejo de lire ses dépôts publics sans compte. Dans Forgejo, chaque dépôt est public ou privé (ses Paramètres, Visibilité). Interrupteur activé, un visiteur sans compte peut :

Un dépôt privé reste caché : son adresse répond « introuvable ». Tant que l’interrupteur est activé, Forgejo ne liste en outre aucun compte (l’onglet Utilisateurs d’Explorer et la recherche d’utilisateurs sont désactivés, y compris pour les utilisateurs connectés), si bien qu’un visiteur ne peut pas collecter les noms de comptes. Pousser, les tickets, les demandes d’ajout et les paramètres demandent toujours un compte. Interrupteur désactivé, chaque page demande d’abord au visiteur de se connecter.

Pour partager un dépôt, rendez-le public dans Forgejo, activez Navigation publique et envoyez l’adresse. Sur un nom d’hôte Git, l’adresse est https://<nom d’hôte Git>/<propriétaire>/<dépôt>.

Nouveau projet

Nouveau projet est une page qui mène un projet, étape par étape, de rien à une première version compilée et publiée. Elle s’ouvre dans son propre onglet depuis la palette de commandes (Ctrl+Maj+P, Nouveau projet), le haut de la barre latérale de l’Éditeur, l’en-tête de la barre latérale Git, la page Git et la page Projets ; un exemple de Projets de l’éditeur sur la page Exemples a Créer un projet à partir de cet exemple. Elle demande le rôle développeur, les modules Git et Éditeur, et votre compte dans Forgejo (la page Git montre sa synchronisation). Tant que Git ou l’Éditeur est désactivé, la page le dit au-dessus des étapes, et un admin les active là d’un seul bouton.

  1. Modèle. Les modèles sont groupés : Programmes (C, C++ avec CMake, Go, Rust, Node, Python, Java), Paquets pour QTS (un paquet QPKG, une app App Builder, un paquet depuis les sources), Noyau (un module noyau, le pilote USB-série ch341), Sites web (un site statique : des pages dans src/, un Makefile qui compile public/, une vérification des liens en make test) et Exemples. Chaque carte dit ce qu’une compilation produit et signale ce qui manque encore à ce NAS (QDK, un environnement de compilation, un module désactivé), avec un lien vers la page qui l’ajoute.
  2. Nom et visibilité. Le nom nomme le dépôt et le dossier projects/<nom> ; la page le vérifie pendant la saisie. Puis le propriétaire (votre compte, ou une organisation où Forgejo vous laisse créer des dépôts), privé ou public, et une description si vous le souhaitez. Pour une app App Builder, le préréglage dont elle part et la cible.
  3. Service, pour un paquet QPKG et un paquet depuis les sources : la façon dont le paquet démarre et s'arrête, construite à partir de blocs. Choisissez un préréglage (Outil en ligne de commande lie le programme dans /usr/bin ; Service en arrière-plan ajoute un compte, un dossier de données sur le volume, le programme lancé sous ce compte, une attente de son port et un arrêt avec délai ; Application web ajoute le bouton Ouvrir d'App Center ; Vide n'a que les verbes), puis modifiez ses blocs. La carte de chaque bloc montre les lignes qu'il écrit dans le script pendant que vous tapez, et une valeur refusée est signalée sous son champ. Le démarrage n'active jamais l'Enable d'App Center, et l'arrêt n'y touche jamais. La vue Projet modifie les blocs plus tard.
  4. Compilation. L’environnement où le projet se compile, gardé pour le projet (la vue Projet le change ensuite), ou aucun, et bvsd en choisit un à chaque compilation. L’étape propose d’abord celui que bvsd choisirait lui-même, où compilent bvs qbuild et la CI : le Ubuntu 24.04 builder, sinon le Debian 12 builder, sinon un autre environnement Debian ou Ubuntu. Quand le Makefile du modèle donne à chaque app son environnement sur une ligne ENV, l’étape le dit et n’en demande aucun, et le projet n’en garde aucun. Pour un paquet depuis les sources, l’étape dit aussi que l’adresse de la source et le sha256 de la recette de départ sont provisoires : la première compilation échoue tant que la recette ne donne pas la vraie source de votre programme et le sha256 de ce fichier. La page montre le workflow que la CI lance à chaque push. Compiler juste après la création reste activé tant que vous ne le désactivez pas ; pour un paquet depuis les sources, il est d’abord désactivé, et vous pouvez l’activer. S’il n’y a aucun environnement Debian ou Ubuntu pour le NAS, l’étape le dit : un admin y crée l’environnement de compilation avec Créer cet environnement, puis l’étape le propose ; sinon, désactivez Compiler juste après la création et compilez le projet plus tard.
  5. Publication, pour un paquet QPKG, une app App Builder ou un site web : Déploiement de test sur ce NAS (admin, paquets signés seulement ; pour une app, Activer sur ce NAS), Publier dans le dépôt App Center de ce NAS et Publier sur mon serveur web (admin) vers l’une des cibles web ; Ajouter une destination en enregistre une nouvelle. Chacune est facultative. Le choix de publication devient aussi l’interrupteur Publier dans le dépôt App Center du projet (vue Projet, Réglages) : tant qu’il est activé, la CI du projet y publie à chaque exécution.
  6. Vérification liste chaque réponse et les étapes qui vont s’exécuter. Créer le projet les envoie.
  7. Progression suit la tâche de chaque étape : le dépôt et son premier commit, la première compilation, puis le déploiement de test, la publication dans App Center et la publication web, l’une après l’autre. Une ligne montre son état et la fin de son journal ; un clic montre le journal. Une étape en échec dit pourquoi et propose Réessayer, et les étapes suivantes attendent. À la fin, Ouvrir le projet, Ouvrir dans l’éditeur et Ouvrir dans Forgejo. Recharger la page ou revenir à son onglet relit les tâches et n’envoie aucune étape deux fois. Quitter la page arrête la chaîne ; la vue Projet a les mêmes étapes.

Quand bvsd refuse le projet (un nom pris par un dossier, une app ou un dépôt, un propriétaire où vous ne pouvez pas créer), la page revient à l’étape qui porte cette réponse, montre la raison sous son champ et garde toutes les autres réponses. Un module désactivé (un admin l’active depuis la page), l’absence de compte Forgejo et l’absence d’environnement Debian ou Ubuntu pour une app App Builder sont expliqués dans Vérification.

Ce que fait la première tâche :

Le workflow s’exécute sur le runner du NAS à chaque push une fois le module CI activé, dans l’environnement que nomme le workflow. Le workflow QPKG publie le paquet dans le dépôt de paquets, qui n’accepte que des paquets signés. Si le premier commit ou son push échoue après la création du dépôt, la tâche supprime le dossier, supprime à nouveau le dépôt et dit pourquoi. Tant que l’interrupteur Publier dans le dépôt App Center du projet est désactivé, bvs repo publish dans le workflow affiche un avis au lieu de publier, et l’exécution continue.

La vue Projet

Chaque dossier de projects/ dans le dossier de données a sa propre page : un projet de l’assistant, la copie d’un exemple de la catégorie Projets de l’éditeur ou un dépôt que vous y avez cloné. Elle s’ouvre depuis la branche Projets de la barre latérale de l’Éditeur, depuis la page Projets, avec Ouvrir le projet à la fin de Nouveau projet, et depuis la palette de commandes (Ouvrir le projet …, ou Ctrl+P et son nom). Elle demande le rôle développeur. Le menu d’un projet sur la page Projets a aussi Compiler, Recompiler, Publier et la publication vers les cibles web. Le même menu active ou désactive la publication par la CI dans App Center.

La page lit le dossier et n’y change rien d’elle-même. Elle déduit le type du projet de ses fichiers : une app App Builder du nom du dossier, un qpkg.cfg en haut (un paquet QPKG), un Makefile en haut, ou rien de cela, quand le workflow CI du projet le compile. Quand une app App Builder porte le nom du dossier, un projet avec un qpkg.cfg en haut, ou avec un Makefile et un qpkg.cfg dans qpkg/, garde sa propre compilation, et Déploiement de test et Publier prennent toujours son QPKG.

La bande du haut contient les étapes. Une étape qui ne peut pas s’exécuter garde son bouton, désactivé, et dit pourquoi à côté et sous la bande. Une étape que le projet ne peut pas prendre du tout quitte la bande, et une phrase en dessous dit ce que fait le projet et où va le résultat de la compilation : le dossier du projet pour un programme, la page Noyaux pour un module noyau, la page de chaque app pour un Makefile qui ne compile que des apps App Builder.

Un projet Makefile choisit une cible à côté de Compiler (la cible par défaut de make, sa première, sauf si vous en choisissez une autre) ; un projet CMake se compile, ou se compile et lance ses tests. Un projet de module noyau se compile dans l’espace de travail de l’atelier noyau pour le noyau en cours, et cette compilation revient à un admin. Une étape en cours a Annuler, et la tâche s’arrête le plus souvent aussitôt. Lancer le workflow lance à la main le workflow CI du projet quand il a un déclencheur workflow_dispatch ; sinon le bouton est désactivé et la page dit pourquoi. Le workflow de chaque modèle a ce déclencheur. Installé sur ce NAS liste les paquets que les déploiements de test du projet ont installés, avec Supprimer de ce NAS pour un admin. Supprimer le projet, dans le menu à côté des boutons de l’en-tête ou dans le menu du projet sur la page Projets, est pour un admin ou pour le développeur dont le compte Forgejo contient le dépôt. Vous tapez d’abord le nom du projet ; le dossier part, et le dépôt Forgejo, une app App Builder de ce nom et les paquets installés restent. La page donne ensuite le lien vers le dépôt.

Réglages contient ce que bvsd garde pour le projet hors de son dossier. Pour un projet Makefile, CMake ou QPKG, il montre l’environnement où s’exécutent Compiler et Recompiler, et le change. Pour un Makefile qui ne fait que créer et compiler des apps App Builder, il liste chaque app avec l’environnement que nomme sa ligne du Makefile. Un projet qui fait un paquet, ou dont le workflow lance bvs repo publish, y a l’interrupteur Publier dans le dépôt App Center : activé, bvs repo publish dans la CI du projet ajoute ses paquets au dépôt ; désactivé, l’exécution CI saute cette étape avec un avis. Un projet sans choix gardé (la copie d’un exemple, un clone) l’a activé. Git montre la branche, son avance ou son retard sur le distant tels que le dernier fetch les a laissés (la page ne fait jamais de fetch), le dernier commit et les chemins modifiés. Fichiers liste un dossier à la fois ; choisissez un fichier pour le lire, un .qpkg se télécharge. L’édition reste dans l’éditeur, et le dossier .git est laissé de côté.

Recettes, pour un projet doté de son propre dossier recipes/, liste les recettes que prennent ses apps : chacune avec sa version, la version de la bibliothèque qu’elle remplace quand elle porte le nom d’une recette de la bibliothèque, et en dessous ce que la vérification des recettes a trouvé, avec le fichier et la ligne. Une recette que bvsd laisse de côté a une ligne avec la raison ; au-delà de trois laissées de côté de la même façon, une ligne compte le reste. Ce que la vérification a trouvé sur le dossier recipes dans son ensemble a sa propre ligne. Un clic ouvre le dossier de la recette dans l’éditeur ; le menu copie aussi la commande qui lance la même vérification dans un terminal du NAS : bvs recipe lint avec le dossier du projet. La carte apparaît aussi quand le recipes du projet est un lien, un fichier, un dossier que bvsd ne peut pas lire ou un dossier qui ne contient que des liens, et dit pourquoi aucune recette n’en est lue.

Service et paquet (un paquet QPKG, ou un projet Makefile dont le paquet est dans qpkg/, comme un paquet depuis les sources) contient le script de démarrage et d'arrêt du paquet sous forme de blocs, les champs de son qpkg.cfg (Paquet) et les fichiers écrits à partir d'eux (Script). Enregistrer montre les différences de chaque fichier, puis en fait un commit dans le dépôt du projet ; si le projet a changé entre-temps, planifiez à nouveau. Modifier à la main désactive les blocs, et vous modifiez le script dans l'éditeur ; Rattacher les blocs montre ce qu'une nouvelle écriture remplacerait. Mettre à jour la bibliothèque apporte au paquet le bvs-qpkg.sh de ce Bucket & Code Server IDE, avec ses différences. Un projet créé avant les blocs propose Utiliser des blocs pour ce script.

Versions liste ce vers quoi le projet peut passer, et Passer à cette version le fait :

VersionCe que fait le passage
Un .qpkg dans build/, ou un export de l’App Builderun déploiement de test de ce fichier (admin)
La compilation de l’App Builderl’active (admin) ; l’App Builder garde une compilation
Une version du dépôt de paquetsen fait la version listée (admin)
Un tag gitsort le tag dans le dossier

Un clic choisit une version ; son menu la déploie aussi en test, la publie, la publie vers une cible web ou télécharge un .qpkg. Un tag est sorti en HEAD détaché, et Revenir à main dans la carte Git revient à la branche. Le passage est refusé tant que le dossier a des modifications non commitées ; le message les liste, et vous les commitez ou les mettez de côté dans l’éditeur d’abord. Cochez deux versions et Comparer les deux liste les fichiers que l’une a et l’autre n’a pas, et les fichiers modifiés. Deux tags, ou deux paquets, sont comparés par contenu ; un paquet et un commit seulement par taille. Sur la page Paquets, un admin installe aussi une version du dépôt sur ce NAS (Installer sur ce NAS), avec les contrôles du déploiement de test.

Votre propre serveur web (cibles web)

Une cible web est l’endroit où un admin publie un paquet ou un site web sur son propre serveur web : un dossier de ce NAS (le partage Web de QTS, que sert le Web Server de QTS, ou un autre dossier partagé) ou un distant rclone (SFTP, FTP, WebDAV, S3, configuré dans le rclone.conf des sauvegardes), avec l’adresse publique qui le sert. Elles sont sur la page Publication, sous Cibles web : Ajouter une destination, Modifier, Supprimer et Tester, qui y copie un petit fichier, le récupère par l’adresse publique et le supprime ensuite.

Une cible dossier est un dossier à elle dans un partage (/share/Web/monsite, jamais un partage entier ni un volume), hors du dossier de données, car une publication de site retire de la cible ce que le site ne contient plus. L’adresse commence par http:// ou https:// et ne contient ni utilisateur ni mot de passe.

Chaque publication relit le fichier par l’adresse publique : le .qpkg d’un paquet avec son .sha256, comparé par sha256, ou l’index.html d’un site, comparé octet par octet. Quand l’adresse ne sert pas ce qui a été copié, la tâche échoue avec web_check: et les deux valeurs.

Runners CI

Le module CI fait tourner Forgejo Actions : un fichier de workflow dans .forgejo/workflows/ d’un dépôt s’exécute sur un runner quand quelque chose est poussé. Il a besoin du module Git. Un admin l’active sous Modules, CI, Activer. La tâche enregistre le runner propre du NAS auprès de Forgejo, redémarre Forgejo avec Actions activé et démarre le runner ; elle se termine quand le runner a atteint Forgejo.

Le runner du NAS

Runners externes

Une machine de compilation ailleurs (un serveur, une VM) peut aussi prendre des tâches de ce Forgejo. Sur la page CI, sous Enregistrer un runner externe, un admin lui donne un nom et obtient les commandes pour Linux x86_64 et aarch64. Elles téléchargent forgejo-runner 13.2.0 depuis code.forgejo.org, vérifient son sha256, gardent le jeton du runner dans runner-token (lisible par son propriétaire seulement) et démarrent le runner avec l’étiquette linux-amd64 (ou linux-arm64). Le runner apparaît aussitôt dans la liste, hors ligne jusqu’à ce que les commandes s’exécutent. Le jeton n’est affiché qu’à ce moment-là. Un tel runner exécute ses tâches sur sa propre machine, en tant que l’utilisateur qui l’a démarré, et atteint Forgejo à son adresse publique.

SVN et Bucket

Le module SVN et Bucket sert les dépôts Subversion à /svn/<nom> et les buckets à /bucket/<nom>. Un bucket est un lecteur réseau (WebDAV) dans lequel chaque fichier enregistré devient une révision, si bien que toute version antérieure d’un fichier peut être lue ou remise en place. Un admin active le module sous Modules ; la page SVN & Bucket crée, liste et supprime ensuite les deux types.

Dépôts SVN

svn checkout "https://<adresse du NAS>:9951/svn/<nom>"
svn commit -m "…"

La page affiche la commande de checkout avec l’adresse du dépôt. Derrière un proxy, l’adresse suit l’URL publique, et avec un nom d’hôte SVN elle est /svn/<nom> sur ce nom. L’Historique d’un dépôt liste ses révisions ; un fichier peut être lu à n’importe quelle révision, comparé avec une autre, et remis en place comme nouvelle révision (Restaurer cette version, pour les comptes en lecture et écriture).

Buckets

Clients WebDAV et leurs limites

ClientComment se connecterRemarques
Finder de macOSAller, Se connecter au serveur, https://<adresse du NAS>:9951/bucket/<nom>le Finder verrouille un fichier pendant qu’il l’écrit ; le bucket répond aux verrous WebDAV
rcloneun remote webdav avec vendor = other et l’adresse du bucketadapté aux copies par script
davfs2 (Linux)mount -t davfs https://<adresse du NAS>:9951/bucket/<nom> /mnt/<dossier>le nom d’utilisateur du panneau et le mot de passe ou le mot de passe d’application
Cyberduck, WinSCPune connexion WebDAV (HTTPS) au port 9951, chemin /bucket/<nom>
curlcurl -T fichier -u <utilisateur> https://<adresse du NAS>:9951/bucket/<nom>/fichierun envoi, une révision (ou deux, voir plus haut)
Explorateur WindowsConnecter un lecteur réseaule WebClient de Windows n’envoie un mot de passe qu’en HTTPS avec un certificat auquel Windows fait confiance : placez le bucket derrière un proxy avec un vrai certificat (Derrière un proxy inverse) ; le certificat auto-signé ne suffit pas

Montrer un dépôt ou un bucket aux personnes sans compte

Un admin peut rendre public un dépôt SVN ou un bucket avec l’interrupteur de sa ligne sur la page SVN & Bucket (Sur le web). Toute personne qui a l’adresse peut alors le lire dans un navigateur, sans compte :

AdresseCe qu’elle affiche
https://<adresse du NAS>:9951/svn-web/<nom>/un dépôt SVN
https://<adresse du NAS>:9951/bucket-web/<nom>/un bucket

Le lien Voir sur le web de la ligne ouvre cette page. Elle liste les fichiers et dossiers à la révision la plus récente ou à une plus ancienne, affiche un fichier texte avec les numéros de ligne (jusqu’à 1 Mio) ou une image, et propose chaque fichier au téléchargement. L’Historique liste les révisions avec leurs auteurs, messages et fichiers modifiés. La page d’une révision affiche le diff de chaque fichier qu’elle a modifié (jusqu’à 20 fichiers d’au plus 1 Mio ; les autres sont des liens) ; n’importe quel fichier peut être comparé entre deux révisions.

Éditeur et outils d’IA

Le module Éditeur fait tourner VS Code dans le navigateur (code-server) pour chaque compte developer et admin. Un admin l’active sous Modules. Chaque compte reçoit sa propre instance, démarrée quand le compte ouvre l’éditeur et arrêtée après un temps sans trafic.

Le terminal de l’éditeur est un shell root sur le NAS. Sous QTS, les processus du paquet tournent en tant qu’admin (uid 0), sauf Forgejo et httpd. Ne donnez le rôle developer qu’aux personnes à qui vous donneriez le mot de passe admin du NAS.

Ouvrir l’éditeur

L’éditeur ne répond qu’à ses propres pages. Un WebSocket, un formulaire ou la requête d’un script qu’une autre page envoie avec la session du compte, depuis un autre site ou depuis un autre port du NAS, reçoit 403 et ne démarre aucune instance ; une autre page n’atteint donc pas non plus un serveur de développement derrière la vue Ports.

Extensions

Claude Code, Gemini CLI et Codex CLI

Sous Outils IA en ligne de commande sur la page Réglages de l’éditeur, chaque compte installe, met à jour et supprime ces outils pour lui-même :

OutilInstallé avecCommande
Claude Codel’installeur d’Anthropic (claude.ai/install.sh), npm s’il échoueclaude
Gemini CLInpm install -g @google/gemini-cligemini
Codex CLInpm install -g @openai/codexcodex

Coder avec un assistant d’IA

Chaque projet créé par Nouveau projet contient un skill pour les assistants IA : .claude/skills/qnap-dev/ et un AGENTS.md qui y renvoie. Le skill, en anglais, réunit les consignes pour tout ce qui concerne un NAS QNAP : ce qu’il est dans le shell (une racine sur disque RAM, BusyBox, pas de systemd, pas de gestionnaire de paquets, getcfg et setcfg), le stockage et les chemins, comment construire, signer et publier avec ce paquet (bvs env run, bvs ldd, bvs qbuild, l’App Builder, l’atelier du noyau, le dépôt de paquets), les ports, les sauvegardes et ce qu’il ne doit pas suggérer, comme apt sur le NAS ou autoriser les apps non signées dans App Center. Il dit clairement que la signature avec un jeton matériel n’est ni prise en charge ni testée.

Toolchains et environnements

La page Toolchains télécharge ce qu’il faut pour compiler des logiciels sur le NAS :

TypeCe que c’estExemples
Système de fichiers racineun système Linux à décompresser dans un environnementDebian 12 et 13, Ubuntu 22.04 et 24.04, Alpine 3.22
Toolchain croiséeun compilateur qui compile pour un autre processeurtoolchains Bootlin pour aarch64, x86-64 et armv7, avec glibc ou musl
Runtimeun langage ou un outil de compilationPython, Go, Node.js, Zig, Rust, CMake, Ninja, Java (JDK)
QNAPles outils propres de QNAPQDK 2.5.0, pour bvs qbuild et Exporter en QPKG
Sources du noyauune arborescence du noyau Linux pour l’atelier du noyauLinux 6.6.129 de kernel.org ; la publication GPL du noyau de QNAP pour QTS 5.2.3

Les entrées pour un autre processeur sont masquées ; « Afficher les entrées pour d’autres processeurs » les liste, mais elles ne peuvent pas être installées. Les toolchains Bootlin tournent sur x86_64, donc un NAS ARM n’a pas de toolchain croisée.

Le catalogue

Le paquet contient un catalogue intégré. Le catalogue distant signé à https://pub.qnaputilities.com/bucketvs/catalog.json peut ajouter des entrées sans nouveau paquet. bvsd ne l’utilise que si sa signature ed25519 correspond à la clé intégrée au paquet et qu’il n’est pas plus ancien que le catalogue en usage. « Actualiser le catalogue » le récupère aussitôt, et la tâche cron intégrée « Actualisation du catalogue des toolchains » le récupère chaque jour à 04:15.

Installer et supprimer

Installer est l’affaire d’un admin, affichée avec sa progression sur la page Tâches :

  1. L’archive est téléchargée dans toolchains/cache/ dans le dossier de données. Un téléchargement interrompu reprend quand l’installation est relancée.
  2. Son sha256 est vérifié par rapport au catalogue. Une différence supprime le fichier.
  3. Une toolchain croisée ou un runtime est décompressé dans toolchains/<kind>/<id> et son archive supprimée. Un système de fichiers racine ou des sources du noyau restent sous forme d’archive ; chaque environnement ou espace de travail du noyau décompresse sa propre copie. QNAP publie sa publication GPL du noyau en deux parties : les deux sont téléchargées, chacune vérifiée par son propre sha256, puis réunies.

Un volume plein fait échouer l’installation avec « no space left on » et le point de montage du volume.

« Supprimer » efface une entrée installée. Les environnements créés à partir d’un système de fichiers racine sont des copies et restent.

Utiliser une toolchain ou un runtime

bvs use <id> affiche les lignes export (comme PATH) qui rendent utilisable dans un shell une toolchain croisée ou un runtime installé :

eval "$(bvs use bootlin-aarch64-glibc-stable)"

La page Toolchains affiche les mêmes lignes sous « bvs use » pour chaque entrée installée.

Environnements

Un environnement est un système Linux décompressé à partir d’un système de fichiers racine dans envs/<nom> dans la dossier de données. Il est modifiable : apt install build-essential fonctionne dans un environnement Debian ou Ubuntu, et ce que vous installez y reste.

À l’intérieur d’un environnement :

La même chose depuis un shell (les exemples appellent bvs par son nom, comme peuvent le faire une tâche cron et une session SSH sur le NAS tant que le paquet tourne) :

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 et bvs env run démarrent dans le dossier d’où vous les lancez. Un dossier sous projects/ de la dossier de données est le même dossier sous /projects dans l’environnement. Tout autre dossier (le checkout d’une tâche CI, un dossier d’un partage) est monté sur /work et la commande y démarre. Depuis /, elles démarrent dans /projects.

Compiler un QPKG avec bvs qbuild

bvs qbuild compile un QPKG à partir du dossier où vous le lancez (un dossier avec qpkg.cfg, comme celui que crée le modèle QPKG de Nouveau projet). Il exécute le qbuild de QNAP dans un environnement Debian ou Ubuntu. qbuild appelle des programmes système par leur chemin complet, et dans l’environnement ces chemins mènent aux programmes de l’environnement au lieu de ceux du NAS. Le paquet arrive dans build/ du dossier.

bvs tc install qdk-2.5.0-x86_64      # une fois ; qdk-2.5.0-aarch64 sur un NAS ARM
cd /share/CACHEDEV1_DATA/BucketVS/projects/MyTool
bvs qbuild                           # --env <nom> choisit l’environnement

Il utilise l’environnement ubuntu2404-builder (l’exemple « Ubuntu 24.04 builder »), sinon debian12-builder, sinon un autre environnement Debian ou Ubuntu, et y a besoin de rsync. Quand il manque quelque chose, il s’arrête et nomme la commande qui l’ajoute, par exemple bvs env run ubuntu2404-builder -- apt-get install -y rsync. Les arguments après bvs qbuild vont à qbuild. Avant que qbuild ne démarre, bvs qbuild indique quel cas de signature de code s’applique au dossier.

Un environnement a ses propres fichiers et outils. Tout ce qu’il contient tourne en root, voit chaque processus du NAS et utilise le réseau du NAS.

Signer le code d’un QPKG

App Center vérifie la signature de code d’un paquet à son installation. Pour signer, il faut un certificat de signature de code que QNAP vous a délivré. bvs qbuild nomme l’un des trois cas sur sa première ligne, par exemple bvs: code signing, case 1 (a certificate as files): … :

CasLe dossier contientCe qui se passe
1, un certificat sous forme de fichierscertificate et private_key, éventuellement ca_certs (la chaîne)qbuild signe le paquet avec openssl ; l’environnement a besoin d’openssl et de bsdextrautils
2, un certificat sur un jeton matérielcertificate_hsmni pris en charge ni testé : bvs qbuild s’arrête avant de construire quoi que ce soit
3, pas de certificataucun de ces fichiersle paquet est construit sans signature

App Builder

L’App Builder compile des programmes choisis dans un seul dossier, le préfixe de l’app (par défaut /usr/app/my_app_prefix), à l’intérieur d’un environnement.

L’onglet Exemples d’Apps contient des apps prêtes à l’emploi, des environnements, des workflows CI, des tâches cron et des Projets de l’éditeur. Voir le code sur une carte montre ce que l’exemple crée avant de l’utiliser, pour tout rôle : les fichiers d’un projet de l’éditeur, le fichier du workflow, la commande de la tâche cron, ou pour une app ses recettes dans l’ordre de build avec le build.sh et le recipe.json de chacune. La vue est en lecture seule et affiche les fichiers texte ; un environnement n’a pas de fichier, sa carte n’a donc pas ce bouton. Utiliser un exemple demande le rôle developer, et un environnement le rôle admin : la carte d’un environnement n’offre pas Utiliser cet exemple à un developer.

Recettes

Chaque programme est compilé à partir d’une recette. Une recette nomme sa source avec un sha256, les recettes dont elle dépend, les outils de compilation dont l’environnement a besoin, et une vérification qui prouve que le résultat fonctionne (comme bin/bash --version). Il existe des recettes pour des bibliothèques (zlib, openssl, ncurses, readline et d’autres), des shells (bash, zsh, busybox), des outils (coreutils, curl, git, jq, rsync, tmux, htop, nano et d’autres), des serveurs (nginx, redis, openssh, dropbear) et un langage (lua).

Mises à jour des recettes

Les recettes nouvelles et mises à jour arrivent aussi sous forme de catalogue signé depuis pub.qnaputilities.com, et atteignent ainsi le NAS avant la prochaine version de Bucket & Code Server IDE. bvsd cherche un catalogue plus récent une fois par jour. Il ne l’utilise que si sa signature correspond à la clé intégrée à bvsd, que chaque fichier correspond à la liste du catalogue et que ses recettes sont plus récentes que celles livrées avec le paquet ; un catalogue qui échoue à un contrôle n’est jamais utilisé. Tant qu’un catalogue est utilisé, Nouvelle app marque les recettes qu’il apporte comme nouvelle dans le catalogue ou mise à jour par le catalogue.

La carte Bibliothèque de recettes de la page Apps indique la bibliothèque qu’utilisent les builds (Bibliothèque du paquet avec la version du paquet, ou Catalogue avec la version du catalogue) et le dernier contrôle avec son résultat. Un admin y trouve deux boutons ; le second apparaît tant qu’un catalogue est utilisé :

Après un changement, une recompilation réutilise chaque recette dont les fichiers n’ont pas changé. Avant chaque build, bvsd contrôle de nouveau les fichiers du catalogue. Si l’un d’eux a changé sur le NAS, le build s’arrête avant que rien ne s’exécute, et les builds utilisent le catalogue précédent ou la bibliothèque du paquet.

Compiler une app

Apps, Nouvelle app (rôle developer) demande un nom, le préfixe (/usr/app/<nom> sauf si vous en choisissez un autre), l’environnement dans lequel l’app se compile (un environnement Debian ou Ubuntu ; la galerie d’exemples crée le « Ubuntu 24.04 builder », que la page choisit en premier), la cible (l’architecture de ce NAS, ou aarch64 ou armv7 en compilation croisée), les modèles de NAS où elle fonctionne, le mode de liaison et les recettes. Les recettes dont elles dépendent sont ajoutées dans l’ordre de compilation.

Une app peut aussi prendre les recettes d’un projet qui a son propre dossier recipes/. Choisissez ce projet dans Recettes d’un projet, à l’étape Paquets. Ses recettes viennent en tête de liste, sous le nom du projet et marquées projet, puis viennent celles de la bibliothèque. Une recette du projet qui porte le nom d’une recette de la bibliothèque la remplace dans cette app et indique quelle version de la bibliothèque elle remplace. Une recette que le projet laisse de côté est nommée avec la raison. Une recette choisie qui manque à la liste du projet est nommée sous la liste déroulante et laissée hors de l’app ; elle revient quand vous choisissez une liste qui l’a. La page de l’app nomme le projet, et un développeur ouvre la vue Projet depuis ce nom. Un viewer voit les recettes du dernier build de l’app dans l’ordre où son journal les nomme, chacune avec son état et son journal ; avant le premier build, il n’y a pas d’ordre à montrer.

Chaque mode de liaison est une carte, avec une image de l’endroit où les programmes trouvent leurs bibliothèques, ce que le mode coûte en taille, en mises à jour et en lieux où l’app tourne, et quelles recettes le permettent. Avant que vous choisissiez des recettes, les cartes comptent toute la bibliothèque de recettes ; quand vous revenez à la première étape, elles comptent les recettes de votre compilation. Pour une app statique, vous choisissez ce qui arrive aux recettes qui ne peuvent pas être liées statiquement : les compiler en bundle, ou les laisser de côté.

Une compilation Qt exécute les outils de Qt lui-même (moc, rcc, et lrelease de Linguist pour les traductions). Dans une compilation croisée, les recettes Qt (qtbase, qttools) compilent donc d’abord ces outils pour ce NAS, dans host/ sous le préfixe, puis Qt pour la cible ; les recettes compilées sur Qt exécutent les outils depuis cet endroit. Rien sur la cible n’exécute host/. Il fait partie de la compilation de l’app, donc l’archive et Exporter en QPKG l’emportent aussi.

Vos propres recettes

Quand la bibliothèque de recettes n’a pas de recette pour un programme, un projet peut avoir la sienne. Les recettes vont dans le dossier recipes/ du projet, au format de la bibliothèque, et seules les apps qui nomment le projet les compilent. Un paquet se fait ainsi en cinq étapes :

  1. Créer le projet. Dans Nouveau projet, le modèle Package from source (paquet depuis les sources) crée un dossier avec une recette de départ qui porte le nom du projet, un Makefile pour deux apps (une pour le processeur de ce NAS, une pour aarch64, en compilation croisée sur un NAS x86_64) et le script de démarrage et d’arrêt du paquet issu de l’étape Service.
  2. Écrire la recette. New recipe dans l’éditeur ajoute une autre recette à partir de la même recette de départ (Ouvrir l’éditeur). Mettez dans recipe.json la vraie adresse de la source du programme et son sha256 (curl -fsSL <adresse> | sha256sum dans le terminal de l’éditeur affiche la somme), et ses étapes de compilation dans build.sh. Le dossier d’une recette contient recipe.json, build.sh et le fichier vendor que nomme recipe.json, rien d’autre ; un correctif va donc dans build.sh sous forme de here-document.
  3. La vérifier. Chaque enregistrement d’un fichier de recette vérifie les recettes du projet et liste les résultats dans la vue Problems ; make lint dans le terminal et la carte Recettes de la vue Projet donnent les mêmes résultats. La vérification lit recipe.json et analyse build.sh avec bash -n. Elle n’exécute jamais la recette.
  4. Compiler. Compiler dans la vue Projet crée les deux apps quand elles manquent, puis les compile l’une après l’autre. Un build lit les recettes du projet une fois, à son début ; un fichier enregistré ensuite attend le build suivant. Une recette du projet qui porte le nom d’une recette de la bibliothèque la remplace dans les apps de ce projet seulement, et le journal du build le dit.
  5. Empaqueter et installer. make qpkg dans le terminal de l’éditeur met le dernier build réussi de chaque app dans le paquet, avec le QDK des Toolchains, et laisse de côté une app qui n’en a pas. Avec les fichiers de signature du code dans qpkg/ à côté de qpkg.cfg, ou dans un dossier nommé par QPKG_CERT_DIR, le paquet est signé (Signer le code d’un QPKG), et Déploiement de test dans la vue Projet (admin) l’installe sur ce NAS.

Quelques règles s’appliquent aux recettes d’un projet :

Sur quels modèles de NAS une app fonctionne

Un programme compilé contre la glibc ne démarre que sur un NAS dont la glibc est au moins aussi récente que la version la plus récente que le programme demande. Le paquet compte sur une glibc 2.39 ou plus récente sur tous les NAS où il fonctionne (QTS 6.0, QuTS hero 6.0 et suivants) : c’est son plancher glibc. 2.39 est la glibc d’Ubuntu 24.04 et de QuTS hero 6.0.1, lue dans le propre /lib/libc.so.6 de ce firmware ; QNAP ne publie aucune version de glibc, et ses notes de version ne citent aucun QTS 6.0. Les NAS de test sous QTS 6.1.0 et QuTS hero 6.1.0 ont 2.43.

Fonctionne sur, dans la nouvelle app et dans Modifier, choisit l’un des deux :

Une compilation croisée (aarch64 ou armv7) est toujours pour tous les NAS. La nouvelle app avertit quand la glibc de l’environnement choisi dépasse ce que l’app autorise. Après chaque compilation, bvsd lit la version de glibc que demande chaque programme et chaque bibliothèque, y compris pour une compilation croisée. Un fichier au-dessus de la limite fait échouer la compilation, et les solutions sont nommées : un autre environnement (Choisir un autre environnement), le mode de liaison static ou Construire pour ce NAS seulement. La page de l’app indique quelle glibc exige sa compilation réussie la plus récente, et l’onglet Dépendances liste chaque fichier au-dessus de la limite.

Sur le NAS, bvs tree-deps <préfixe> --tree <dossier> --glibc-max 2.39 fait la même vérification sur n’importe quelle arborescence d’app.

Activer une app sur le NAS

Activer (admin) fait du préfixe un lien vers la compilation réussie la plus récente de l’app, donc ses programmes tournent sur le NAS depuis /usr/app/<nom>/bin. L’activation ne remplace jamais rien qu’elle n’a pas créé : un dossier, un fichier ou un autre lien à l’emplacement du préfixe est refusé avec la raison. Le disque système de QTS est reconstruit à chaque démarrage, donc le paquet recrée les liens à chacun de ses démarrages. Désactiver (admin) supprime le lien ; supprimer l’app la désactive d’abord et la déplace dans la corbeille pour 7 jours. Un developer ne peut supprimer une app que tant qu’elle n’est pas active. Une app compilée pour une autre architecture ne peut pas être activée ici ; téléchargez son archive pour un NAS de ce type.

Exporter une app

Exporter en QPKG (admin) emballe la compilation réussie la plus récente dans un QPKG à part, qui installe l’app sur un autre NAS sans ce paquet. Il refuse une app compilée pour ce NAS seulement, et s’arrête avant l’emballage quand un programme de la compilation exige une glibc au-dessus de 2.39 (voir Sur quels modèles de NAS une app fonctionne). Il faut QDK : installez « QNAP QDK 2.5.0 » sur la page Toolchains, onglet QNAP. Tant que QDK n’est pas installé, le bouton n’apparaît pas et la page de l’app indique où l’obtenir. L’export exécute qbuild dans l’environnement de l’app, de la même façon que bvs qbuild. Chaque compilation y installe rsync ; pour une app compilée la dernière fois avec une version plus ancienne du paquet, le refus nomme la commande qui l’ajoute. Le paquet exporté crée le lien de son préfixe au démarrage et le supprime à l’arrêt. Il n’est pas signé : le journal de la tâche indique le cas 3, tout comme une ligne sous le bouton. Dans une session SSH, /etc/init.d/<nom>.sh disable et enable règlent l’interrupteur du paquet exporté dans l’App Center et laissent le lien du préfixe tel quel. À chaque démarrage, le paquet exporté ajoute aussi une ligne à /etc/profile et à /root/.profile, qui met bin et sbin de l’app dans le PATH d’une connexion SSH, après les commandes propres du NAS, pour admin et pour tout autre compte autorisé à se connecter ; une suppression retire cette ligne.

Dépôt de paquets

Le paquet tient un dépôt App Center : les paquets QPKG qui y sont publiés peuvent être installés sur d’autres NAS depuis l’App Center, comme les apps de n’importe quel dépôt.

Atelier du noyau

L’atelier du noyau compile des modules pour le noyau que le NAS exécute, vérifie chacun par rapport à ce noyau, et le charge. QNAP n’a pas publié les sources de ses noyaux actuels (ses publications GPL s’arrêtent à QTS 5.2.3), donc l’atelier lit ce que le noyau en cours montre de lui-même et configure une arborescence du noyau pour lui correspondre.

Ce qu’il faut

Le profil

bvs kernel profile montre ce qu’est le noyau en cours : sa version (6.6.129-qnap), le compilateur avec lequel QNAP l’a compilé, le vermagic des modules propres de QNAP, la taille de struct module dans ceux-ci et l’emplacement de init et exit, si les modules doivent être signés, et les réglages qu’une arborescence du noyau reçoit pour lui correspondre.

L’espace de travail

bvs kernel prepare crée l’espace de travail du noyau en cours dans kernels/<release> du dossier des données :

  1. Il prend les sources du noyau que le catalogue a pour cette version (bvs kernel sources) : l’arborescence GPL propre de QNAP quand QNAP en a publié une, sinon l’arborescence de kernel.org, à laquelle manquent les modifications propres de QNAP. --source en choisit une autre.
  2. Il configure l’arborescence : avec la configuration de QNAP pour ce modèle quand l’arborescence est celle de QNAP, sinon avec les réglages du profil. --option NAME=m ajoute un réglage, par exemple un pilote.
  3. Il prépare l’arborescence pour la compilation de modules (--full compile plutôt le noyau entier, ce qui prend bien plus longtemps et permet à la vérification de voir les symboles exportés du noyau).
  4. Il vérifie que l’arborescence compile exactement pour la version du noyau en cours.

Il s’exécute comme une tâche sur la page Tâches. Un prepare échoué garde l’arborescence du précédent.

Compiler un module

Les modules qu’une compilation produit sont gardés dans kernels/<release>/modules/. Un module que QNAP fournit pour ce noyau n’est pas gardé : la copie propre de QNAP reste celle qui se charge. bvs kernel make --build-only n’y garde rien : le module reste là où il a été compilé. Les workflows CI des modèles de noyau de Nouveau projet compilent ainsi.

La vérification et le chargement

bvs kernel check <module> compare un module au noyau en cours : le vermagic, la taille de struct module et l’emplacement de init et exit dans celle-ci (par rapport aux modules propres de QNAP), si une signature est exigée, les modules dont il dépend, et chaque symbole dont il a besoin. Chaque constat dit ce qui ne correspond pas et quoi faire. Le code de sortie 3 signifie que le module ne doit pas être chargé.

bvs kernel load <module> refait la vérification et charge le module, en chargeant d’abord les modules dont il dépend (ceux de QNAP depuis le NAS, ou les vôtres). Un module avec une erreur à la vérification n’est jamais chargé. bvs kernel unload <module> le retire ; un module en cours d’utilisation reste chargé. Chaque chargement et déchargement est écrit dans log/kernel-modules.log.

Le noyau de QNAP ne liste pas ses symboles de données, donc la vérification ne peut pas rechercher des symboles comme jiffies ; elle les nomme en avertissements. Si l’un d’eux manque, le noyau refuse le module au chargement.

Modules dans une app

Une app peut nommer des modules de l’espace de travail. Activer l’app les charge avant que son lien soit créé, et chaque démarrage du paquet les charge de nouveau une fois le panneau disponible ; la page Noyaux affiche un chargement encore en cours. La désactiver les décharge d’abord ; un module en cours d’utilisation garde l’app active.

Après une mise à jour de QTS vers un autre noyau, les modules doivent être recompilés dans l’espace de travail du nouveau noyau. Il en va de même après une restauration dans un autre dossier de données : kernels/ ne fait pas partie d’une sauvegarde.

Dans le panneau

La page Noyaux affiche le profil du noyau en cours, les sources du noyau du catalogue, l’espace de travail et ses modules. Un admin y prépare l’espace de travail (une source, l’environnement, des réglages supplémentaires, le noyau entier ou non) et compile des modules depuis un dossier de projet ou un répertoire de l’arborescence ; les deux s’exécutent comme des tâches. Vérifier (developer) affiche chaque constat avec sa solution ; Charger et Décharger (admin) font ce que font bvs kernel load et unload, et un chargement refusé affiche la vérification qui l’a arrêté. Un fichier .ko n’importe où sous le dossier des données peut être vérifié par son chemin.

Tâches cron et opérations

La page Tâches a deux listes : les tâches planifiées (cron) et les opérations (les longues tâches que bvsd exécute, comme les installations et les déplacements).

Tâches planifiées

Un developer crée et modifie ses propres tâches ; un admin les modifie toutes. Une tâche a :

Chaque tâche garde ses 100 dernières exécutions avec la fin de leur sortie (4 Ko). Le journal complet d’une exécution est gardé 30 jours.

Une tâche s’exécute en root pour le compte de son propriétaire, avec le dossier personnel de celui-ci comme HOME ; elle ne s’exécute donc que tant que son propriétaire est un developer ou un admin actif. Tant que le propriétaire est désactivé ou a le rôle member ou viewer, chacune des heures de la tâche est enregistrée comme une exécution sautée qui dit pourquoi, par exemple « its owner ola is disabled », et Exécuter maintenant répond avec la même raison. Aucune notification n’est envoyée. Une exécution en cours au moment où le propriétaire est désactivé ou reçoit un rôle inférieur à developer est arrêtée. La tâche s’exécute de nouveau dès que le compte est réactivé, ou redevient developer. Supprimer un compte supprime ses tâches. Les tâches intégrées s’exécutent quoi qu’il arrive à un compte.

Quand une commande se termine, les processus qu’elle a lancés en arrière-plan continuent de tourner. En cas de dépassement du délai, de suppression de la tâche ou d’arrêt du paquet, tout le groupe de processus de l’exécution reçoit SIGTERM, puis SIGKILL après 5 secondes.

Les nuits de changement d’heure, les tâches suivent la règle du cron de Debian. Une tâche avec * au début de son champ des minutes ou des heures (aussi */N), @hourly ou @every suit le temps écoulé : en automne, elle s’exécute lors des deux passages de l’heure répétée, et au printemps l’heure sautée ne vient pas. Toute autre tâche exécute chacune de ses heures une fois : une heure dans l’heure répétée s’exécute une fois, et une heure dans l’heure sautée s’exécute juste après le changement.

Tout compte connecté, un viewer aussi, lit les commandes des tâches et la sortie de leurs exécutions. Ne mettez ni mot de passe ni jeton dans une commande : faites-la les lire dans un fichier sous <data>/etc que seul root lit (chmod 600).

Tâches intégrées

TâcheQuandCe qu’elle fait
Maintenancetous les jours à 03:30supprime de tmp/ dans le dossier de données ce que rien n’a modifié depuis 10 jours ; fait la rotation de log/audit.log au-delà de 10 Mo
Vider la corbeilletous les jours à 03:45supprime ce qui a été déplacé dans trash/ dans le dossier de données il y a plus de 7 jours (comme le dossier personnel d’un compte supprimé)
Actualisation du catalogue des toolchainstous les jours à 04:15récupère le catalogue signé des toolchains
Rotation des journaux de nginxtoutes les heures, à la minute 7renomme nginx-access.log ou nginx-error.log en .1 dès qu’il dépasse 20 Mo (cinq anciens fichiers gardés) et demande à nginx de rouvrir ses journaux

Un admin peut changer la planification, le délai maximal, la règle et la notification d’une tâche intégrée, et la désactiver. Son nom et sa commande restent.

Opérations

Les installations, les tâches d’environnement, les déplacements de données et l’activation d’un module s’exécutent comme des opérations. La liste affiche les 50 dernières, les plus récentes d’abord, avec leur progression et leur journal. Les opérations et leurs journaux sont gardés 30 jours. Une opération qui tournait quand le paquet s’est arrêté apparaît comme interrupted. Un developer annule ses propres opérations ; un admin annule n’importe laquelle.

Sauvegardes

La page Sauvegardes (admin) définit ce qui est sauvegardé, quand, où vont les copies et combien sont gardées. Sauvegarder maintenant lance une sauvegarde à tout moment. Sur une nouvelle installation, les sauvegardes planifiées sont désactivées ; une fois Sauvegardes planifiées activé, une sauvegarde s’exécute tous les jours par défaut (la tâche cron intégrée backup). Elle garde l’exécution la plus récente de chacun des 7 derniers jours, des 4 dernières semaines et des 6 derniers mois, et toujours la dernière exécution réussie. Une seule sauvegarde, vérification, restauration ou suppression s’exécute à la fois.

Deux exécutions le même jour comptent pour un seul jour : quand la plus récente se termine, l’exécution antérieure de ce jour est supprimée. Un Sauvegarder maintenant l’après-midi remplace donc l’exécution planifiée du matin ; copiez d’abord une exécution ailleurs quand l’état de ce matin-là compte.

Ce que contient une sauvegarde

Une exécution est un dossier <données>/backups/<id>/ avec un manifest.json qui liste chaque fichier avec son sha256 :

PartieContenu
réglagesetc/ : réglages, comptes, secrets TOTP, la clé TLS, les clés de sauvegarde
Gitle dump de Forgejo : dépôts, wikis, objets LFS, pièces jointes et sa base de données
SVN, bucketsune copie de chaque dépôt, faite de façon incrémentale : une révision déjà copiée ne l’est pas de nouveau
réglages VS Codeles réglages VS Code de chaque compte, ses raccourcis clavier, ses snippets et la liste de ses extensions (pas les fichiers des extensions : la vue Extensions les réinstalle)
environnementsles environnements des Toolchains (désactivé par défaut : ils peuvent être recréés)
projetschaque dossier de projet avec son historique Git et les fichiers pas encore validés, sans node_modules
dossiers HOMEle dossier HOME de chaque compte, sans les caches ni les installations propres des outils d’IA (leur bouton Installer les remet)
App Builderles réglages de chaque app et l’historique de ses compilations ; une compilation refait les fichiers de l’app
dépôt de paquetsles paquets publiés, leurs icônes et l’index que lit App Center

Ces quatre parties sont dans chaque sauvegarde, quoi que vous cochiez sur la page. Un dossier qui n’a pas changé depuis la sauvegarde précédente est lié à la copie de celle-ci et n’occupe aucune place.

L’exécution ne devient visible que lorsque chaque partie est écrite et vérifiée ; un échec ou un volume plein supprime le dossier inachevé et laisse les exécutions précédentes telles qu’elles étaient. Vérifier relit entièrement une exécution : le sha256 de chaque archive, svnadmin verify de chaque révision, git fsck de chaque dépôt et un contrôle d’intégrité de la base de données de Forgejo.

Destinations

Chaque exécution est copiée vers chaque destination de la page :

Une copie qui quitte le NAS (rsync, rclone) doit être chiffrée : activez Chiffrer les copies qui quittent le NAS et Créer la clé. Les copies sont chiffrées avec age pour sa moitié publique ; la moitié secrète n’est affichée qu’une fois et bvsd ne la garde pas. Sans elle, aucun NAS, celui-ci compris, ne peut restaurer une copie chiffrée : conservez-la loin de ce NAS. Une nouvelle clé chiffre les exécutions à partir de ce moment ; les copies plus anciennes demandent l’ancienne clé secrète.

Une destination qui échoue est nommée dans le résultat de l’exécution ; l’exécution elle-même reste bonne.

rclone.conf contient les identifiants des distants. Avant qu’une copie ou un Test ne l’utilise, bvsd le rend (ainsi que la clé de sauvegarde) lisible par root seul (mode 600) s’il ne l’est pas, et le journal de la tâche le dit.

Restaurer

Restaurer sur une exécution remet en place soit tout, soit un dépôt (un dépôt SVN, un bucket ou un dépôt Git), soit un dossier de projet :

Notifications

bvsd écrit chaque notification dans les journaux système de QTS. Il peut aussi les envoyer à des services de messagerie et de courrier par des URL shoutrrr (Telegram, Discord, Slack, e-mail, un webhook générique et d’autres).

NotificationQuandInterrupteur pour les URL
échec de tâcheune exécution cron d’une tâche avec notification en cas d’échec a échoué ou dépassé le délai ; une opération a échouénotify.on_job_failure
sauvegardele résultat de chaque sauvegarde, vérification et restauration, réussies comprises ; une sauvegarde planifiée qui n’a pas pu démarrernotify.on_backup
boucle de redémarrageun processus a commencé à redémarrer en bouclenotify.on_crashloop
certificatun certificat téléversé a 30 jours ou moins ; nginx est revenu au certificat auto-signé ; un nouveau certificat auto-signé a été créénotify.on_cert_expiry
systèmeréglages refusés au démarrage, un déplacement de données inachevé trouvé, des processus restants arrêtés, la configuration n’a pas pu être écritetoujours envoyée

Les URL et les interrupteurs se trouvent sous Notifications sur la page Système ; les interrupteurs sont activés par défaut. Un admin les modifie là. Les autres comptes voient les interrupteurs et seulement le schéma de chaque URL, car le reste d’une URL contient son jeton. L’admin du NAS peut aussi les définir par le 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

Journaux et paquet de diagnostic

Chaque journal est log/<name>.log dans le dossier de données. Les journaux de bvsd et de chaque processus qu’il surveille subissent une rotation à 20 Mo, et cinq anciens fichiers sont gardés. nginx-access.log et nginx-error.log ont les mêmes limites, vérifiées à chaque démarrage de bvsd et toutes les heures par la tâche « Rotation des journaux de nginx », donc l’un d’eux peut dépasser 20 Mo d’au plus une heure de trafic. La tâche « Maintenance » fait la rotation de audit.log dès qu’il dépasse 10 Mo et garde trois anciens fichiers. La page Journaux (admin) affiche les dernières lignes de n’importe quel journal, les filtre et suit les nouvelles lignes à mesure qu’elles arrivent :

JournalCe qui l’écrit
bvsdbvsd lui-même : démarrages, arrêts, réglages appliqués, problèmes
nginxla sortie propre de nginx
nginx-access, nginx-errorchaque requête, et les erreurs de nginx
auditchaque requête sur le socket CLI
un par processus de modulele programme de chaque module

La page Système affiche la version, la plateforme, le fuseau horaire et chaque processus que bvsd surveille. « Télécharger le paquet de diagnostic » (admin) crée une archive pour un rapport de bug :

Elle ne contient jamais de mots de passe, de sessions, de jetons ni de clés.

Mises à jour

bvsd lit https://pub.qnaputilities.com/bucketvs/latest.json au démarrage et toutes les 24 heures. Quand il nomme une version plus récente, la page Système la nomme, avec le lien que donne le flux. bvsd ne fait que signaler la nouvelle version : il ne télécharge ni n’installe jamais de paquet. Une vérification échouée ne change rien dans le panneau.

Installer une nouvelle version

Installez le nouveau paquet par-dessus l’ancien, depuis l’App Center ou avec Installer manuellement. L’installation arrête bvsd, remplace les fichiers du programme et le redémarre ; le dossier de données, les réglages, les comptes et chaque dépôt restent, tout comme les sessions du panneau. Les instances de l’éditeur s’arrêtent avec bvsd, donc les terminaux ouverts des éditeurs se terminent ; une instance redémarre quand son compte ouvre l’éditeur.

Depuis une version qui utilisait les ports 6050, 6051 et 6052. Les versions précédentes écoutaient sur 6050 (HTTP), 6051 (HTTPS) et 6052 (Git via SSH). Le premier démarrage de la nouvelle version déplace chacun d’eux vers 9950, 9951 et 9952 et le dit dans une notification ; un port que vous avez choisi vous-même reste. Changez ce qui nomme les anciens ports : favoris, un proxy Plesk vers 6050, et les remotes git comme ssh://git@<NAS>:6052/… (git remote set-url).

Supprimer, réinstaller et un paquet endommagé

Votre travail reste quand le paquet est supprimé, réinstallé ou endommagé. Tout ce que vous créez se trouve dans la dossier de données : comptes et réglages, dépôts Git et SVN, buckets, dossiers de projet, dossiers HOME, réglages et extensions de VS Code, apps de l’App Builder, environnements, dépôt de paquets et sauvegardes. Le dossier d’installation (<volume>/.qpkg/bucketvs) ne contient que les programmes et un fichier qui désigne le dossier de données.

Une panne de disque est autre chose : le dossier de données est sur les disques du NAS lui-même. Gardez des sauvegardes sur une autre machine (Sauvegardes) ; chaque sauvegarde contient vos dossiers de projet, vos dossiers HOME, les réglages de l’App Builder et le dépôt de paquets.

La commande bvs

bvs est la ligne de commande du paquet, dans /usr/bin/bucketvs/bin. Elle est dans le PATH de chaque processus que bvsd démarre, tâches cron comprises. Tant que le paquet tourne, /usr/bin/bvs est un lien vers elle, donc une session SSH sur le NAS l’appelle aussi par son nom ; l’arrêt du paquet retire ce lien.

Chaque commande qui parle à bvsd par son socket CLI demande root, car le socket n’appartient qu’à root : user, jobs et, tant que bvsd tourne, tc install, tc remove et env create, clone, export et delete. env shell, env run et qbuild demandent root aussi : elles démarrent bvs-chroot. En tant qu’autre utilisateur, une commande qui a besoin du socket s’arrête avec « 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>

Fichiers et dossiers

CheminContenu
/usr/bin/bucketvsles programmes du paquet (un lien vers son dossier d’installation)
/usr/bin/bucketvs/etc/data-rootle chemin du dossier de données
/usr/bin/bucketvs/var/run/bvsd.sockle socket d’API du panneau (nginx l’utilise)
/usr/bin/bucketvs/var/run/bvsd-cli.sockle socket de la commande bvs, root seulement
<dossier de données>/etc/réglages, comptes, sessions, jetons, les certificats, le nginx.conf généré (secrets avec le mode 600)
<dossier de données>/log/les journaux
<dossier de données>/tmp/fichiers temporaires de chaque processus
<dossier de données>/home/<utilisateur>/le dossier personnel de chaque compte
<dossier de données>/jobs/opérations, tâches cron et leurs exécutions, avec leurs journaux
<dossier de données>/toolchains/le cache de téléchargement, les toolchains et runtimes installés, les exports
<dossier de données>/envs/environnements
<dossier de données>/projects/espaces de travail, visibles en tant que /projects dans les environnements
<dossier de données>/trash/éléments supprimés, gardés 7 jours

Les modules ajoutent leurs propres dossiers ; leurs sections les nomment.