Préparer et compiler
Cloner, compiler et tester
Avant de lire : Préparer votre environnement : la toolchain épinglée, protoc, et un hôte qui passe ses vérifications.
Cette page suppose l’hôte décrit dans Préparer votre environnement : la toolchain
Rust épinglée et protoc. Après elle, vous saurez compiler et installer votre arborescence, exécuter
chaque gate de CI localement, et exécuter la batterie E2E et le harnais de chaos sans toucher à un
état réel du moteur.
Tout ce qui suit s’exécute depuis la racine de votre checkout — idéalement un git worktree : un
répertoire de travail séparé avec sa propre branche, un par tâche, créé à partir de origin/main
(la commande se trouve dans Commencer ici, étape 2 ;
les règles se trouvent dans Flux de contribution).
Cloner#
git clone https://github.com/angolardevops/delonix-runtime.git
cd delonix-runtime
git fetch --tags origin # several gates compare against the release tags
Compiler#
cargo build --workspace # every crate and every binary
cargo build -p delonix-runtime-bin # just the `delonix` CLI
cargo build --release -p delonix-runtime-bin # what the docs generator and the CLI gates use
Le workspace fournit ces binaires, à partir de ces paquets :
| Binaire | Paquet | Sortie |
|---|---|---|
delonix (la CLI) |
delonix-runtime-bin |
target/debug/delonix ou target/release/delonix |
delonix-cri |
delonix-cri |
target/ |
delonix-mcp |
delonix-mcp-bin |
target/ |
delonix-mgmt |
delonix-mgmt-bin |
target/ |
Le workflow de release compile exactement ces quatre paquets. Si vous définissez CARGO_TARGET_DIR, les binaires
y atterrissent au lieu de target/.
Deux remarques pratiques :
- Testez toujours le binaire que vous avez compilé (
./target/debug/delonix), jamais undelonixprésent dans votrePATH— c’est une release installée, souvent en retard de plusieurs versions. - Si vous travaillez dans plusieurs worktrees, les faire tous pointer vers un même
CARGO_TARGET_DIRpartagé économise du disque, mais deux builds qui s’y exécutent en même temps s’attendront mutuellement et peuvent invalider les artefacts l’un de l’autre. Un répertoire target par worktree est plus lent la première fois et prévisible ensuite.
Installer votre build localement#
La plupart des modifications n’ont jamais besoin d’un build installé : exécutez ./target/debug/delonix depuis votre worktree. N’installez
que lorsque vous avez besoin d’un chemin stable — une unité systemd, un script dans un autre shell, un kubelet qui parle à
delonix-cri. Avant et après l’installation, vérifiez quel build vous exécutez :
./target/debug/delonix --version # commit: <hash> (+N commits since vX.Y.Z) · built: <date>
command -v delonix # which `delonix` your shell would run instead
La ligne commit: provient de bins/delonix-runtime-bin/build.rs (DELONIX_GIT_HASH,
DELONIX_GIT_SINCE). Entre deux releases, chaque build porte le même numéro de version ; le commit
est donc le seul moyen de distinguer votre build de celui publié.
Comment delonix trouve ses binaires serveur#
delonix serve cri, delonix serve api et delonix mcp ne contiennent pas les serveurs : ils font un exec de
delonix-cri, delonix-mgmt et delonix-mcp (exec_server dans
bins/delonix-runtime-bin/src/cmd/serve.rs). La recherche est la suivante :
- le fichier de ce nom à côté du
delonixen cours d’exécution ; - sinon le nom dans le
PATH.
delonix passe au serveur sa propre version dans DELONIX_DISPATCH_VERSION, et un serveur d’une
autre release refuse de démarrer. Il se passe aussi lui-même dans DELONIX_BIN, afin que le serveur rappelle
la même CLI. Un serveur démarré directement (par exemple par une unité) trouve la CLI via
DELONIX_BIN, puis un delonix situé à côté de lui-même, puis le PATH (cli_bin dans
crates/contexts/delonix-node/src/dispatch.rs). Gardez ensemble les quatre binaires d’un même build ;
un mélange de votre build et d’une release est refusé, ou exécute du code que vous n’aviez pas l’intention de tester.
delonix cluster kubeadm et delonix image vm build cherchent delonix-cri dans leur propre ordre
(resolve_cri_bin dans bins/delonix-runtime-bin/src/cmd/vmimage.rs) : --cri-bin, puis à côté de
delonix, puis un cargo build --release -p delonix-cri si le répertoire courant se trouve dans un
checkout des sources, et seulement ensuite un téléchargement de l’asset publié.
Compilez les quatre avant de les installer :
cargo build --release -p delonix-runtime-bin -p delonix-cri -p delonix-mgmt-bin -p delonix-mcp-bin
Option A — l’exécuter depuis le worktree (le plus sûr)#
Rien n’est copié ; rien en dehors de votre checkout ne peut donc le prendre par accident :
alias delonix-dev="$PWD/target/release/delonix"
delonix-dev --version
Les serveurs sont trouvés parce qu’ils se trouvent à côté de lui dans target/release/. Sur Ubuntu 23.10+, ce chemin
a besoin de son propre profil AppArmor (voir
AppArmor).
Option B — installer pour votre utilisateur dans ~/.local/bin#
install -d ~/.local/bin
install -m 0755 target/release/delonix target/release/delonix-cri \
target/release/delonix-mgmt target/release/delonix-mcp ~/.local/bin/
hash -r # forget the path your shell cached
command -v delonix && delonix --version
Si une release est aussi installée dans /usr/local/bin, c’est le répertoire qui vient en premier dans le PATH qui l’emporte.
AppArmor. scripts/install.sh écrit un seul profil, /etc/apparmor.d/delonix, lié à
<install dir>/delonix, et uniquement sur les hôtes avec
kernel.apparmor_restrict_unprivileged_userns=1. Un binaire que vous avez copié vers un nouveau chemin n’est pas couvert.
Ne relancez pas l’installateur pour « déplacer » ce profil sur une machine qui utilise aussi une installation
publiée : le fichier de profil est réécrit, et le binaire publié le perd. Ajoutez plutôt un second profil
avec un nom différent — de la même forme que celle écrite par l’installateur, il ne remplace donc rien :
printf 'abi <abi/4.0>,\ninclude <tunables/global>\nprofile delonix-dev %s flags=(unconfined) {\n userns,\n}\n' \
"$HOME/.local/bin/delonix" | sudo tee /etc/apparmor.d/delonix-dev >/dev/null
sudo apparmor_parser -r /etc/apparmor.d/delonix-dev
Non vérifié ici : cette commande reproduit install.sh (le bloc AppArmor) avec un nom de profil et un fichier
différents ; elle n’a pas été chargée sur un hôte où la restriction était active lors de la rédaction de cette page.
L’installateur ajoute aussi la complétion du shell, les pages de manuel et les fichiers de syntaxe pour éditeurs, mais seulement dans sa phase binaire. Pour votre propre build, générez-les à partir du binaire si vous les voulez :
mkdir -p ~/.local/share/bash-completion/completions
delonix completion shell bash > ~/.local/share/bash-completion/completions/delonix
delonix man --dir ~/.local/share/man
Option C — installation système dans /usr/local/bin#
sudo install -m 0755 target/release/delonix target/release/delonix-cri \
target/release/delonix-mgmt target/release/delonix-mcp /usr/local/bin/
Uniquement sur une machine où aucun workload Delonix n’est en service. Le binaire installé n’est pas qu’une simple commande :
- les unités de démarrage écrites par
delonix system boot enablelancentExecStart=<exe> container start <name>, où<exe>est le chemin du binaire qui a exécutéenable(bins/delonix-runtime-bin/src/cmd/boot.rs, préfixe d’unitédelonix-boot-) ; remplacer ce fichier change ce qui démarre après le prochain redémarrage ; dist/delonix-cri.serviceexécute/usr/local/bin/delonix-cri; sur un nœud Kubernetes, le kubelet reçoit donc votre build au prochain redémarrage de cette unité ;- les processus de longue durée démarrés auparavant (le pin et le processus de contrôle du réseau, les superviseurs de containers) continuent d’exécuter le code avec lequel ils ont démarré ; pendant un temps, deux builds tournent donc côte à côte.
Vérifiez d’abord :
delonix container ls -a; delonix vm ls
ls ~/.config/systemd/user/delonix-boot-* /etc/systemd/system/delonix-* 2>/dev/null
pgrep -a delonix
Préparer l’hôte#
scripts/install.sh fait deux travaux distincts. Seul le premier concerne le binaire :
| Partie | Ce qu’elle fait | Flag qui la saute ou l’active |
|---|---|---|
| Binaire | télécharge une release, vérifie la signature minisign et le sha256, installe delonix (plus delonix-mcp, delonix-mgmt, et delonix-cri avec --with-cri), puis la complétion, les pages de manuel, la syntaxe pour éditeurs et l’extension d’éditeur |
sautée avec --no-binary ; --user choisit ~/.local/bin |
| Paquets de l’hôte | slirp4netns, uidmap, nftables, iproute2, conntrack |
toujours |
| Identité rootless | plages /etc/subuid et /etc/subgid pour votre utilisateur |
toujours |
| AppArmor | profil pour <dir>/delonix lorsque la restriction de userns est active |
toujours (lorsque la restriction est active) |
| Ancien Debian | kernel. lorsqu’il vaut 0 |
toujours (lorsque nécessaire) |
| Dépendances des VM | libvirt, qemu, outillage cloud-init ; Cloud Hypervisor et son firmware téléchargés depuis l’amont | sautée avec --no-vm |
| Provider de VM par défaut | providers.yaml avec defaultProvider: libvirt (ADR-0054) : /etc/delonix/, ou ~/.config/delonix/ avec --user ; écrit seulement s’il n’existe pas, jamais réécrit |
--vm-provider cloud-hypervisor change le défaut ; sauté avec --no-vm |
| Réglage du noyau | /, / |
sautée avec --no-tune |
| Délégation de cgroup | drop-in de user@.service, uniquement si ce n’est pas déjà délégué |
sautée avec --no-delegate |
| Accélérateurs | CDI NVIDIA et groupe render, uniquement lorsqu’un GPU est présent |
sautée avec --no-gpu |
| Options à activer | ports inférieurs à 1024 (--low-ports), construction d’images de VM (--with-image-build), réglage pour la montée en charge (--production) |
désactivées par défaut |
Pour préparer un hôte pour votre propre build sans télécharger aucune release Delonix, exécutez l’installateur
depuis votre checkout avec --no-binary :
bash scripts/install.sh --no-binary # add --no-vm if you do not need VM dependencies
bash scripts/install.sh --help # the full flag list, from the script header
Avec --no-binary, le profil AppArmor est écrit pour le répertoire du delonix que
command -v delonix trouve (ou /usr/local/bin s’il n’y en a aucun) — la même précaution que ci-dessus s’applique sur une
machine dotée d’une installation publiée. Le script utilise sudo pour les étapes concernant l’hôte.
Demandez ensuite au binaire si l’hôte est prêt (en lecture seule) :
delonix system doctor # every prerequisite, and how to fix each; --strict exits non-zero on a failure
delonix system info # state root, rootless, cgroup delegation, network infra
Voir Diagnostiquer l’hôte pour la signification de chaque vérification.
Utiliser une racine d’état isolée#
Un build installé utilise par défaut votre racine d’état réelle : les mêmes containers, réseaux et
volumes que la release. Exportez d’abord DELONIX_ROOT et DELONIX_NET_RUNTIME_DIR (voir
Isoler l’état du moteur), et consultez
Variables d’environnement pour toutes les autres variables que lit votre build.
Désinstaller et revenir en arrière#
Il n’existe pas de flag de désinstallation dans install.sh. Supprimez ce que vous avez copié :
rm -f ~/.local/bin/delonix ~/.local/bin/delonix-cri ~/.local/bin/delonix-mgmt ~/.local/bin/delonix-mcp
hash -r
sudo apparmor_parser -R /etc/apparmor.d/delonix-dev && sudo rm /etc/apparmor.d/delonix-dev # if you added it
Pour revenir à un binaire publié, relancez l’installateur ; il remplace les binaires de son répertoire d’installation par la release que vous nommez :
curl -fsSL https://github.com/angolardevops/delonix-runtime/releases/latest/download/install.sh | bash -s -- --user
curl -fsSL https://github.com/angolardevops/delonix-runtime/releases/latest/download/install.sh | bash -s -- --version vX.Y.Z
Les fichiers de complétion et les pages de manuel générés à la main ne sont supprimés par aucune de ces deux étapes. Terminez par
delonix --version pour confirmer le commit sur lequel vous êtes revenu.
Exécuter les tests#
cargo test --workspace # the whole suite
cargo test -p delonix-sdn # one crate
cargo test -p delonix-stack -- reconcile # tests whose path contains "reconcile"
cargo test -p delonix-stack -- --exact kinds::tests::nenhum_kind_aparece_duas_vezes
Les tests qui ont besoin de privilèges ou d’un vrai hôte se sautent eux-mêmes au lieu d’échouer, de sorte que la suite a
un sens sur un portable comme en CI. Quelques tests réels sont marqués #[ignore] et nomment la commande pour
les exécuter dans leur commentaire de documentation (par exemple dans crates/adapters/delonix-vm/src/lib.rs) ; n’exécutez ceux-ci
que sur une machine qui vous appartient :
cargo test -p <crate> -- --ignored <test-name>
Un cargo test vert prouve la logique pure. Il ne prouve pas qu’une modification des namespaces,
des cgroups, du holder réseau ou du démarrage des VM fonctionne — cela exige une exécution réelle (voir
Batterie de bout en bout et Harnais de chaos).
Les gates exécutés par la CI#
| Job CI | Ce qu'il vérifie |
|---|---|
fmt |
rustfmt |
lang |
lang ratchet |
arch |
arch fitness |
contract |
contract gate |
version |
version gate |
cli-surface |
cli surface |
clippy |
clippy -D warnings |
test |
test |
test-arm64 |
test (arm64) |
deny |
cargo-deny |
fuzz |
fuzz (60s smoke, per target) |
script-tests |
script tests (Python gates) |
perf-probe |
perf probe (environment and bench) |
perf |
perf gate (regression against the baseline) |
release-verify |
release verify |
docs |
generated docs and valid examples |
Chaque job de .github/workflows/ci.yml peut être reproduit localement. Exécutez ceux qui correspondent à ce que vous
avez touché avant de pousser ; exécutez-les tous avant de demander une revue.
| Job | Commande locale | Échoue lorsque |
|---|---|---|
fmt |
cargo fmt --all --check |
le code n’est pas formaté par rustfmt (configuration par défaut) |
lang |
python3 scripts/ |
les identifiants, commentaires ou messages en portugais augmentent — ou diminuent sans abaisser scripts/ dans le même commit (--list les affiche, --update abaisse la ligne de base) |
arch |
python3 scripts/ |
une dépendance va à l’encontre de la direction des couches, un crate se trouve dans le mauvais répertoire, un crate membre épingle une version de dépendance, un nom de consommateur apparaît dans le code, ou un ratchet (cliquet) de dette bouge (--list, --update) |
arch |
python3 scripts/ |
un fait généré dans docs/dev/ est obsolète — exécutez python3 scripts/ et commitez |
contract |
python3 scripts/ |
le contrat de nœud dans proto/delonix/node/v1 n’est pas propre au sens de buf format, échoue à buf lint, rompt la compatibilité avec le dernier tag, n’a pas de mapping HTTP, ou docs/api/openapi.yaml n’est pas celui généré (--update le réécrit). Nécessite protoc, buf v1.73.0 et protoc-gen-openapi v0.7.1 dans le PATH, ainsi que les tags |
version |
python3 scripts/ |
la version du workspace n’est pas le tag le plus récent que contient le commit (voir Flux de contribution) ou la branch ne contient pas le tag le plus récent. Nécessite les tags |
cli-surface |
cargo build --release -p delonix-runtime-bin && scripts/ |
une feuille de la CLI a été ajoutée, supprimée ou reclassée sans mise à jour de scripts/ dans le même commit (scripts/) |
cli-surface |
python3 scripts/ |
une commande delonix … citée dans la documentation actuelle n’existe pas dans l’arbre du binaire |
clippy |
cargo clippy --workspace --all-targets --locked -- -D warnings |
n’importe quel avertissement |
test |
cargo build --workspace --locked && cargo test --workspace --locked --no-fail-fast |
n’importe quel test échoue |
deny |
cargo deny check advisories licenses sources |
un avis RUSTSEC, une licence ou une source non autorisée (deny.toml) |
docs |
cargo build --release -p delonix-runtime-bin && python3 docs/ |
le site commité n’est pas ce que le générateur produit à partir de ce binaire |
docs |
. et . |
un exemple publié utilise une forme dépréciée ou a des références non résolues |
cli-tree.sh et docs_cli_gate.py lisent l’arbre depuis le vrai --help du binaire ; définissez
DELONIX_BIN=/path/to/delonix pour choisir quel binaire. docs/gen.py utilise par défaut
target/release/delonix et nécessite le module Python markdown. Le job docs génère aussi les
pages de manuel (delonix man --dir <dir> --index) et les vérifie avec groff -mandoc -ww -z.
Workflows séparés, non requis à chaque modification : chaos.yml exécute le harnais de chaos sur un
runner propre (et signale skipped lorsque le runner bloque les user namespaces), release.yml publie un
tag, et vm-image.yml / vm-appliances.yml construisent des images de VM.
Isoler l’état du moteur#
Tout ce qui va au-delà de --help touche l’état du moteur. Par défaut, c’est votre état réel : vos
containers, réseaux, volumes et le holder réseau. Avant d’exécuter le moteur pour tester —
à la main, via e2e.sh, ou via n’importe quel script — faites pointer les deux racines d’état vers un
répertoire jetable :
export DELONIX_ROOT=$HOME/scratch/dlx/root # containers, images, networks, IPAM, volumes
export DELONIX_NET_RUNTIME_DIR=/tmp/dlx-run # the holder's control and slirp sockets
mkdir -p "$DELONIX_ROOT" "$DELONIX_NET_RUNTIME_DIR"
Les deux, toujours. Une demi-isolation est pire que pas d’isolation du tout. Les sockets réseau et les pidfiles sont
résolus séparément : les pidfiles vivent sous la racine d’état, tandis que les sockets de contrôle et slirp du holder
vivent dans un répertoire d’exécution (par défaut /tmp/delonix-net-<uid>). Lorsque deux racines d’état
se sont retrouvées sur le même répertoire d’exécution, chacune a lu son propre pidfile (absent), en a conclu qu’il n’y avait pas
d’infrastructure réseau, et a démarré ou démoli l’infrastructure par-dessus les sockets de l’autre. Sur un hôte de
développement exécutant des workloads actifs, cela s’est terminé avec la racine réelle reconstruisant son infrastructure réseau et
redémarrant de vrais containers.
Le moteur dérive désormais un suffixe à partir d’un DELONIX_ROOT non par défaut pour le répertoire d’exécution
(runtime_dir/root_suffix dans crates/adapters/delonix-sdn/src/infra.rs), ce qui ferme cette
collision dans le cas courant. Continuez malgré tout à exporter les deux : cela rend l’isolation explicite, garde
le chemin du socket court et sous votre contrôle, et c’est ce que font scripts/e2e.sh et
scripts/chaos.sh (e2e renseigne la variable que vous n’avez pas exportée).
Gardez DELONIX_NET_RUNTIME_DIR court : un chemin de socket unix plus long qu’environ 108 octets échoue avec
path must be shorter than SUN_LEN. e2e.sh refuse un répertoire d’exécution de plus de 80 octets.
Lorsque vous avez terminé, démontez l’infrastructure réseau isolée avec les deux mêmes variables exportées :
./target/debug/delonix net netns down
Recettes d’images de VM (scripts/verify-images.sh)#
Les recettes de images/ sont vérifiées de deux façons. Un test unitaire dans le crate de la CLI
(vmspec::every_shipped_recipe_is_valid_and_complete) échoue si une recette cesse de se parser ou pointe vers un
fichier ou un builder qui n’existe pas. scripts/verify-images.sh va plus loin : il construit hors ligne les quatre
distributions à image cloud dans un DELONIX_ROOT isolé et relit le qcow2 obtenu face à ce que la recette déclarait ;
--self-test prouve que les vérifications peuvent échouer sur une image que personne n’a construite. Il requiert
libguestfs-tools (voir Construire des microVMs) et ne fait pas partie des gates de la CI. Les
phases --packages, --profile, --boot et --appliance existent mais n’avaient pas été exécutées à la sortie de
la v4.2.0.
Batterie de bout en bout (scripts/e2e.sh)#
e2e.sh exécute la CLI contre le vrai noyau : le --help de chaque feuille, plus des exécutions réelles d’une
grande partie de la surface, et affiche un rapport PASS/FAIL/SKIP/XFAIL (détail JSONL dans
$OUT/results.jsonl, par défaut OUT=/tmp/delonix-e2e).
./scripts/e2e.sh # uses ./target/debug/delonix
./scripts/e2e.sh ./target/release/delonix
- Il s’isole lui-même par défaut : il fixe
DELONIX_ROOTetDELONIX_NET_RUNTIME_DIRvers ses propres répertoires (sauf si vous exportez d’abord les deux) et démonte l’infrastructure qu’il a démarrée.E2E_SHARED_STATE=1s’exécute contre l’état réel de la machine — uniquement pour diagnostiquer un hôte. - Le code de sortie est non nul lorsqu’une vérification échoue, ou lorsqu’une vérification marquée comme défaut connu (
XFAIL) réussit de manière inattendue. Les SKIP ne font pas échouer l’exécution mais sont listés dans leur propre bloc : une vérification sautée n’a rien prouvé. - Il a besoin d’un accès réseau pour récupérer des images ; les sections dont les préconditions manquent sont sautées avec la raison.
- Une exécution verte signifie que le
--helpde chaque feuille a été vérifié et que certaines feuilles ont été exécutées. Lisez l’en-tête du script pour savoir ce qui est exécuté et ce qui ne l’est pas.
Harnais de chaos (scripts/chaos.sh)#
Le harnais de chaos casse volontairement un moteur en cours d’exécution — tuer le holder, remplir le disque, attaches concurrents, applies partiels — et indique s’il s’est dégradé de la manière qu’il promet.
scripts/chaos.sh # every scenario, ./target/debug/delonix
scripts/chaos.sh holder_kill oom # selected scenarios
scripts/chaos.sh --keep scale # leave the sandbox up for a post-mortem
scripts/chaos.sh --clean # tear the kept sandbox down
- Il redirige toujours les deux racines vers son sandbox (
DELONIX_CHAOS_DIR, par défaut/tmp/dlx-chaos) et ne touche jamais aux containers, réseaux ou enregistrements du moteur réel. Les répertoires d’images (images,layers,blobs) sont des liens symboliques vers votre store réel pour éviter les téléchargements : en pratique, le harnais ne fait que les lire, mais un scénario qui écrirait une image écrirait dans le store réel. - Il refuse de s’exécuter sur une machine chargée (charge au-dessus d’un seuil, partagé avec
scripts/bench.shviascripts/bancada.sh) : sous charge, les scénarios échouent pour des raisons qui relèvent du banc, pas du produit.--max-load Nmodifie le seuil ;--forces’exécute quand même et marque le verdict comme non publiable. - Le code de sortie n’est 0 que lorsqu’aucun scénario n’échoue. Les SKIP sont listés séparément.
- Certains scénarios ont besoin de ressources externes et sont sautés sans elles (par exemple
truenas_destroya besoin deDELONIX_CHAOS_TRUENAS_URL/_USER/_PASS).
Les répertoires jetables sous /tmp conviennent pour ces sandboxes à usage unique. Vos worktrees, non
— voir Flux de contribution.
Suivant : Structure du projet — la carte du dépôt : ce qu’est chaque répertoire, qui le modifie, et ce qui est généré.