SDKMAN
Fait proxy et cache de SDKMAN — le JDK, Gradle, Maven, Kotlin et tous les autres candidats — dans un seul registre : l'API des candidats (api.sdkman.io/2) et le courtier de téléchargement (broker.sdkman.io) derrière un unique bloc type = "sdkman". sdk list et sdk install se résolvent par des listings dont les versions bloquées ont été retirées, une version bloquée répond invalid là où sdk install la valide, et la redirection du courtier vers le CDN de l'éditeur est suivie côté serveur, de sorte que le JDK de 200 Mo est mis en cache ici plutôt que renvoyé ailleurs.
En un coup d'œil
| Type de configuration | sdkman |
| Amont par défaut | api.sdkman.io/2 (API des candidats) · broker.sdkman.io (broker_url) |
| Modes | proxy seul |
| Adressage | {candidate}/{version}/{platform} — une archive par plateforme |
| Publication privée | ❌ proxy seul |
| Coupure réseau | hors ligne, versions/all et candidates/default sont composés à partir des archives de candidats détenues pour la plateforme |
Mise en place du proxy
sdkman-init.sh ne définit ses deux variables d'API que si elles sont vides : exportez-les donc avant de le sourcer — dans /etc/profile.d, dans un Containerfile, ou dans le bloc env: d'un job de CI. Remplacez <registry> par le nom de registre que vous avez configuré :
export SDKMAN_CANDIDATES_API="https://batlehub.example.com/proxy/<registry>/sdkman"
export SDKMAN_BROKER_API="https://batlehub.example.com/proxy/<registry>/sdkman/broker"
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk list java # la table rendue, versions bloquées retirées
sdk install java 21.0.5-tem # valider, télécharger par la route du courtier, hookLe bloc de registre côté administrateur :
[[registries]]
name = "jvm"
type = "sdkman"
mode = "proxy" # le seul mode : pas de protocole de publication
upstreams = ["https://api.sdkman.io/2"] # l'API des candidats (le /2 en fait partie)
broker_url = "https://broker.sdkman.io" # le courtier de téléchargement
[registries.rbac]
# candidates, versions, validate, hooks et healthcheck sont des listings
# (`releases:list`) ; le téléchargement est une lecture (`releases:read`).
# Une installation exige les deux.
anonymous = ["releases:read", "releases:list"]broker_url est le second hôte de SDKMAN et de personne d'autre : il est rejeté sur tout autre type de registre. Le /2 d'upstreams est servi tel qu'il est donné — un opérateur qui pointe vers https://beta.sdkman.io/2 doit pouvoir le dire — et une URL qui en est dépourvue est signalée au chargement, parce que c'est plus probablement une faute de frappe qu'un choix.
Ce que l'installateur n'est pas. BatleHub fait proxy du registre, pas de get.sdkman.io : amorcer SDKMAN lui-même est un curl | bash contre l'hôte de son propre installateur, documenté comme prérequis de coupure réseau plutôt que répliqué (RFC 0010, décision 9). Les endpoints broker/version/sdkman/… et selfupdate/… sont, eux, servis, parce que le client en fonctionnement les appelle.
Versions bloquées
Un blocage porte sur le candidat : bloquer java 21.0.5-tem couvre les huit plateformes, pas seulement celle dont vous lisiez le listing. Il atteint tous les endroits où sdk regarde :
versions/all— la version est retirée de la liste séparée par des virgules.candidates/default/{c}— si le défaut nomme la version bloquée, il est réparé vers la plus récente autorisée, comme l'est ledist-tags.latestde npm.- le
versions/listrendu — la table qu'imprimesdk list <candidate>, dans ses deux mises en page. Dans la table des éditeurs Java, la ligne entière disparaît et le nom de l'éditeur est promu à la ligne suivante de son bloc ; dans la grille qu'emploie tout autre candidat, la cellule est vidée à sa propre largeur et rien ne bouge. Rien n'est re-rendu : un changement de mise en page en amont se dégrade donc en une version que nous n'avons pas su masquer, jamais en une table corrompue. candidates/validate/{c}/{v}/{plat}— le point de passage obligé. Chaquesdk installvalide ici et s'arrête sur tout ce qui n'est pasvalid; une version bloquée répondinvalidsans que l'amont soit interrogé, et SDKMAN imprime son propre refus (« Stop! java 21.0.5-tem is not available … is an invalid version »). Aucun téléchargement n'est tenté.
Une requête directe vers broker/download/… pour une version bloquée reçoit toujours le 403 et le motif de l'opérateur : masquer gouverne la résolution, cela ne remplace pas le diagnostic.
Voir bloquer une version de paquet et quels listings sont filtrés.
Authentification
sdk construit sa propre commande curl et n'a nulle part où placer un en-tête. libcurl lit ~/.netrc sans qu'on le lui demande : une instance authentifiée a donc besoin d'une entrée pour l'hôte du proxy.
machine batlehub.example.com
login <your-user-id>
password <your-token>Notes
- Les scripts de hook sont relayés octet pour octet.
hooks/preethooks/postrenvoient du bash quesdksource et exécute sous l'utilisateur appelant — le hook du JDK Linux réempaquette l'archive avectaretzip. C'est la conception de SDKMAN et ce que le client fait aujourd'hui directement depuisapi.sdkman.io; BatleHub n'ajoute ni ne retire de confiance en transportant ces octets, et ne les modifie pas, parce que réécrire une URL à l'intérieur d'un hook ferait de lui un coauteur du shell exécuté. - La chaîne de redirections est suivie à travers le garde-fou SSRF. Le courtier nomme l'hôte de téléchargement, et cet hôte n'est pas SDKMAN :
github.com,repo.maven.apache.org,services.gradle.org, et tout ce sur quoi un éditeur publie. Chaque saut est vérifié contre le garde-fou, et les identifiants amont de l'opérateur s'arrêtent aux deux origines configurées. La sortie réseau vers ces hôtes de CDN est un prérequis ; la liste est observée, pas exhaustive — voir Ce qui sort de cette instance. - Pas de dates : un garde-fou d'âge doit donc afficher sa position. SDKMAN ne publie aucune date de publication, de sorte que tout artefact atteint un
release_age_gateavecpublished_at = None. Sur ce type,deny_missing_timestampest obligatoire :truerefuse tout téléchargement sur le registre,falserend le garde-fou inerte, et ce serveur ne choisit ni l'un ni l'autre à votre place. Un bloc[registries.security](RFC 0018) retient plutôt par défaut sur un horodatage manquant. - Les en-têtes de réponse
X-Sdkman-*ne sont pas transmis. Le client litX-Sdkman-Checksum-<ALG>pour vérifier un téléchargement ; aucun candidat échantillonné n'en émet, et le lecteur du client (grep '^X-Sdkman') ne correspond à rien sur les noms d'en-têtes en minuscules que l'API envoie aujourd'hui : le contrôle est donc inerte, avec ou sans proxy. Consigné dans la RFC 0010 §13.2 plutôt que laissé à découvrir. - Le préchauffage a besoin d'une plateforme.
warm_packages = ["java@21.0.5-tem"]préchauffe une archive par entrée decache.warm_platforms, avec pour défaut la plateforme sur laquelle tourne ce serveur ; deviner les huit récupérerait 1,6 Go de JDK pour un.sdkmanrcd'une ligne.batlehub-cli registry suggestlit.sdkmanrcet écrit les deux. - La liste rendue est mise en cache par client. Sa clé de cache inclut la requête
?current=&installed=qu'envoiesdk list, de sorte que deux machines aux ensembles installés différents ne partagent jamais une entrée.
Endpoints
| Méthode | Chemin | Description |
|---|---|---|
GET | /proxy/{registry}/sdkman/broker/download/{candidate}/{version}/{platform} | The archive for one version on one platform, streamed through the |
GET | /proxy/{registry}/sdkman/broker/version/sdkman/{component}/{channel} | The current SDKMAN script or native version on a channel — what `sdk |
GET | /proxy/{registry}/sdkman/candidates/{candidate}/{platform}/versions/all | Every version of a candidate on a platform, comma-separated, blocked |
GET | /proxy/{registry}/sdkman/candidates/{candidate}/{platform}/versions/list | The rendered table sdk list <candidate> prints, in either of its two |
GET | /proxy/{registry}/sdkman/candidates/all | Every candidate name, comma-separated — what sdk update caches and |
GET | /proxy/{registry}/sdkman/candidates/default/{candidate} | The version sdk install <candidate> resolves to with no version given, |
GET | /proxy/{registry}/sdkman/candidates/list | The rendered candidate table sdk list prints with no argument. |
GET | /proxy/{registry}/sdkman/candidates/validate/{candidate}/{version}/{platform} | The chokepoint: valid or invalid for one version on one platform. A |
GET | /proxy/{registry}/sdkman/healthcheck | The API's health token, read by every sdk invocation. Relayed as-is: |
GET | /proxy/{registry}/sdkman/hooks/{phase}/{candidate}/{version}/{platform} | A pre- or post-install hook: bash the client sources and runs, relayed |
GET | /proxy/{registry}/sdkman/selfupdate/{channel}/{platform} | The self-update script for a channel and platform — bash the client |
Voir aussi
- Distributions Node — l'autre type de chaîne d'outils de la RFC 0010
- Utiliser BatleHub — tokens, prérequis de publication, la CLI
- Vue d'ensemble des registres · Mise en cache · Contrôle d'accès