feint est un émulateur local des API cloud européennes : il répond à
la place de Scaleway, Outscale et Exoscale sur 127.0.0.1:4599, et
vos clients officiels ne font pas la différence. Un binaire Go statique, un
port, aucun compte et aucune facture. Ce guide montre comment l'installer en
vérifiant ce que vous exécutez, brancher scw, oapi-cli, exo et
Terraform dessus, puis obtenir de vraies machines derrière l'API. Public
visé : développeurs et équipes plateforme qui testent du code cloud sans vouloir
payer un compte pour chaque exécution.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer feint en vérifiant la signature Sigstore et la provenance du binaire.
- Diagnostiquer l'hôte avant de démarrer, avec
feint doctor. - Savoir quand une nouvelle version est publiée, sans appel réseau imposé.
- Brancher les trois CLI officiels sans copier une variable à la main.
- Appliquer une configuration Terraform contre l'émulateur.
- Faire tourner de vraies machines qui portent l'adresse publiée par l'API.
- Installer Incus et OVN sur Debian 13, câblage compris.
- Situer la couverture réelle de chaque provider avant de vous appuyer dessus.
Pourquoi les clouds européens n'avaient pas d'émulateur
Section intitulée « Pourquoi les clouds européens n'avaient pas d'émulateur »AWS a LocalStack, Azure a Azurite, et les clouds européens n'avaient rien. Concrètement, une équipe qui écrit du Terraform Scaleway ou du code SDK Outscale teste contre un compte payant, ou ne teste pas. Le premier choix transforme chaque exécution de CI en ligne de facture et chaque développeur en propriétaire de ressources oubliées ; le second laisse les erreurs remonter en production.
Un émulateur répond à ce besoin précis : il rejoue le protocole du fournisseur pour que le client officiel, celui que vous utiliserez vraiment, fonctionne sans quitter votre machine. Le site couvre déjà l'équivalent côté AWS avec Floci : la logique est la même, seul le périmètre change.
feint sert pour le moment trois fournisseurs sur un seul port. Les espaces
d'URL ne se chevauchent pas, ce qui rend la cohabitation possible : Scaleway
sert /<produit>/v<N>/…, Outscale répond en POST /api/v1/<Action>, Exoscale
expose /v2/<ressource>. Un seul multiplexeur HTTP les héberge tous les trois,
et le serveur refuse de démarrer si deux paquets revendiquent la même route.
Prérequis
Section intitulée « Prérequis »- Une machine Linux ou macOS en x86-64 ou ARM64.
cosignetjqpour la vérification d'installation,ghen option.- Les CLI officiels que vous voulez piloter :
scw,oapi-cli,exo, Terraform ou OpenTofu. - Incus 6.0.4 minimum (7.2 recommandé) uniquement pour le mode machines réelles ; la procédure Debian 13, OVN compris, figure dans ce guide.
Rien de tout cela n'est nécessaire pour la partie principale : l'émulateur est un binaire statique sans dépendance, il tient son état en mémoire et n'a besoin d'aucun démon.
Comment installer feint et vérifier ce qu'on exécute
Section intitulée « Comment installer feint et vérifier ce qu'on exécute »Téléchargez le binaire de la version, vérifiez qui l'a publié, puis vérifiez
les octets. L'ordre compte : une somme de contrôle ne prouve rien si vous ne
savez pas qui a produit la liste qui la contient. La release v0.2.0 publie
les binaires, un fichier checksums.txt, sa signature Sigstore et une
attestation de provenance SLSA.
-
Récupérer les artefacts de la version.
Fenêtre de terminal base=https://github.com/stephrobert/feint/releases/download/v0.2.0curl -fsSLO "$base/feint-linux-amd64"curl -fsSLO "$base/checksums.txt"curl -fsSLO "$base/checksums.txt.cosign.bundle" -
Vérifier la signature de la liste de sommes, avant de faire confiance à une seule ligne de son contenu.
Fenêtre de terminal cosign verify-blob --bundle checksums.txt.cosign.bundle \--certificate-identity-regexp 'https://github.com/stephrobert/feint/.*' \--certificate-oidc-issuer https://token.actions.githubusercontent.com \checksums.txtLa sortie attendue tient en deux mots :
Verified OK. Toute autre réponse doit arrêter l'installation. -
Vérifier les octets contre la liste signée.
Fenêtre de terminal sha256sum -c checksums.txt --ignore-missingLe résultat attendu est
feint-linux-amd64: OK. Sans--ignore-missing, la commande échoue sur toutes les plateformes que vous n'avez pas téléchargées, ce qui ressemble à tort à un binaire corrompu. -
Installer le binaire et confirmer la version.
Fenêtre de terminal install -m 0755 feint-linux-amd64 ~/.local/bin/feintfeint versionLa sortie doit afficher
v0.2.0.
Si vous préférez la provenance à la signature, gh vérifie quel workflow et
quel commit ont produit le binaire :
gh attestation verify feint-linux-amd64 --repo stephrobert/feintComment savoir qu'une nouvelle version est sortie
Section intitulée « Comment savoir qu'une nouvelle version est sortie »Depuis la version 0.2.0, feint version --check demande à GitHub si une
version plus récente existe, et affiche la commande pour l'installer. Deux
principes gouvernent cette commande, et ils méritent d'être connus avant de la
lancer : rien ne part sur le réseau tant que le drapeau n'est pas tapé, et
le binaire ne se met jamais à jour tout seul.
feint version --checkTrois réponses sont possibles selon ce que vous exécutez. Quand une version plus récente est publiée, la sortie donne la commande d'installation épinglée sur cette version précise :
a newer release is available: v0.2.0
base=https://github.com/stephrobert/feint/releases/download/v0.2.0 curl -fsSLO "$base/feint-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')" curl -fsSLO "$base/checksums.txt" sha256sum -c checksums.txt --ignore-missing
release notes: https://github.com/stephrobert/feint/releases/tag/v0.2.0La commande proposée nomme la version, jamais latest. La raison est la
même que dans la procédure d'installation plus haut : une référence mutable
télécharge ce qui est le plus récent au moment de l'appel, et ce contenu ne peut
plus être confronté à la somme de contrôle écrite juste en dessous.
Si vous êtes déjà à jour, la commande rappelle d'abord votre version, puis conclut en une ligne :
v0.2.0this is the latest releaseLe troisième cas concerne les binaires construits localement :
the latest release is v0.2.0 (this build reports "dev", which is not a released version) https://github.com/stephrobert/feint/releases/tag/v0.2.0Un binaire compilé depuis les sources porte dev, et une installation par
go install porte une pseudo-version horodatée. Ni l'un ni l'autre ne se
compare à une étiquette de version, donc l'outil annonce la dernière release
sans prétendre que votre exemplaire est périmé.
Comment vérifier que l'hôte est prêt
Section intitulée « Comment vérifier que l'hôte est prêt »feint doctor inspecte la machine avant que vous ne perdiez du temps. Il
contrôle le port, le runtime de machines disponible et ce qu'il peut
prouver, la présence des clients officiels, et il signale les pièges connus
de l'environnement.
feint doctor 
La lecture est directe : ok valide un point, warn signale quelque
chose qui n'empêche pas de travailler. Sur la capture ci-dessus, deux
avertissements méritent une explication. Le premier, no contracts/ directory here, indique que les réponses ne seront pas confrontées aux descriptions
d'API des fournisseurs, ce qui n'arrive que si vous lancez feint depuis le
dépôt cloné. Le second, le ProxyJump sur 10.*, est un piège réel :
cette plage est celle des réseaux privés émulés, et une règle SSH trop large
fait échouer la connexion avec timed out during banner exchange alors que le
serveur SSH écoute normalement.
Un avertissement ne fait jamais échouer doctor. Seul un élément cassé
produit un code retour non nul, ce qui rend la commande utilisable telle quelle
dans un script d'amorçage.
Comment démarrer l'émulateur
Section intitulée « Comment démarrer l'émulateur »feint start détache le processus lui-même, attend qu'il réponde et indique
où sont les journaux. Aucun &, aucun conteneur, aucun gestionnaire de
services : un binaire Go statique sait se mettre en arrière-plan, là où un
émulateur écrit en Java ou en Python délègue cette tâche à docker run -d.
feint startfeint listening on 127.0.0.1:4599 (pid 1155265) logs: /run/user/1000/feint/127.0.0.1_4599/feint.logL'état se lit avec feint status, qui répond ce qui tourne, ce qui est
monté et ce qu'un client a réellement piloté depuis le démarrage :
feint statusrunning on 127.0.0.1:4599 (pid 1155265, since 2026-07-30T09:39:36Z) resources 21 machines none
provider routes driven by a client scaleway 55 0 outscale 20 0 exoscale 14 0La colonne driven by a client est plus utile qu'elle n'en a l'air : elle
distingue une route montée d'une route exercée, donc elle vous dit ce
que votre test a vraiment traversé. Les autres verbes du cycle de vie sont
feint stop, feint restart, feint logs et feint wait. Ce dernier
interroge l'émulateur jusqu'à ce qu'il réponde : c'est le verbe de CI, celui
qui remplace la boucle curl que chaque équipe finissait par écrire.
Comment brancher le CLI Scaleway
Section intitulée « Comment brancher le CLI Scaleway »feint env scaleway produit l'environnement dont le client officiel a
besoin. La commande n'écrit que des lignes export sur la sortie standard, ce
qui rend eval sûr ; les remarques et avertissements partent sur la sortie
d'erreur.
eval "$(feint env scaleway)"scw instance server create name=web-01 type=DEV1-S image=ubuntu_jammy zone=fr-par-1scw instance server list zone=fr-par-1 
Les variables produites pointent SCW_API_URL sur http://127.0.0.1:4599
et fournissent des identifiants bien formés mais fictifs. C'est suffisant :
les SDK valident la forme des identifiants côté client avant d'émettre
quoi que ce soit, et l'émulateur ne vérifie aucune signature.
Le serveur créé apparaît immédiatement en running dans la liste, alors que
le protocole renvoie bien stopped à la création. L'explication n'est
pas dans l'émulateur : scw instance server create envoie une action de
démarrage juste après la création. Interrogé directement, l'émulateur répond
ce que répondrait Scaleway :
curl -s -X POST "http://127.0.0.1:4599/instance/v1/zones/fr-par-1/servers" \ -H 'Content-Type: application/json' \ -d '{"name":"etat-initial","commercial_type":"DEV1-S","image":"ubuntu_jammy"}' \ | jq -c '{name: .server.name, state: .server.state}'{"name":"etat-initial","state":"stopped"}Comment brancher Outscale et Exoscale
Section intitulée « Comment brancher Outscale et Exoscale »Les deux autres fournisseurs se branchent de la même façon, avec une nuance
par client. feint env la signale sur la sortie d'erreur au lieu de vous
laisser la découvrir.
Le client oapi-cli lit un profil JSON plutôt que l'environnement. La
remarque affichée par feint env outscale le précise : il faut lui passer
--config avec endpoints.api sur http://127.0.0.1:4599, le client
ajoutant /api/v1 de lui-même.
eval "$(feint env outscale)"oapi-cli CreateNet --IpRange 10.0.0.0/16oapi-cli ReadNets{ "Nets":[ { "IpRange":"10.0.0.0/16", "NetId":"vpc-3a31b260", "State":"available", "Tags":[], "Tenancy":"default" } ], "ResponseContext":{"RequestId":"3b25f637-a288-4839-b4aa-c3b1a709f6bb"}}Le CLI exo prend son point d'accès dans son fichier de
configuration, où endpoint doit valoir http://127.0.0.1:4599/v2. Notez le
suffixe /v2, qui fait partie de l'adresse chez ce fournisseur.
eval "$(feint env exoscale)"exo compute instance-type list| ID | FAMILY | SIZE ||--------------------------------------|----------|-------|| 21624abb-764e-4def-81d7-9fc54b5957fb | standard | tiny || b6cd1ff5-3a2f-4e9d-a4d1-8988c1191fe8 | standard | small |Deux types d'instances seulement : c'est le catalogue figé de l'émulateur, pas l'inventaire d'Exoscale. La section sur les limites détaille ce point.
Comment appliquer une configuration Terraform
Section intitulée « Comment appliquer une configuration Terraform »Le provider Scaleway se détourne avec un seul réglage, api_url. Le reste
de la configuration reste celle que vous écririez pour le vrai fournisseur, ce
qui est tout l'intérêt : vous testez le code que vous déploierez.
terraform { required_providers { scaleway = { source = "scaleway/scaleway" version = "~> 2.79" } }}
provider "scaleway" { access_key = "SCWXXXXXXXXXXXXXXXXX" secret_key = "11111111-1111-1111-1111-111111111111" project_id = "11111111-1111-1111-1111-111111111111" organization_id = "99999999-9999-4999-8999-999999999999" region = "fr-par" zone = "fr-par-1"
api_url = "http://127.0.0.1:4599"}
resource "scaleway_vpc" "lab" { name = "lab-feint"}
resource "scaleway_vpc_private_network" "lab" { name = "reseau-interne" vpc_id = scaleway_vpc.lab.id}
resource "scaleway_instance_server" "web" { name = "web-terraform" type = "DEV1-S" image = "ubuntu_jammy"}L'application se déroule sans adaptation particulière :
terraform initterraform apply -auto-approveApply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
private_network_id = "fr-par/a0fa6f82-2aad-4f82-985a-2abeb65f05f7"server_id = "fr-par-1/d2303f04-8ab3-4e71-a682-ad91c81286b7"Les identifiants renvoyés portent le préfixe de région ou de zone, comme
chez Scaleway. Un terraform destroy fonctionne symétriquement, ce qui
permet de valider un cycle complet dans une CI sans créer la moindre
ressource facturée. Pour la construction des configurations elles-mêmes, la
section Terraform du site
couvre le sujet en profondeur.
Comment obtenir de vraies machines derrière l'API
Section intitulée « Comment obtenir de vraies machines derrière l'API »Par défaut, feint est un plan de contrôle : il répond, et rien ne tourne. Donnez-lui un runtime et un serveur créé devient un conteneur ou une machine virtuelle réelle, sur un vrai pont réseau, portant l'adresse que l'API a publiée. C'est la différence entre un émulateur et un simple serveur de maquettes.
Les quatre modes ne délivrent pas la même chose, et un seul écart compte vraiment :
--vm | Machines | Adresses | Pare-feu | Isolation inter-VPC | Noyau propre | Nécessite |
|---|---|---|---|---|---|---|
off (défaut) | non | non | non | non | non | rien |
incus | oui | oui | oui | non | non | Incus 6.0.4+ |
incus-vm | oui | oui | oui | non | oui | Incus + KVM |
incus-ovn | oui | oui | oui | oui | non | Incus + OVN |
L'isolation est la seule capacité qui change de verdict selon le mode. Deux réseaux privés de deux VPC différents ne doivent pas se joindre. En mode pont, ils se joignent, et la cause est documentée par le runtime lui-même : le trafic entre ponts gérés sur un même hôte est routé directement. Un réseau OVN est un réseau logique doté de son propre routeur, donc la séparation vient de la topologie et non d'une règle.
Plutôt que de deviner, demandez à l'émulateur ce que son mode sait prouver :
feint start --vm incuscurl -s localhost:4599/_feint/health | jq -c '.capabilities'{"machines":true,"addresses":true,"firewall":true,"isolation":false,"own_kernel":false}Le même appel en --vm incus-ovn renvoie "isolation":true. Cette
déclaration est faite pour être lue par vos tests : une suite qui compare un
nom de mode en dur doit être modifiée à chaque évolution, une suite qui lit
les capacités continue de fonctionner.
Comment installer Incus et OVN sur Debian 13
Section intitulée « Comment installer Incus et OVN sur Debian 13 »Debian 13 est la distribution la plus simple pour ce mode, et la procédure
tient en trois temps : le dépôt, les paquets, le câblage OVN. C'est ce dernier
que personne ne devine, et sans lui incus network create --type=ovn échoue
avec une erreur qui ne nomme ni la cause ni le réglage manquant.
Un mot sur le choix du dépôt, parce qu'il se discute. Debian 13 « trixie »
package Incus 6.0.4, exactement le plancher en dessous duquel les listes
de contrôle d'accès sur une interface sont refusées. Le paquet de la
distribution suffit donc, contrairement à Ubuntu 24.04 qui livre 6.0.0 et ne
bougera plus. Le dépôt Zabbly, publié par le mainteneur d'Incus, apporte la
série 7.2 recommandée, celle sur laquelle les mesures du projet ont été
faites. Sur ma VM Debian 13, apt-cache policy incus affiche bien
6.0.4-2+deb13u8 avant l'ajout du dépôt.
-
Installer les prérequis et récupérer la clé du dépôt dans son propre trousseau. Une clé déposée dans
/etc/apt/keyringsne signe que le dépôt qui la nomme, là où le magasin système vaudrait pour tout.Fenêtre de terminal apt-get updateapt-get install -y --no-install-recommends ca-certificates curl gpg uidmapmkdir -p /etc/apt/keyringscurl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.ascgpg --show-keys --with-fingerprint /etc/apt/keyrings/zabbly.ascVérifiez l'empreinte affichée avant de continuer : elle doit valoir
4EFC 5906 96CB 15B8 7C73 A3AD 82CC 8797 C838 DCFD, pourZabbly Kernel Builds. C'est le seul moment où vous décidez à qui vous faites confiance. -
Déclarer le dépôt, en dérivant la suite et l'architecture de la machine plutôt qu'en les écrivant en dur.
Fenêtre de terminal cat > /etc/apt/sources.list.d/zabbly-incus.sources <<EOFEnabled: yesTypes: debURIs: https://pkgs.zabbly.com/incus/stableSuites: $(. /etc/os-release && echo "$VERSION_CODENAME")Components: mainArchitectures: $(dpkg --print-architecture)Signed-By: /etc/apt/keyrings/zabbly.ascEOFSur Debian 13,
Suitesvauttrixie. Aucuncurl | shdans cette procédure : chaque fichier est écrit sur disque, et la clé est vérifiée avant que le moindre paquet n'arrive. -
Installer Incus, OVN et Open vSwitch. Incus vient de Zabbly, les paquets OVN de Debian.
Fenêtre de terminal apt-get updateapt-get install -y --no-install-recommends \incus incus-client ovn-central ovn-host openvswitch-switchContrôle immédiat :
incus --versiondoit répondre7.2etovn-nbctl --versionovn-nbctl 25.03.0sur une trixie à jour. -
Démarrer les services, puis attendre. Les unités systemd rendent la main avant que les bases de données OVN n'écoutent, et une commande lancée dans cet intervalle échoue sans raison apparente.
Fenêtre de terminal systemctl enable --now openvswitch-switch ovn-central ovn-hostwhile [ ! -S /run/ovn/ovnnb_db.sock ]; do sleep 1; done -
Indiquer à Open vSwitch où se trouve la base southbound. C'est la moitié du câblage, celle qui relie le commutateur au plan de contrôle OVN.
Fenêtre de terminal ovs-vsctl set open_vswitch . \external_ids:ovn-remote=unix:/run/ovn/ovnsb_db.sock \external_ids:ovn-encap-type=geneve \external_ids:ovn-encap-ip=127.0.0.1 -
Initialiser Incus, puis donner au pont d'uplink la plage que les réseaux OVN viendront y découper.
Fenêtre de terminal incus admin init --minimalincus network set incusbr0 ipv4.address=10.108.0.1/24incus network set incusbr0 \ipv4.dhcp.ranges=10.108.0.10-10.108.0.99 \ipv4.ovn.ranges=10.108.0.100-10.108.0.199L'adresse se fixe dans une commande séparée des plages : celles-ci sont validées contre l'adresse courante du pont, et
incus admin init --minimalen choisit une au hasard. Sansipv4.ovn.ranges, la création d'un réseau OVN est refusée avec un message qui accuse le réseau plutôt que le pont. -
Vérifier par un vrai réseau, pas par la liste des paquets installés.
Fenêtre de terminal incus network create ovntest --type=ovn network=incusbr0incus network delete ovntestNetwork ovntest createdvalide l'ensemble du câblage. C'est le seul contrôle qui prouve quelque chose : des paquets installés mais mal reliés passent tous les autres.
Ne désactivez pas AppArmor. La tentation existe, parce que l'intégration continue du projet OVN coupe AppArmor avant ses tests système. Ce contournement vise des binaires compilés depuis les sources, hors des chemins couverts par les profils packagés. Une installation par paquets embarque les profils dont elle a besoin : sur la VM de test, Incus, OVN et Open vSwitch fonctionnent tous avec AppArmor actif. Couper un contrôle d'accès obligatoire pour faire tourner un outil de test est un mauvais échange.
Le verdict final ne se lit pas dans apt, mais dans la capacité déclarée :
feint doctor --vm autofeint start --vm autocurl -s localhost:4599/_feint/health | jq -c '.machines, .capabilities.isolation'Sur la VM Debian 13 fraîchement installée, doctor annonce machine runtime: incus-ovn avec isolation true, et l'API de santé confirme
"incus-ovn" puis true. Une valeur false signifie qu'OVN est absent,
ou présent mais non câblé.
La machine porte-t-elle vraiment l'adresse publiée ?
Section intitulée « La machine porte-t-elle vraiment l'adresse publiée ? »Oui, et cela se vérifie en trois commandes. Créez un réseau privé sur un bloc choisi, rattachez-y un serveur, démarrez-le, puis demandez au runtime, pas à l'émulateur, ce que la machine porte.
# le bloc demandé est le bloc obtenucurl -s -X POST "http://127.0.0.1:4599/vpc/v2/regions/fr-par/private-networks" \ -H 'Content-Type: application/json' \ -d '{"name":"lab","subnets":["10.51.0.0/24"]}' | jq -c '{id, subnet: .subnets[0].subnet}'
# ce que l'API publiecurl -s "http://127.0.0.1:4599/ipam/v1/regions/fr-par/ips" | jq -r '.ips[0].address'
# ce que la machine porte, vu du runtimeincus exec "feint-scw-<id-du-serveur>" -- ip -4 -o addr showSur mon poste, l'IPAM publie 10.51.0.2/24 et le conteneur porte
10.51.0.2/24 : les deux adresses coïncident. Le même essai en
--vm incus-ovn donne 10.52.0.2/24 des deux côtés. La machine créée
s'appelle feint-scw-<identifiant du serveur>, ce qui permet de la retrouver
sans chercher.
Tout ce que l'émulateur crée est étiqueté, et feint clean retire
exactement ces objets, sans toucher au reste de votre hôte :
feint clean --vm incusremoved 1 machine(s), 1 network(s), 1 rule set(s)Si Incus n'est pas encore installé sur votre poste, la section Incus du site couvre la mise en place.
Comment revenir à un état connu
Section intitulée « Comment revenir à un état connu »feint snapshot nomme l'état d'un émulateur en cours et permet d'y
revenir. C'est le mécanisme qui rend un jeu de données de test atteignable une
fois puis rejouable autant de fois que nécessaire.
feint snapshot save etat-de-referencefeint snapshot listsaved 21 resources to /home/bob/.local/state/feint/snapshots/etat-de-reference.json
NAME RESOURCES BYTES SAVEDetat-de-reference 21 26472 2026-07-30T09:43:40ZAprès avoir supprimé toutes les ressources, feint snapshot load etat-de-reference répond loaded etat-de-reference: the emulator now holds 21 resources et l'inventaire est reconstitué. Le chargement remplace
l'état, il ne fusionne pas : un jeu de test ne doit pas dépendre de ce que
la session a fait avant lui.
Ce que feint ne fait pas
Section intitulée « Ce que feint ne fait pas »La couverture est partielle, et elle est mesurée plutôt qu'annoncée. En v0.2.0, 89 routes sont montées au total. Le tableau ci-dessous reprend la maturité déclarée par le projet et la part de la surface amont réellement servie :
| Fournisseur | Routes montées | Surface amont servie | Maturité | Prouvé par |
|---|---|---|---|---|
| Scaleway | 55 | 27 % | utilisable | scw, Terraform, OpenTofu |
| Outscale | 20 | 7 % | démarrage | oapi-cli |
| Exoscale | 14 | 3 % | aperçu | exo |
Utilisable signifie qu'une configuration réaliste s'applique et se détruit. Les deux autres niveaux veulent dire que le protocole est juste mais que la surface est mince. Concrètement, visez Scaleway pour un usage sérieux aujourd'hui, et considérez Outscale et Exoscale comme des chantiers ouverts.
Cinq limites méritent d'être connues avant de vous appuyer sur l'outil. Elles sont toutes vérifiables en quelques commandes.
Les identifiants ne sont validés contre rien. Une création qui nomme une image inexistante réussit, là où le vrai cloud refuserait :
scw instance server create name=fantome type=DEV1-S \ image=00000000-dead-beef-0000-000000000000 zone=fr-par-1C'est délibéré, parce que l'émulateur n'a pas d'inventaire : refuser les identifiants inconnus casserait toute configuration qui référence une image de production. Le coût est réel : une faute de frappe dans un identifiant d'image passera ici et sera rattrapée en production.
Le catalogue est une fiction. Types de serveurs, prix, images et zones forment une petite table figée. Elle existe parce que les clients la lisent avant de créer quoi que ce soit, mais toute réponse de capacité, de prix ou de disponibilité est décorative.
L'authentification est acceptée, jamais vérifiée. Aucune signature n'est contrôlée, sur aucun fournisseur :
curl -s -o /dev/null -w '%{http_code}\n' \ "http://127.0.0.1:4599/instance/v1/zones/fr-par-1/servers"La réponse est 200, sans le moindre jeton. feint ne doit donc jamais
être exposé sur un réseau que vous ne maîtrisez pas : c'est un outil de
développement qui accorde tout à tout le monde, par construction. Il écoute sur
127.0.0.1 par défaut, et c'est une décision de sécurité, pas un détail
de configuration.
Les transitions de cycle de vie sont immédiates. Un serveur passe de
stopped à running pendant l'appel. Les états que les clients vérifient
sont en revanche préservés : supprimer un serveur démarré est refusé avec
{"type":"transient_state"}, parce que Terraform s'appuie sur cette erreur.
Le stockage objet n'est pas émulé. Le provider Terraform Scaleway construit
l'adresse S3 en dur dans son code, donc la détourner demanderait une
interception DNS et un certificat TLS accepté par le provider. Le CLI et les
SDK, eux, honorent SCW_S3_ENDPOINT et peuvent déjà pointer vers un MinIO
local.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause | Solution |
|---|---|---|
404 Not Found sur scw instance server-type list | Le CLI interroge /product-catalog/v2alpha1/, une API récente que l'émulateur ne monte pas | Utiliser scw marketplace local-image list, ou consulter curl -s localhost:4599/_feint/routes |
Feint does not serve /marketplace/v2/images | La route demandée n'existe pas dans le paquet ; le message le dit explicitement | Vérifier la route dans /_feint/routes avant d'insister |
feint: no contract under contracts sur feint probe | probe a besoin des descriptions d'API livrées avec le dépôt | Lancer depuis le dépôt cloné, ou passer --contracts <répertoire> |
warn no contracts/ directory here dans doctor | Même cause, en avertissement | Sans effet si vous ne validez pas les réponses contre les contrats |
gh attestation verify ne renvoie rien | Hors terminal interactif, la commande ne s'exprime que par son code retour | Contrôler echo $? ou ajouter --format json |
timed out during banner exchange en SSH vers une machine | Un ProxyJump du fichier ~/.ssh/config capture la plage 10.* des réseaux émulés | Restreindre le motif Host, ou utiliser ssh -F /dev/null |
Multiple variable sources detected avec Terraform | Un profil Scaleway existe déjà sur le poste | Lire la colonne Currently using : le bloc provider l'emporte |
Un mode --vm ne sépare pas deux VPC | Le mode pont ne fournit pas l'isolation | Lire capabilities.isolation dans /_feint/health, et passer en --vm incus-ovn |
À retenir
Section intitulée « À retenir »- feint émule Scaleway, Outscale et Exoscale sur un seul port,
127.0.0.1:4599, sans compte ni facture. - Un binaire Go statique qui se détache seul : ni Docker, ni démon, ni dépendance externe.
- Les CLI officiels fonctionnent tels quels :
feint env <fournisseur>produit l'environnement attendu,evalsuffit. - Terraform s'y branche avec
api_url, et un cycleapplypuisdestroycomplet passe. - Le mode machines est réel : le conteneur porte l'adresse publiée par l'API, et
feint cleanne retire que ce que l'émulateur a créé. - Seul
--vm incus-ovnisole deux VPC ; interrogezcapabilitiesplutôt que de supposer. feint version --check(depuis la 0.2.0) signale une nouvelle version et donne la commande épinglée ;FEINT_NO_UPDATE_CHECK=1coupe tout appel réseau.- La couverture est partielle et assumée : 27 % de la surface Scaleway, 7 % chez Outscale, 3 % chez Exoscale.
- Aucune signature n'est vérifiée : l'outil reste sur la boucle locale, jamais sur un réseau partagé.