Zapewnienie powtarzalnego porządkowania katalogów w systemie Linux

16

Prowadzę hostowaną firmę zajmującą się ciągłą integracją , a także kod naszych klientów w systemie Linux. Za każdym razem, gdy uruchamiamy kod, uruchamiamy go na osobnej maszynie wirtualnej. Częstym problemem, który się pojawia, jest to, że testy klienta czasami kończą się niepowodzeniem z powodu uporządkowania katalogu ich kodu wypisanego na maszynie wirtualnej.

Pozwól mi bardziej szczegółowo. W systemie OSX system plików HFS + zapewnia, że ​​katalogi są zawsze przeglądane w tej samej kolejności. Programiści używający OSX zakładają, że jeśli działa na ich komputerze, musi działać wszędzie. Ale często nie działa w systemie Linux, ponieważ systemy plików Linux nie oferują gwarancji porządkowania podczas przeglądania katalogów.

Jako przykład rozważmy, że istnieją 2 pliki, a.rb, b.rb. a.rb określa MyObject, a b.rb używa MyObject. Jeśli a.rb zostanie załadowany jako pierwszy, wszystko będzie działać. Jeśli b.rb zostanie załadowany jako pierwszy, spróbuje uzyskać dostęp do niezdefiniowanej zmiennej MyObjecti zakończy się niepowodzeniem.

Ale gorsze jest to, że nie zawsze kończy się to niepowodzeniem. Ponieważ porządkowanie systemu plików w systemie Linux nie jest uporządkowane, na różnych komputerach będzie inna kolejność. Jest to gorsze, ponieważ czasami testy przechodzą pomyślnie, a czasem kończą się niepowodzeniem. To najgorszy możliwy wynik.

Moje pytanie brzmi więc, czy istnieje sposób na powtarzalność zamawiania systemu plików. Jakaś flaga do ext4, która mówi, że zawsze będzie przechodzić przez katalogi w określonej kolejności? A może inny system plików, który ma taką gwarancję?

Paul Biggar
źródło
Oprócz naprawdę prawdziwych odpowiedzi - jaki jest „prawidłowy” porządek? Tylko posortowane alfanumerycznie? A może przez CTIME? Arbitralnie magicznie? W jaki sposób klienci zapewniają to zamówienie przy wdrażaniu? W jaki sposób należy przekazać ci te magiczne informacje o zamówieniu?
Michuelnik,
@Michuelnik Nie ma prawdziwej poprawnej kolejności, ale coś powtarzalnego oznaczałoby, że za każdym razem otrzymujemy ten sam wynik, co byłoby lepsze niż nic. Najlepiej byłoby użyć kolejności HFS +, która moim zdaniem jest alfabetyczna.
Paul Biggar,
@Michuelnik Ten problem dotyczy znacznie więcej testów niż wdrażania. Wdrożenie odbywa się głównie w systemie Linux, ale jeśli coś zawiedzie, naprawi to. Testy przeważnie działają na OSX, więc jeśli coś zawiedzie, musi to być nasza wina.
Paul Biggar,
1
@PaulBiggar: Rozumiem twój problem i nie mogę zaoferować dobrego rozwiązania (chyba że znajdziesz sposób na wykrycie, czy przyczyną problemu jest kolejność plików). Ale nie zgadzam się, że „powtarzalny sukces jest lepszy niż niespójny failur”: jeśli moje środowisko programistyczne (i CI) ma powtarzalny sukces, ale moja platforma wdrażania ma syndrom „niewiarygodnego niepowodzenia”, to jestem naprawdę w złym miejscu. Bym raczej zobaczyć awarię nierzetelne jak najszybciej (najlepiej w moim systemie rozwoju, ale przynajmniej w moim systemie CI).
Joachim Sauer

Odpowiedzi:

16

Wiem, że nie jest to odpowiedź, której szukasz, ale uważam, że właściwym rozwiązaniem jest unikanie zależności od kolejności plików w katalogu. Być może zawsze jest spójny we wszystkich systemach plików HFS +, a może możesz znaleźć sposób, aby uczynić go spójnym w ext4 lub innym systemie plików, ale na dłuższą metę będzie cię to kosztowało więcej kłopotów niż zaoszczędzi. Ktoś inny korzystający z Twojej aplikacji spotka się z przykrą niespodzianką, gdy nie zorientuje się, że jest kompatybilny tylko z niektórymi systemami plików, a nie innymi. Kolejność może ulec zmianie, jeśli system plików zostanie przywrócony z kopii zapasowej. Prawdopodobnie wystąpią problemy ze zgodnością, ponieważ kolejność zgodna z HFS + i kolejność zgodna z ext4 mogą nie być takie same.

Po prostu przeczytaj wszystkie wpisy katalogu i posortuj listę leksykograficznie przed użyciem. Tak jak lsrobi.

Wspomnieć pliki a.rbi b.rb, ale jeśli mówimy o programowaniu plików źródłowych języka, nie każdy plik powinien już być odpowiedzialny za zapewnienie, że importuje wszystkie zależności?

Celada
źródło
Problem polega na tym, że nie napisaliśmy kodu, który uruchamiamy. Prowadzimy kod klienta i nie mamy kontroli nad sposobem pisania kodu. Więc naszym problemem jest to, że jesteśmy obwiniani za problem, ponieważ działa on na ich komputerze, ale nie na naszym. Gdybyśmy mogli zmusić wszystkich do napisania poprawnego kodu, zrobilibyśmy to, ale nie leży to w naszej mocy :)
Paul Biggar
10
@PaulBiggar: ale czy „problem nie działa tutaj, ale nie w produkcji” nie jest dokładnie problemem, który CI powinien rozwiązać? Innymi słowy: „Dlaczego mój kod psuje się w twoim systemie?” należy odpowiedzieć: „Ponieważ robimy dokładnie to , o co nas prosisz!” ;-)
Joachim Sauer
4
Nie wiem o nikim innym, ale kiedy kod działa na moim komputerze, a następnie kończy się niepowodzeniem w przypadku transakcji CI lub kolegi, natychmiast zakładam, że istnieje coś zależnego od platformy lub środowiska, które muszę naprawić ...
matt5784
1
Z pewnością tworzenie aplikacji na platformie, której nie będziesz używać w produkcji, to zły pomysł? Pozwól im się rozwijać na tej samej platformie, dla której piszą.
Matthew Ife,
2
Nie zgadzam się. Myślę, że to świetny pomysł. Powoduje to, że podczas przechodzenia od programowania do testowania serwerów pojawia się znacznie więcej błędów. Dzięki temu kod jest znacznie bardziej wytrzymały, zanim zostanie przeniesiony na serwery produkcyjne. Tak więc w poprawnym lub teoretycznym świecie jest znacznie lepiej. To ten sam świat, w którym możesz zmusić wszystkich do napisania poprawnego kodu, znanego również jako kraina marzeń.
Hennes,
5

Wywołanie POSIX w readdir () w Linuksie nie gwarantuje spójnego uporządkowania. Jeśli chcesz uporządkować wyniki, aplikacja obsługująca pliki jest odpowiedzialna za uporządkowanie sposobu, w jaki są prezentowane funkcjom wywołującym.

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

Ponieważ powiedziałeś, że to kod klienta i nie możesz go naprawić, możesz zmienić połączone biblioteki, które służą do zapewnienia spójnego wywołania readdir (). Zajmie to trochę pracy i będzie warte własnego pytania. Szybkie odniesienie do tego można znaleźć na stronie http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .

Zmiana tego może spowodować powstanie całej innej serii problemów, których być może nie będę w stanie przewidzieć. Ostrzegamy Cię, ale może to być rozwiązanie, jeśli Twój klient nie może być odpowiednio wykształcony.

Jeff Ferland
źródło
1

Poinformuj swojego klienta, że ​​istnieje nieodłączna zależność od zamówienia, którą należy wyraźnie stwierdzić. Zaoferuj, aby pomóc klientowi wyrazić zależność w taki sposób, aby kompilacja działała na wszystkich systemach i aby klient przyjął zmieniony przepływ, który przechwytuje zależność od kolejności kompilacji.

Jeśli klient chce mieć możliwość kompilacji na innych komputerach, byłoby z ich strony przekonywanie, że przychodzi za darmo.

Paddy3118
źródło
Na pewno to zrobimy. Przydałoby się jednak, gdyby faktycznie zostali naszymi klientami, abyśmy mogli to zrobić.
Paul Biggar,
0

Współczesny Linux (ext4) dodaje indeks B-drzewa dla list plików. Jednym z jego efektów jest domyślna kolejność plików zależna od skrótu ich nazw.

Aby wyłączyć tę funkcję, użyj:

tune2fs -O ^ katalog_dysku

tak
źródło