Aller au contenu

Registres

BatleHub sert par proxy, met en cache et héberge en privé 23 types de registres — des gestionnaires de paquets par langage aux dépôts de paquets système, en passant par les places de marché d'extensions d'éditeur et les miroirs de fichiers génériques.

Chaque type de registre tourne dans l'un de trois modes, réglé registre par registre dans la configuration :

  • proxy — un pur cache en lecture devant un amont. La première requête est récupérée en amont et stockée ; toutes les suivantes sont servies depuis le cache.
  • local — un registre entièrement privé. Rien n'est récupéré en amont : vous publiez et servez vos propres artefacts.
  • hybrid — les artefacts locaux l'emportent, et tout ce qui n'est pas publié localement se rabat sur le proxy amont.

Cinq types sont en proxy seul (pas de modèle de publication privée) : GitHub, Forgejo, GitLab (ils hébergent les sources et les releases en amont), ainsi que les archives d'IDE JetBrains et les miroirs de fichiers generic (caches par chemin uniquement).

Les registres

Hébergement de code source

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
GitHubgithubReleases, assets, tarballs, fichiers brutsproxy seulapi.github.com
Forgejo / GiteaforgejoReleases, assets, archives, brut (/api/v1)proxy seulcodeberg.org
GitLabgitlabReleases, assets de liens, archives (/api/v4)proxy seulgitlab.com

Gestionnaires de paquets par langage

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
npmnpmPackument et tarballsproxy · local · hybridregistry.npmjs.org
CargocargoIndex sparse et .crateproxy · local · hybridcrates.io
Modules GogoproxyGOPROXY (.info/.mod/.zip)proxy · local · hybridproxy.golang.org
MavenmavenXML de métadonnées, JAR et POMproxy · local · hybridrepo1.maven.org
PyPIpypiAPI Simple (PEP 503/691) et wheelsproxy · local · hybridpypi.org
Condacondarepodata.json et .conda/.tar.bz2proxy · local · hybridconda.anaconda.org
Composer (PHP)composerPackagist v2 (métadonnées p2 et dist)proxy · local · hybridrepo.packagist.org
RubyGemsrubygemsGems, versions et API d'informationproxy · local · hybridrubygems.org
NuGet (.NET)nugetIndex v3, index plat et .nupkgproxy · local · hybridapi.nuget.org
TerraformterraformProviders et modules (API v1)proxy · local · hybridregistry.terraform.io
Ansible GalaxygalaxyAPI collections v3 (liste des versions, document de version, tarball) et les lectures v1 des rôlesproxy · local · hybridgalaxy.ansible.com/api/

Extensions d'éditeur

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
OpenVSXopenvsxVSIX d'extensionsproxy · local · hybridopen-vsx.org
Place de marché VS Codevscode-marketplaceVSIX d'extensions (Gallery MS)proxy · local · hybridmarketplace.visualstudio.com
Place de marché JetBrainsjetbrains-marketplaceAPI de plugins et téléchargementsproxy · local · hybridplugins.jetbrains.com

Paquets système adressé par chemin

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
Debian / APTdebPackages/Release et .debproxy · local · hybridaucun — déclarez upstreams
RPM / YUM / DNFrpmrepodata/ et .rpmproxy · local · hybridaucun — déclarez upstreams
Pacman / Archpacman<repo>.db et .pkg.tar.zstproxy · local · hybridaucun — déclarez upstreams
Alpine / apkapkAPKINDEX.tar.gz et .apkproxy · local · hybridaucun — déclarez upstreams

Binaires et miroirs adressé par chemin

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
IDE JetBrainsjetbrainsArchives d'installation d'IDEproxy seuldownload.jetbrains.com
Miroir génériquegenericN'importe quelle arborescence HTTPproxy seulaucun — déclarez upstreams et path_allow

Caches de compilation RFC 0028

RegistretypeCe qu'il relaieModesPublicationAmont par défaut
Cache binaire Nixnixnix-cache-info, un {hash}.narinfo par chemin du store (relayé avec la seule URL: réécrite, de sorte que chaque Sig: reste vérifiable) et les NARproxy · local · hybridecache.nixos.org

Chaînes d'outils RFC 0010

Typés, de sorte qu'une publication puisse être bloquée et pas seulement mise en cache — l'identité que le miroir générique ne sait pas donner aux mêmes octets.

RegistretypeCe dont il fait proxyModesPublicationAmont par défaut
Distributions Nodenodedistindex.tab/index.json, archives de publication, SHASUMS256.txt octet pour octet (nvm, fnm, n, mise)proxy seulnodejs.org/dist
SDKMANsdkmanAPI des candidats et courtier de téléchargement (le JDK, Gradle, Maven, Kotlin, …) ; le 302 du courtier est suivi côté serveurproxy seulapi.sdkman.io/2 et broker.sdkman.io
Chaîne d'outils RustrustupManifestes de canal (la liste filtrée), archives de composants par cible et leur .sha256 ; le .asc est relayé octet pour octetproxy seulstatic.rust-lang.org

Matrice des fonctionnalités

Chaque registre, et la façon dont ses capacités se projettent sur les fonctionnalités de BatleHub. Les types adressés par chemin (Deb, RPM, Pacman, IDE JetBrains, Generic) n'ont pas de modèle de version par paquet : les axes structurels (liste de versions, archive de sources, binaire, garde-fou d'âge, préchauffage, recherche) affichent donc . Ils bénéficient tout de même du RBAC au niveau du registre et de la diffusion vers plusieurs amonts, et Deb, RPM et Pacman gèrent l'hébergement privé signé. Forgejo et GitLab reproduisent le comportement de GitHub.

Légende : Ver. liste de versions · Src archive de sources · Bin asset binaire ou d'extension · Pub publication privée · Fan diffusion vers plusieurs amonts · Âge garde-fou d'âge de publication · Préch. préchauffage du cache (énumération des versions) · Rech. recherche amont de l'explorateur de paquets. ✓ pris en charge · sans objet · ⚠ partiel.

RegistreVer.SrcBinPubFanÂgeRBACPréch.Rech.
GitHub
Forgejo / Gitea
GitLab
npm
Cargo
Modules Go
Maven
PyPI
Conda✓ ¹⚠ ²✓ ¹
Composer
RubyGems
NuGet
Terraform
Ansible Galaxy✓ ⁶✓ ⁷
OpenVSX
Place de marché VS Code
Place de marché JetBrains
Debian / APT ³
RPM / YUM / DNF ³
Pacman / Arch ³
IDE JetBrains ³
Generic ³
Distributions Node✓ ⁴✓ ⁵
SDKMAN⚠ ⁴✓ ⁵

¹ Conda n'a pas d'API dédiée de liste de versions par paquet. BatleHub en synthétise une en parcourant repodata.json sur noarch, linux-64, osx-64, osx-arm64 et win-64 ; le résultat est l'union des versions trouvées sur toutes les plateformes disponibles.

² Les horodatages conda viennent du champ timestamp de repodata.json (en millisecondes depuis l'époque). La plupart des paquets le portent ; ceux qui ne l'ont pas sautent le garde-fou, sauf si vous mettez deny_missing_timestamp = true sur la règle.

³ Type adressé par chemin : les artefacts sont récupérés par chemin de fichier, sans modèle de version par paquet, d'où les sur les axes structurels. Ces types n'énumèrent pas de versions mais savent préchauffer des fichiers précis par cache.warm_paths, et sont encadrés par une liste d'autorisation path_allow obligatoire. Deb, RPM et Pacman gèrent en plus l'hébergement privé signé (local / hybrid) ; les archives d'IDE JetBrains et Generic sont en proxy seul.

Garde-fous d'âge des chaînes d'outils (RFC 0010 §6.7) : nodedist lit la date de publication dans index.tab, donc les publications courantes sont filtrées et une publication retirée du listing atteint le garde-fou sans date ; sdkman ne publie aucune date, donc le garde-fou est entièrement décidé par deny_missing_timestamp. Sur ces deux types, ce champ est obligatoire sur une règle release_age_gate.

Préchauffage par plateforme : une publication Node et une version SDKMAN sont une archive par plateforme, donc warm_packages préchauffe les plateformes de cache.warm_platforms, avec pour défaut celle du serveur. Le bouton de récupération par version de la console est refusé pour la même raison.

Une seule page, toujours (RFC 0031 §4.4) : ansible-galaxy résout un lien de pagination par rapport à la racine d'API configurée, et les liens de l'amont sont des chemins absolus qui remplacent tout le chemin — aucune continuation émise par BatleHub ne pourrait donc être suivie jusqu'à lui. Chaque listing qu'il sert porte donc un next nul, et l'adaptateur parcourt lui-même les pages de l'amont.

Garde-fous d'âge Galaxy : chaque version amont d'une collection porte created_at, donc le garde-fou est entièrement décidé en mode proxy. Une collection publiée localement et un listing hors ligne peuvent n'en porter aucune : deny_missing_timestamp est donc obligatoire sur une règle release_age_gate ici, comme sur les types de chaînes d'outils.

Recherche amont de l'explorateur de paquets (« Pas encore passé par le proxy ») : Go passe par pkg.go.dev ; PyPI est une recherche par nom exact ; Terraform combine la recherche de modules avec une recherche de provider par namespace ou par paire exacte. Les proxys de releases (GitHub, Forgejo, GitLab), la place de marché VS Code, Conda et les types adressés par chemin n'ont pas d'API de recherche amont — voir le guide de l'explorateur de paquets.

READMEs

Ce qu'un paquet dit de lui-même, version par version. Qu'un registre en ait un du tout est une propriété de son protocole, pas une préférence : le texte voyage soit dans un document que le proxy récupère déjà pour résoudre une version, soit à l'intérieur de l'artefact — et c'est ce qui décide si la page du paquet peut l'afficher pour une version dont cette instance ne détient aucun octet.

Détenu nulle part ici est la colonne à lire avant de chercher un manque : versions + README signifie que la page du paquet répond entièrement pour un paquet que rien ici n'a jamais récupéré ; versions seulement signifie qu'elle liste les versions et annonce que le README arrivera au premier téléchargement ; ni l'un ni l'autre signifie que la page répond à partir de ce que cette instance détient, et de rien d'autre.

Récupérable dit si la page propose un bouton Récupérer cette version sur ces lignes purement amont, et si le catalogue en propose un sur un résultat de recherche amont. no n'est pas une limite du bouton mais de la coordonnée : une version Maven est un ensemble de fichiers, un provider Terraform s'adresse par système et architecture en plus de la version, une version PyPI est une sdist plus une wheel par interpréteur et par plateforme, et un artefact conda porte une plateforme de canal et une chaîne de build — « récupérer cette version » n'a donc de sens unique pour aucun d'eux. La page dit lequel, plutôt que d'afficher un bouton désactivé — voir récupérer depuis la console.

RegistryREADME sourcePer versionHeld nowhere hereFetchable
githubthe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
forgejothe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
gitlabthe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
cargoa file inside the artifactyesversions onlyyes
npmthe metadata document, else the artifactyesversions + READMEyes
openvsxa URL in the metadata, read separatelyyesversions + READMEyes
goproxya file inside the artifactyesversions onlyyes
pypithe metadata document, else the artifactyesversions + READMEno
condaa file inside the artifactyesversions onlyno
composera file inside the artifactyesversions onlyyes
vscode-marketplacea URL in the metadata, read separatelyyesversions + READMEyes
maventhe POM carries <description>, which is a sentence rather than a document; putting one where a reader expects the other makes every package look thinly documentedversions onlyno
terraforma file inside the artifactyesversions onlyno
rubygemsa file inside the artifactyesversions onlyyes
nugeta file inside the artifactyesversions onlyyes
debpath-addressed: there is no package identity to hang a README onneitherno
rpmpath-addressed: there is no package identity to hang a README onneitherno
pacmanpath-addressed: there is no package identity to hang a README onneitherno
apkan .apk carries pkgdesc, one sentence in .PKGINFO; putting a sentence where a reader expects a document makes every package look thinly documentedneitherno
jetbrainspath-addressed: there is no package identity to hang a README onneitherno
jetbrains-marketplacethe metadata document, already fetchedyesversions + READMEyes
genericpath-addressed: there is no package identity to hang a README onneitherno
nodedista Node release is a set of tarballs and a checksum file; the dist tree carries no proseversions onlyno
sdkmanSDKMAN describes a distribution, not a package: no document in the protocol carries prose about a candidateversions onlyno
rustupa toolchain release is a manifest and a set of tarballs; the dist tree carries no proseversions onlyno
galaxya file inside the artifactyesversions onlyyes
nixa store path is a NAR and its narinfo; the protocol carries no prose, and the NAR is a filesystem image rather than a package with a manifestneitherno

La table ci-dessus est générée depuis le code Rust et reste en anglais : ses cellules sont de la prose que RegistryKind::readme_support() possède, et la traduire créerait une seconde source de vérité pour une phrase que le code écrit.

Cela se configure registre par registre avec [registries.readme] et [registries.upstream_detail]. Les deux sont actifs par défaut, et le second émet une requête sortante la première fois que quelqu'un ouvre la page d'un paquet dont cette instance ne détient rien — voir ce qui sort de cette instance.

Deux réglages façonnent ce que la page sait faire de plus : remote_images = "proxy" rend les images d'un README à travers ce serveur plutôt que de les laisser partir ailleurs, et console_fetch (actif par défaut) est le bouton Récupérer cette version, sur la page du paquet comme sur les lignes amont du catalogue. La recherche dans la prose des README stockés vaut pour toute l'instance et est désactivée par défaut — [search] readmes.

Voir aussi

Publié sous licence Apache 2.0. Fait avec ❤️ et beaucoup trop de ☕.