Aller au contenu

Importer des paquets depuis des sources externes

Utilisez la fonctionnalité d'import de Repod pour mettre en miroir des paquets provenant de dépôts publics ou internes vers votre dépôt privé, sans avoir à uploader les fichiers manuellement.

Maven, PyPI, npm et les images de conteneurs ont leur propre importateur

Ce guide couvre le flux source-et-catalogue APT/RPM décrit ci-dessous. Maven Central, PyPI, npmjs.org et Docker Hub disposent chacun d'un onglet Importateur en une seule étape, plus simple (recherchez ou référencez un artefact par ses coordonnées, il est téléchargé, scanné et publié en une seule opération) — voir Configuration des clients et Registre de conteneurs pour ceux-là.


Fonctionnement de l'import

L'import est un processus en deux étapes :

  1. Synchroniser l'index — Repod récupère les métadonnées de paquets du dépôt distant (Packages.gz pour APT, repomd.xml pour RPM) et les stocke dans un catalogue local consultable. Aucun paquet n'est téléchargé à ce stade.

  2. Importer un paquet — Repod télécharge le binaire du paquet sélectionné depuis la source distante, le fait passer par le pipeline de sécurité complet (antivirus, scan CVE, vérification GPG), et le publie dans votre distribution.


Étape 1 — Ajouter une source externe

Naviguez vers Import → Sources → Ajouter une source, ou utilisez l'API :

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/v1/import/sources \
  -d '{
    "name": "ubuntu-jammy",
    "type": "apt",
    "url": "http://archive.ubuntu.com/ubuntu",
    "distribution": "jammy",
    "components": ["main", "universe", "restricted"]
  }'
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/v1/import/sources \
  -d '{
    "name": "epel9",
    "type": "rpm",
    "url": "https://dl.fedoraproject.org/pub/epel/9/Everything/x86_64/"
  }'
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/v1/import/sources \
  -d '{
    "name": "almalinux9-appstream",
    "type": "rpm",
    "url": "https://repo.almalinux.org/almalinux/9/AppStream/x86_64/os/"
  }'

Sources externes courantes

Nom URL Distribution
Ubuntu 22.04 http://archive.ubuntu.com/ubuntu jammy
Ubuntu 24.04 http://archive.ubuntu.com/ubuntu noble
Debian 12 http://deb.debian.org/debian bookworm
Nginx stable http://nginx.org/packages/ubuntu jammy
Nom URL
EPEL 9 https://dl.fedoraproject.org/pub/epel/9/Everything/x86_64/
EPEL 8 https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/
AlmaLinux 9 BaseOS https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/
AlmaLinux 9 AppStream https://repo.almalinux.org/almalinux/9/AppStream/x86_64/os/
Nginx stable (RPM) https://nginx.org/packages/rhel/9/x86_64/

Étape 2 — Synchroniser l'index

La synchronisation récupère les métadonnées distantes et alimente le catalogue local consultable. Aucun paquet n'est téléchargé à cette étape.

Dans l'interface web : Import → Sources → [nom de la source] → Synchroniser maintenant

Via l'API (renvoie un flux SSE en temps réel) :

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/api/v1/import/sources/1/sync

La réponse est un flux Server-Sent Events. Chaque ligne est une mise à jour de progression :

data: {"status":"syncing","count":0,"message":"Fetching index..."}
data: {"status":"syncing","count":4521,"message":"Processing packages..."}
data: {"status":"done","count":4521,"message":"Index updated"}

Durée de synchronisation

Synchroniser une grande source (par ex. Ubuntu jammy main+universe) peut prendre 30 à 120 secondes en raison de la taille de Packages.gz. Les synchronisations suivantes sont plus rapides car seuls les paquets modifiés sont traités.


Étape 3 — Parcourir et sélectionner des paquets

Après la synchronisation, parcourez le catalogue de paquets sous Import → Catalogue. Utilisez la zone de recherche pour trouver des paquets par nom.

Le catalogue affiche pour chaque paquet :

  • Nom, version, architecture
  • Taille
  • Horodatage de dernière synchronisation
  • Description

Étape 4 — Importer un paquet

Sélectionnez un paquet dans le catalogue et cliquez sur Importer, ou utilisez l'API :

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/v1/import/packages \
  -d '{
    "source_id": 1,
    "package":   "nginx",
    "version":   "1.24.0-1ubuntu2",
    "arch":      "amd64",
    "distribution": "jammy"
  }'
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/v1/import/packages \
  -d '{
    "source_id": 2,
    "package":   "nginx",
    "version":   "1.24.0-1.el9.ngx",
    "arch":      "x86_64",
    "distribution": "almalinux9"
  }'

L'import exécute le pipeline de sécurité complet et renvoie un résultat :

{
  "status": "published",
  "package": "nginx",
  "version": "1.24.0",
  "distribution": "jammy",
  "pipeline": {
    "antivirus": "clean",
    "cve_scan": "no_findings",
    "gpg": "unsigned_pass",
    "dependencies": "satisfied"
  }
}

Import en lot

Pour importer plusieurs paquets à la fois, utilisez une boucle shell :

PACKAGES=(nginx curl libssl3 openssl)
SOURCE_ID=1
DIST=jammy

for pkg in "${PACKAGES[@]}"; do
  echo "Importing $pkg..."
  curl -sf -X POST -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    http://localhost:8000/api/v1/import/packages \
    -d "{
      \"source_id\": $SOURCE_ID,
      \"package\": \"$pkg\",
      \"distribution\": \"$DIST\"
    }"
  echo
done

Omettez la version pour importer la dernière

Si version est omis, Repod importe la dernière version disponible depuis l'index synchronisé.


Environnements air-gap

Dans les réseaux air-gap où Repod ne peut pas atteindre directement les URL externes, vous pouvez pré-télécharger les paquets et les uploader via le point de terminaison d'upload standard :

# On an internet-connected machine
apt-get download nginx
scp nginx_1.24.0-1_amd64.deb repod-server:/tmp/

# On the Repod server — upload the .deb
TOKEN=$(curl -s ... | jq -r .access_token)
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -F "file=@/tmp/nginx_1.24.0-1_amd64.deb" \
  -F "distribution=jammy" \
  http://localhost:8000/api/v1/upload/
# On an internet-connected machine
dnf download nginx --destdir=/tmp/
scp /tmp/nginx-*.rpm repod-server:/tmp/

# On the Repod server — upload the .rpm
TOKEN=$(curl -s ... | jq -r .access_token)
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -F "file=@/tmp/nginx-1.24.0-1.el9.ngx.x86_64.rpm" \
  -F "distribution=almalinux9" \
  http://localhost:8000/api/v1/upload/

Résolution de problèmes

La synchronisation renvoie 0 paquet

docker compose logs backend-api | grep -i "sync\|error\|index"

APT : Le fichier Release distant n'a pas pu être récupéré — vérifiez l'URL, l'accès réseau, et si la source nécessite une authentification.

RPM : Le repodata/repomd.xml est injoignable, ou la table PostgreSQL package_index n'est pas synchronisée pour cette source.

Relancez la synchronisation après avoir corrigé la connectivité :

TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"YourPassword"}' | jq -r .access_token)

curl -X POST http://localhost:8000/api/v1/import/sync/start \
  -H "Authorization: Bearer $TOKEN"

L'import échoue avec 404 Not Found

La version du paquet dans le catalogue n'existe plus sur le serveur distant (supprimée en amont). Resynchronisez l'index et sélectionnez une version actuelle.

Paquet bloqué en pending_review

Le scan CVE a trouvé des résultats correspondant à la politique review. Allez dans Sécurité → File de revue, examinez les résultats, et approuvez ou rejetez.

GPG key retrieval failed pendant l'import

Le paquet distant est signé avec une clé que Repod ne reconnaît pas. C'est attendu pour les paquets externes. Le paquet passe quand même si la vérification GPG est configurée en mode souple (comportement par défaut).


Synchronisation planifiée

Pour maintenir l'index à jour automatiquement, configurez une synchronisation planifiée dans Paramètres → Tâches planifiées, ou utilisez une tâche cron :

# Sync all sources daily at 02:00
0 2 * * * curl -sf -X POST \
  -H "Authorization: Bearer $REPOD_TOKEN" \
  http://localhost:8000/api/v1/import/sources/1/sync >> /var/log/repod-sync.log 2>&1

Remplacez $REPOD_TOKEN par un jeton API longue durée créé pour l'utilisateur d'automatisation (rôle admin ou maintainer).