Assurer un classement d'annuaire reproductible sous Linux


16

Je dirige une entreprise d' intégration continue hébergée et nous exécutons le code de nos clients sur Linux. Chaque fois que nous exécutons le code, nous l'exécutons dans une machine virtuelle distincte. Un problème fréquent qui se pose est que les tests d'un client échouent parfois en raison de la commande d'annuaire de leur code extrait sur la machine virtuelle.

Permettez-moi d'aller plus en détail. Sous OSX, le système de fichiers HFS + garantit que les répertoires sont toujours parcourus dans le même ordre. Les programmeurs qui utilisent OSX supposent que si cela fonctionne sur leur machine, cela doit fonctionner partout. Mais souvent, cela ne fonctionne pas sous Linux, car les systèmes de fichiers linux n'offrent pas de garanties de commande lors de la traversée des répertoires.

À titre d'exemple, considérons qu'il existe 2 fichiers, a.rb, b.rb. a.rb définit MyObjectet b.rb utilise MyObject. Si a.rb est chargé en premier, tout fonctionnera. Si b.rb est chargé en premier, il essaiera d'accéder à une variable non définie MyObjectet échouera.

Mais pire que cela, c'est qu'il n'échoue pas toujours. Parce que la commande du système de fichiers sous Linux n'est pas ordonnée, ce sera un ordre différent sur différentes machines. C'est pire parce que parfois les tests réussissent, et parfois ils échouent. C'est le pire résultat possible.

Ma question est donc la suivante: existe-t-il un moyen de rendre la commande du système de fichiers reproductible? Un drapeau vers ext4 peut-être, qui dit qu'il traversera toujours les répertoires dans un certain ordre? Ou peut-être un système de fichiers différent qui a cette garantie?



Outre les réponses vraiment vraies - quel est l'ordre "correct"? Juste trié par ordre alphanumérique? Ou par CTIME? Arbitrairement par magie? Comment les clients assurent-ils cette commande lors du déploiement? Comment ces informations d'ordre magique devraient-elles vous être transférées?
Michuelnik

@Michuelnik Il n'y a pas de véritable ordre correct, mais quelque chose de répétable signifierait que nous obtenons le même résultat à chaque fois, ce qui serait mieux que rien. Idéalement, nous utiliserions l'ordre HFS +, qui, je pense, est alphabétique.
Paul Biggar

@Michuelnik Ce problème affecte les tests beaucoup plus que le déploiement Le déploiement se produit principalement sous Linux, mais si quelque chose échoue, il le corrigera. Les tests s'exécutent principalement sur OSX, donc si quelque chose échoue, cela doit être de notre faute.
Paul Biggar

1
@PaulBiggar: Je comprends votre problème et je ne peux pas proposer une bonne solution (sauf si vous pouvez trouver un moyen de détecter si l'ordre des fichiers est la cause du problème). Mais je ne suis pas d' accord pour dire que "un succès reproductible est meilleur qu'un échec incohérent": si mon environnement de développement (et CI) a un succès reproductible mais que ma plateforme de déploiement a le syndrome "d'échec non fiable", alors je suis vraiment dans une mauvaise situation. Je plutôt voir l'échec peu fiable le plus tôt possible (idéalement sur mon système de développement , mais au moins sur mon système CI).
Joachim Sauer

Réponses:


16

Je sais que ce n'est pas la réponse que vous cherchez, mais je crois que la bonne solution est d' éviter de dépendre de l'ordre des fichiers dans un répertoire. Peut-être qu'il est toujours cohérent dans tous les systèmes de fichiers HFS +, et peut-être pourriez-vous trouver un moyen de le rendre cohérent dans ext4 ou dans un autre système de fichiers, mais cela vous coûtera plus de problèmes à long terme qu'il n'en économisera. Quelqu'un d'autre utilisant votre application sera surpris par une mauvaise surprise lorsqu'il ne réalisera pas qu'il est compatible uniquement avec certains types de systèmes de fichiers et pas avec d'autres. L'ordre peut changer si un système de fichiers est restauré à partir de la sauvegarde. Vous rencontrerez probablement des problèmes de compatibilité car l'ordre cohérent HFS + et l'ordre cohérent ext4 peuvent ne pas être les mêmes.

Il vous suffit de lire toutes les entrées du répertoire et de trier la liste lexicographiquement avant de l'utiliser. Tout comme le lsfait.

Vous parlez de fichiers a.rbet b.rb, mais si nous parlons de fichiers source de langage de programmation, chaque fichier ne devrait-il pas déjà être chargé de s'assurer qu'il importe toutes ses dépendances?


Le problème est que nous n'avons pas écrit le code que nous exécutons. Nous exécutons le code client et nous n'avons aucun contrôle sur la façon dont le code a été écrit. Donc, notre problème est vraiment que nous sommes blâmés pour le problème, car cela fonctionne sur leur machine mais pas sur la nôtre. Si nous pouvions forcer tout le monde à écrire du code correct, nous le ferions, mais ce n'est pas en notre pouvoir :)
Paul Biggar

10
@PaulBiggar: mais "n'est-il pas exécuté ici mais pas en production" n'est-il pas exactement le problème que CI est censé résoudre? En d'autres termes: "Pourquoi mon code casse-t-il dans votre système?" devrait être répondu par "Parce que nous faisons exactement ce que vous nous demandez!" ;-)
Joachim Sauer

4
Je ne connais personne d'autre, mais lorsque le code fonctionne sur ma machine, puis échoue lors de la vérification d'un CI ou d'un collègue, je suppose immédiatement qu'il y a quelque chose de dépendant de la plate-forme ou de l'environnement que je dois corriger ...
matt5784

1
Certes, développer l'application sur une plate-forme que vous n'utiliserez pas en production est une mauvaise idée? Faites-les évoluer sur la même plateforme pour laquelle ils écrivent.
Matthew Ife

2
Je ne suis pas d'accord. Je pense que c'est une excellente idée. Cela fait apparaître beaucoup plus de défauts lors du passage des serveurs de développement aux serveurs de test. Et donc le code est beaucoup plus robuste avant de passer aux serveurs de production. Donc, dans un monde correct ou théorique, c'est beaucoup mieux. C'est le même monde où vous pouvez forcer tout le monde à écrire le code correct, également connu sous le nom de dreamland.
Hennes

5

L'appel POSIX dans Linux readdir () ne garantit aucun ordre cohérent. Si vous voulez des résultats ordonnés, l'application qui gère les fichiers est responsable de l'ordre dans lequel ils sont présentés aux fonctions appelantes.

/programming/8977441/does-readdir-guarantee-an-order

Maintenant, puisque vous avez dit qu'il s'agissait du code de votre client et que vous ne pouvez pas le corriger, vous pouvez éventuellement modifier les bibliothèques liées qui sont utilisées pour fournir un appel readdir () cohérent. Cela demanderait du travail et mériterait sa propre question. Pour une référence rapide à cela, voir http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .

Modifier cela pourrait engendrer d'autres séries entières de problèmes que je ne peux pas prévoir. Vous êtes fortement averti, mais cela peut être une solution si votre client ne peut pas être correctement formé.


1

Informez votre client qu'il existe une dépendance inhérente aux commandes qui doit être explicitement indiquée. Offrez d'aider le client à exprimer la dépendance de telle manière qu'une compilation fonctionne sur tous les systèmes et demandez au client d'adopter le flux modifié qui capture la dépendance de l'ordre de compilation.

Si le client veut être capable de compiler sur d'autres machines, il serait difficile pour lui de penser que c'est gratuit.


Nous allons certainement le faire. Cependant, il serait utile qu'ils deviennent réellement notre client afin que nous puissions le faire.
Paul Biggar

0

Linux moderne (ext4) ajoute un index B-tree pour les listes de fichiers. L'un de ses effets est que l'ordre des fichiers par défaut dépend du hachage de leurs noms.

Pour désactiver cette fonctionnalité, utilisez:

tune2fs -O ^ dir_index

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.