Pourquoi découper en volumes ?
Certains contextes de distribution imposent des contraintes de taille maximale : pièces jointes email (25 MB), capacité d'une clé USB (4 GB FAT32), quota S3 par objet, ou simplement la gestion des échecs de téléchargement sur des connexions instables. Les archives multi-volumes permettent de distribuer un package de n'importe quelle taille dans ces contraintes.
Une archive multi-volumes n'est pas une archive découpée arbitrairement — chaque volume doit être indépendamment vérifiable (HMAC) et l'ensemble doit rester cohérent même si un volume est re-téléchargé.
Découpage en volumes
from universal_installer.multivolume import VolumeBuilder
builder = VolumeBuilder()
# Mode 1 : découpe par taille fixe
volumes = builder.split(
source="release_v1.1.uxc",
volume_size_mb=500,
output_dir="volumes/"
)
# → volumes/release_v1.1.part001.uxv
# → volumes/release_v1.1.part002.uxv
# → volumes/release_v1.1.manifest.json
# Mode 2 : découpe par contenu (fichiers entiers)
# Chaque volume contient des fichiers complets (pas de fichier coupé)
volumes = builder.split_by_content(
source="release_v1.1.uxc",
max_volume_mb=500,
output_dir="volumes/"
)
print(f"Volumes produits : {len(volumes)}")
print(f"Volume le plus grand : {max(v.size_mb for v in volumes):.1f} MB")
Manifest multi-volumes
# release_v1.1.manifest.json
{{
"archive_name": "release_v1.1",
"total_size_mb": 1840.5,
"volumes": [
{{"index": 1, "filename": "release_v1.1.part001.uxv",
"size_mb": 500.0, "sha256": "a3f8c2...", "blocks": "0-7999"}},
{{"index": 2, "filename": "release_v1.1.part002.uxv",
"size_mb": 500.0, "sha256": "d4e7b1...", "blocks": "8000-15999"}},
{{"index": 3, "filename": "release_v1.1.part003.uxv",
"size_mb": 500.0, "sha256": "f2a9c8...", "blocks": "16000-23999"}},
{{"index": 4, "filename": "release_v1.1.part004.uxv",
"size_mb": 340.5, "sha256": "e5b3d2...", "blocks": "24000-29447"}}
],
"signature": "base64_ecdsa_p384..."
}}
Reconstruction
from universal_installer.multivolume import VolumeAssembler
assembler = VolumeAssembler("volumes/release_v1.1.manifest.json")
# Vérifier que tous les volumes sont présents
missing = assembler.check_volumes()
if missing:
print(f"Volumes manquants : {missing}")
else:
# Assembler et vérifier
result = assembler.assemble(
output="release_v1.1_reconstructed.uxc",
verify_sha256=True,
pubkey_path="keys/public.pem"
)
print(f"Assemblage : {'✓' if result.valid else '✗'}")
Reprise partielle
# Télécharger uniquement les volumes manquants
universal-installer multivolume download --manifest https://cdn.exemple.fr/release_v1.1.manifest.json --output-dir volumes/ --resume # ignore les volumes déjà présents et valides
--verify-each # SHA-256 de chaque volume après download
Conclusion
Les archives multi-volumes UXC résolvent trois problèmes distincts : contournement des limites de taille (email, FAT32, S3), reprise de téléchargement granulaire (volume de 500 MB vs archive de 2 GB), et distribution parallèle depuis plusieurs serveurs (CDN multi-origines). Le manifest signé ECDSA garantit l'intégrité de l'ensemble même si les volumes proviennent de sources différentes.