Sicherstellen einer wiederholbaren Verzeichnisreihenfolge unter Linux

16

Ich leite ein gehostetes Unternehmen für kontinuierliche Integration , und wir führen den Code unserer Kunden unter Linux aus. Jedes Mal, wenn wir den Code ausführen, führen wir ihn in einer separaten virtuellen Maschine aus. Ein häufig auftretendes Problem besteht darin, dass die Tests eines Kunden manchmal aufgrund der Verzeichnisreihenfolge des auf der VM ausgecheckten Codes fehlschlagen.

Lassen Sie mich näher darauf eingehen. Unter OSX stellt das HFS + -Dateisystem sicher, dass Verzeichnisse immer in derselben Reihenfolge durchsucht werden. Programmierer, die OSX verwenden, gehen davon aus, dass es überall funktionieren muss, wenn es auf ihrem Computer funktioniert. Unter Linux funktioniert dies jedoch häufig nicht, da Linux-Dateisysteme beim Durchlaufen von Verzeichnissen keine Bestellgarantien bieten.

Angenommen, es gibt 2 Dateien, a.rb, b.rb. a.rb definiert MyObjectund b.rb verwendet MyObject. Wenn a.rb zuerst geladen wird, funktioniert alles. Wenn b.rb zuerst geladen wird, versucht es, auf eine undefinierte Variable zuzugreifen MyObject, und schlägt fehl.

Aber schlimmer als das ist, dass es nicht immer nur scheitert. Da die Dateisystemreihenfolge unter Linux nicht geordnet ist, wird die Reihenfolge auf verschiedenen Computern unterschiedlich sein. Das ist schlimmer, weil manchmal die Tests bestanden werden und manchmal scheitern. Dies ist das schlechteste mögliche Ergebnis.

Meine Frage ist also, gibt es eine Möglichkeit, die Bestellung von Dateisystemen wiederholbar zu machen. Ein Flag für ext4, das besagt, dass Verzeichnisse immer in einer bestimmten Reihenfolge durchlaufen werden? Oder vielleicht ein anderes Dateisystem, das diese Garantie hat?

Paul Biggar
quelle
Neben den wirklich zutreffenden Antworten - was ist die "richtige" Reihenfolge? Nur alphanumerisch sortiert? Oder von CTIME? Beliebig magisch? Wie stellen die Kunden diese Bestellung bei der Bereitstellung sicher? Wie sollen diese magischen Bestellinformationen an Sie übermittelt werden?
Michuelnik
@Michuelnik Es gibt keine richtige Reihenfolge, aber etwas Wiederholbares würde bedeuten, dass wir jedes Mal das gleiche Ergebnis erzielen, was besser wäre als nichts. Idealerweise verwenden wir die HFS + -Ordnung, die meiner Meinung nach alphabetisch ist.
Paul Biggar
@Michuelnik Dieses Problem betrifft Tests viel mehr als die Bereitstellung. Die Bereitstellung erfolgt hauptsächlich unter Linux. Wenn jedoch ein Fehler auftritt, wird das Problem behoben. Die meisten Tests werden unter OSX ausgeführt. Wenn also etwas fehlschlägt, muss es unsere Schuld sein.
Paul Biggar
1
@PaulBiggar: Ich verstehe Ihr Problem und kann keine gute Lösung anbieten (es sei denn, Sie können feststellen , ob die Reihenfolge der Dateien die Ursache des Problems ist). Ich bin jedoch nicht der Meinung, dass "wiederholbarer Erfolg besser ist als inkonsistenter Ausfall": Wenn meine Entwicklungsumgebung (und meine CI-Umgebung) wiederholbar erfolgreich sind, meine Bereitstellungsplattform jedoch das Syndrom "unzuverlässiger Ausfall" aufweist, bin ich wirklich in einer schlechten Situation. Ich würde es vorziehen , den unzuverlässigen Fehler so schnell wie möglich zu sehen (idealerweise auf meinem Entwicklungssystem, aber zumindest auf meinem CI-System).
Joachim Sauer

Antworten:

16

Ich weiß, es ist nicht die Antwort, die Sie suchen, aber ich glaube, die richtige Lösung ist es , abhängig von der Reihenfolge der Dateien in einem Verzeichnis zu vermeiden . Vielleicht ist es immer für alle HFS + -Dateisysteme konsistent, und vielleicht können Sie auch eine Möglichkeit finden, es in ext4 oder einem anderen Dateisystem konsistent zu machen, aber es kostet Sie auf lange Sicht mehr Ärger als es spart. Jemand anders, der Ihre Anwendung verwendet, wird eine böse Überraschung erleben, wenn er nicht merkt, dass sie nur mit einigen Arten von Dateisystemen kompatibel ist und nicht mit anderen. Die Reihenfolge kann sich ändern, wenn ein Dateisystem aus einer Sicherung wiederhergestellt wird. Wahrscheinlich treten Kompatibilitätsprobleme auf, da die konsistente Reihenfolge von HFS + und ext4 möglicherweise nicht identisch sind.

Lesen Sie einfach alle Verzeichniseinträge und sortieren Sie die Liste lexikografisch, bevor Sie sie verwenden. Genau wie es lstut.

Sie erwähnen Dateien a.rbund b.rb, wenn es sich um Programmiersprachen-Quelldateien handelt, sollte nicht jede Datei bereits dafür verantwortlich sein, dass alle Abhängigkeiten importiert werden?

Celada
quelle
Das Problem ist, dass wir den Code, den wir ausführen, nicht geschrieben haben. Wir führen den Kundencode aus und haben keine Kontrolle darüber, wie der Code geschrieben wurde. Unser Problem ist also, dass wir für das Problem verantwortlich gemacht werden, weil es auf ihrem Computer funktioniert, aber nicht auf unserem. Wenn wir alle dazu zwingen könnten, richtigen Code zu schreiben, würden wir das tun, aber das liegt nicht in unserer Macht :)
Paul Biggar
10
@PaulBiggar: Aber ist "es läuft hier, aber nicht in der Produktion" nicht genau das Problem, das CI beheben soll? Mit anderen Worten: "Warum ist mein Code in Ihrem System kaputt?" sollte mit "Weil wir genau das tun , wonach Sie uns fragen!" ;-)
Joachim Sauer
4
Ich kenne niemanden sonst, aber wenn Code auf meinem Computer funktioniert und dann an einem CI oder an der Kasse eines Kollegen fehlschlägt, gehe ich sofort davon aus, dass es etwas Plattform- oder umgebungsabhängiges gibt, das ich beheben muss ...
matt5784
1
Sicherlich ist die Entwicklung der Anwendung auf einer Plattform, die Sie in der Produktion nicht verwenden, eine schlechte Idee? Lassen Sie sie auf derselben Plattform entwickeln, für die sie schreiben.
Matthew Ife
2
Ich stimme dir nicht zu. Ich denke, es ist eine großartige Idee. Beim Übergang von der Entwicklung zu Testservern treten viel mehr Fehler auf. Daher ist der Code wesentlich stabiler, bevor er auf die Produktionsserver verschoben wird. In einer korrekten oder theoretischen Welt ist es also viel besser. Dies ist dieselbe Welt, in der Sie jeden dazu zwingen können, richtigen Code zu schreiben, der auch als Traumland bekannt ist.
Hennes
5

Der POSIX-Aufruf in Linux readdir () garantiert keine konsistente Reihenfolge. Wenn Sie geordnete Ergebnisse wünschen, ist die Anwendung, die Dateien verarbeitet, dafür verantwortlich, zu ordnen, wie sie aufrufenden Funktionen präsentiert werden.

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

Nun, da Sie sagten, dies sei der Code Ihres Kunden und Sie können ihn nicht reparieren, könnten Sie möglicherweise die verknüpften Bibliotheken ändern, die verwendet werden, um einen konsistenten readdir () -Aufruf bereitzustellen. Das würde Arbeit kosten und eine eigene Frage wert sein. Eine Kurzanleitung dazu finden Sie unter http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .

Wenn Sie dies ändern, kann dies zu einer Reihe weiterer Probleme führen, die ich möglicherweise nicht vorhersehen kann. Sie werden stark gewarnt, aber es kann eine Lösung sein, wenn Ihr Kunde nicht richtig geschult werden kann.

Jeff Ferland
quelle
1

Weisen Sie Ihren Kunden darauf hin, dass es eine inhärente Auftragsabhängigkeit gibt, die ausdrücklich angegeben werden sollte. Bieten Sie dem Kunden an, die Abhängigkeit so auszudrücken, dass eine Kompilierung auf allen Systemen funktioniert und der Kunde den geänderten Ablauf übernimmt, der die Abhängigkeit von der Kompilierungsreihenfolge erfasst.

Wenn der Kunde in der Lage sein möchte, auf anderen Maschinen zu kompilieren, wäre es mürrisch, zu glauben, dass es kostenlos ist.

Paddy3118
quelle
Wir werden das definitiv tun. Es wäre jedoch nützlich, wenn sie tatsächlich unser Kunde werden würden, damit wir dies tun können.
Paul Biggar
0

Modernes Linux (ext4) fügt einen B-Tree-Index für Dateilisten hinzu. Einer seiner Effekte ist, dass die Reihenfolge der Standarddateien von einem Hash ihrer Namen abhängt.

Um diese Funktion zu deaktivieren, verwenden Sie:

tune2fs -O ^ dir_index

Jep
quelle