Garantizar un orden de directorio repetible en Linux


16

Dirijo una empresa de integración continua alojada y ejecutamos el código de nuestros clientes en Linux. Cada vez que ejecutamos el código, lo ejecutamos en una máquina virtual separada. Un problema frecuente que surge es que las pruebas de un cliente a veces fallarán debido al pedido del directorio de su código desprotegido en la VM.

Déjame entrar en más detalles. En OSX, el sistema de archivos HFS + garantiza que los directorios se recorran siempre en el mismo orden. Los programadores que usan OSX asumen que si funciona en su máquina, debe funcionar en todas partes. Pero a menudo no funciona en Linux, porque los sistemas de archivos de Linux no ofrecen garantías de pedido al recorrer directorios.

Como ejemplo, considere que hay 2 archivos, a.rb, b.rb. a.rb define MyObject, y b.rb usa MyObject. Si a.rb se carga primero, todo funcionará. Si b.rb se carga primero, intentará acceder a una variable indefinida MyObjecty fallará.

Pero peor que esto, es que no siempre falla. Debido a que el sistema de archivos que ordena en Linux no está ordenado, será un orden diferente en diferentes máquinas. Esto es peor porque a veces las pruebas pasan y otras fallan. Este es el peor resultado posible.

Entonces mi pregunta es, ¿hay alguna manera de hacer que el pedido del sistema de archivos sea repetible? ¿Alguna bandera a ext4 quizás, que dice que siempre atravesará directorios en algún orden? ¿O tal vez un sistema de archivos diferente que tenga esta garantía?



Además de las respuestas realmente verdaderas, ¿cuál es el orden "correcto"? ¿Solo ordenado alfanuméricamente? O por CTIME? ¿Arbitrariamente mágico? ¿Cómo aseguran los clientes este pedido en la implementación? ¿Cómo se le debe transferir esta información de orden mágica?
Michuelnik

@Michuelnik No hay un orden correcto real, pero algo repetible significaría que obtenemos el mismo resultado cada vez, lo que sería mejor que nada. Idealmente, usaríamos el pedido HFS +, que creo que es alfabético.
Paul Biggar

@Michuelnik Este problema afecta las pruebas mucho más que la implementación. La implementación ocurre principalmente en Linux, pero si algo falla, la solucionarán. Las pruebas se ejecutan principalmente en OSX, por lo que si algo falla, debe ser nuestra culpa.
Paul Biggar

1
@PaulBiggar: entiendo su problema y no puedo ofrecer una buena solución (a menos que pueda encontrar una manera de detectar si el orden del archivo es la causa del problema). Pero no estoy de acuerdo con que "el éxito repetible es mejor que el fracaso inconsistente": si mi entorno de desarrollo (y CI) tiene éxito repetible pero mi plataforma de implementación tiene el síndrom "fracaso no confiable", entonces estoy realmente en un mal lugar. Yo más bien cómo se dejan poco fiable, tan pronto como sea posible (idealmente en mi sistema de desarrollo, pero al menos en mi sistema CI).
Joachim Sauer

Respuestas:


16

Sé que no es la respuesta que está buscando, pero creo que la solución correcta es evitar depender del orden de los archivos en un directorio. Tal vez siempre sea consistente en todos los sistemas de archivos HFS +, y tal vez podría encontrar una manera de hacerlo consistente en ext4 o en algún otro sistema de archivos, pero a la larga le costará más problemas de los que ahorrará. Alguien más que use su aplicación se encontrará con una desagradable sorpresa cuando no se dé cuenta de que solo es compatible con algunos tipos de sistemas de archivos y no con otros. El orden puede cambiar si se restaura un sistema de archivos desde la copia de seguridad. Es probable que tenga problemas de compatibilidad porque el orden consistente de HFS + y el orden consistente ext4 podrían no ser los mismos.

Simplemente lea todas las entradas del directorio y ordene la lista lexicográficamente antes de usarla. Al igual quels hace.

Usted menciona archivos a.rby b.rb, pero si estamos hablando de archivos fuente de lenguaje de programación, ¿no debería cada archivo ya ser responsable de garantizar que importe todas sus dependencias?


El problema es que no escribimos el código que estamos ejecutando. Ejecutamos código de clientes y no tenemos control sobre cómo se escribió el código. Entonces, nuestro problema es que nos culpan del problema, porque funciona en su máquina pero no en la nuestra. Si pudiéramos obligar a todos a escribir el código correcto, lo haríamos, pero eso no está a nuestro alcance :)
Paul Biggar

10
@PaulBiggar: ¿pero "no se ejecuta aquí pero no está en producción" exactamente el problema que se supone que arregle CI? En otras palabras: "¿Por qué mi código se rompe en su sistema?" debe responderse con "¡Porque estamos haciendo exactamente lo que nos está pidiendo!" ;-)
Joachim Sauer

44
No conozco a nadie más, pero cuando el código funciona en mi máquina y luego falla en la
verificación de un colector

1
¿Seguramente desarrollar la aplicación en una plataforma que no usará en producción es una mala idea? Haga que se desarrollen en la misma plataforma para la que están escribiendo.
Matthew Ife

2
Estoy en desacuerdo. Creo que es una gran idea. Hace que aparezcan muchas más fallas durante el paso del desarrollo a los servidores de prueba. Y, por lo tanto, el código es mucho más resistente antes de pasar a los servidores de producción. Entonces, en un mundo correcto o teórico, es mucho mejor. Este es el mismo mundo donde puedes obligar a todos a escribir el código correcto, también conocido como Dreamland.
Hennes

5

La llamada POSIX en Linux readdir () no garantiza ningún orden consistente. Si desea resultados ordenados, la aplicación que maneja los archivos es responsable de ordenar cómo se presentan a las funciones de llamada.

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

Ahora, dado que usted dijo que este era el código de su cliente y no puede solucionarlo, podría alterar las bibliotecas vinculadas que se utilizan para proporcionar una llamada readdir () consistente. Eso requeriría algo de trabajo y valdría la pena su propia pregunta. Para una referencia rápida a eso, consulte http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .

Alterar esto podría generar algunas otras series completas de problemas que quizás no pueda prever. Se le recomienda encarecidamente, pero puede ser una solución si su cliente no puede recibir una educación adecuada.


1

Informe a su cliente que existe una dependencia de orden inherente que debe establecerse explícitamente. Ofrezca ayudar al cliente a expresar la dependencia de tal manera que una compilación funcione en todos los sistemas y haga que el cliente adopte el flujo modificado que captura la dependencia del orden de compilación.

Si el cliente desea poder compilar en otras máquinas, sería muy grosero de su parte pensar que es gratis.


Definitivamente vamos a hacer esto. Sin embargo, sería útil si realmente se convirtieran en nuestros clientes para que pudiéramos hacer esto.
Paul Biggar

0

Linux moderno (ext4) agrega un índice de árbol B para listas de archivos. Uno de sus efectos es que el orden de los archivos predeterminados depende de un hash de sus nombres.

Para deshabilitar esta función, use:

tune2fs -O ^ dir_index

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.