xoa-proxy
Proxy HTTP/HTTPS en Rust qui transmet une image XOA à XAPI en flux continu.
Dépôt : Vagrantin/xoa-proxy · Langage : Rust · Licence : AGPL-3.0
Objectif
Quand on clique sur le bouton « Deploy XOA » modifié de XO Lite, XAPI doit
importer une archive de VM .xva. XAPI appelle VM.import avec une URL ; il
attend du serveur situé à cette URL qu’il serve le fichier en HTTP uniquement,
et le fichier doit être au format XVA.
Ce support limité ne me satisfaisait pas et, à l’origine, était même bloquant : je m’appuyais sur l’image de Ronivay, qui est au format gz et n’est accessible qu’en HTTPS.
C’est pour cela que xoa-proxy sert d’interface devant XAPI : il prend en charge les protocoles HTTP et HTTPS (certificats auto-signés compris) et, en plus du format XVA, le format gz.
Ce proxy apporte la souplesse nécessaire pour importer des images de différentes sources, y compris locales, et renforce la sécurité en introduisant la prise en charge de HTTPS.
Conception
Choix technologiques
| Choix | Justification |
|---|---|
| Rust | Sûreté mémoire, adapté à un processus serveur de longue durée dans le Dom0 |
Cheminement d’une requête
XO Lite (navigateur)
│ HTTP GET /image.xva
▼
xoa-proxy
│
│ Interface HTTP/HTTPS pour XAPI
│ Décompression du format gzip à la volée
│
▼
XAPI VM.import
│ Écrit les VDI sur le SR local
▼
VM XOA crééeHTTP et HTTPS
xoa-proxy prend en charge HTTP et HTTPS (certificats auto-signés compris) lorsqu’il récupère l’image XOA upstream. Pendant le téléchargement, les images compressées en gzip sont décompressées à la volée, de sorte que XAPI reçoit toujours un flux XVA brut, non compressé.
Le passage de relais vers XAPI via VM.import se fait délibérément en
HTTP/1.0 : XAPI ne prend pas en charge le codage de transfert par blocs
(chunked transfer encoding, une fonctionnalité de HTTP/1.1), et utiliser le
découpage HTTP/1.1 corromprait l’import. Le proxy gère cette contrainte en
interne ; l’appelant n’a rien à configurer.
Structure du code
xoa-proxy/
├── src/
│ └── main.rs ← serveur HTTP, gestionnaire de requêtes, logique de flux
├── tests/ ← tests d'intégration
├── .cargo/ ← configuration Cargo (réglages de compilation croisée)
├── Cargo.toml ← dépendances : hyper, tokio, tokio-util, ...
└── Cargo.lockMotif central de diffusion en flux
Le cœur du proxy consiste à convertir un tokio::fs::File en corps de
réponse hyper sans charger tout le fichier en mémoire :
use tokio_util::io::ReaderStream;
use hyper::Body;
let file = tokio::fs::File::open("image.xva").await?;
let stream = ReaderStream::new(file);
let body = Body::wrap_stream(stream);
let response = Response::builder()
.header("Content-Type", "application/octet-stream")
.header("Content-Encoding", "gzip")
.body(body)?;Construction
Prérequis
- Chaîne d’outils Rust (stable), à installer via rustup
- Pour la compilation croisée vers le Dom0 : la cible
x86_64-unknown-linux-musl
# Build natif (pour les tests)
cargo build
# Compilation croisée pour le Dom0 (binaire musl statique)
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-muslLe binaire obtenu dans
target/x86_64-unknown-linux-musl/release/xoa-proxy est un exécutable
entièrement statique, sans dépendance à des bibliothèques partagées, ce qui
convient à une intégration dans l’environnement DOM0 de XCP-ng.
Exécution locale, pour le développement ou les tests
# Placer une XVA de test au chemin attendu
cp /chemin/vers/test.xva image.xva
# Démarrer le proxy
./target/release/xoa-proxy
# Tester la diffusion en flux
curl -v http://127.0.0.1:3000/image.xva -o /dev/nullConfiguration
Dans la version actuelle, l’adresse d’écoute et le chemin de l’image sont codés en dur.
| Paramètre | Valeur actuelle |
|---|---|
| Adresse d’écoute | 127.0.0.1:3000 |
| Point d’accès du proxy | image.xva |
Signature GPG
Le RPM xoa-proxy est signé avec la signing subkey RPM de la paire
de clés XCP-hl. La même sous-clé est partagée avec xolite-ce : il n’y a
qu’une seule sous-clé pour les deux RPM.
Le projet publie sa clé publique
à la racine du site de production. Vérifiez l’empreinte de la clé principale avant
de l’importer. Les commandes ci-dessous nécessitent une version de RPM prenant
en charge les sous-clés de signature. Le Dom0 de XCP-ng 8.3 utilise RPM 4.11 ;
les hôtes valident donc les métadonnées signées avec repo_gpgcheck=1. Conservez
les paramètres de dépôt décrits dans Mises à jour.
Pour vérifier le RPM en local :
curl -fLO https://vagrantin.github.io/xcp-hl/xcp-ng-ce-public.asc
gpg --show-keys --with-fingerprint xcp-ng-ce-public.asc
# 2F59 1DB9 D2C1 28C4 C3D9 63F4 6DA0 0DCA 5BBA 215A
rpm --import xcp-ng-ce-public.asc
rpm --checksig xoa-proxy-*.rpmIntégration avec XO Lite CE
Le correctif XO Lite de xolite-ce fixe l’URL de
déploiement à http://127.0.0.1:3000/image.xva. C’est l’adresse sur laquelle
xoa-proxy écoute lorsqu’il est démarré sur un hôte XCP-hl.
Tests
# Lancer les tests unitaires et d'intégration
cargo test
# Les tests d'intégration se trouvent dans tests/
# Ils démarrent le proxy et vérifient son comportement en diffusion continueContribuer
Pour signaler un problème ou proposer une modification, ouvrez un ticket sur Vagrantin/xcp-hl.