Будни опенсорса

Привет, тора гой дневничок. В этот чудесный уже не снежный апрельский день хотелось бы порассуждать и немножечко унизить весь этот ваш опенсорц-коммунити. И я вам сейчас таки расскажу, поцчиму.

Нельзя переоценить влияние опенсорца на разные тусовки™, энтузиазм и упоротость того же Линуса нашего Торвалдса породили линупсы и все что с ними связано. Собственно куча инфраструктуры наворочено уже вокруг этих всех приложений, клаудов и так далее - и в связи с этим засильем опенсорца в практически всех без исключения разработках - наступает эпоха Невидимого Пиздеца. Который уже здесь, вот он.

Традиционно проблемы, связанные с опенсорцом - принято относить к тому, что в каком-то openssl нашли очередной heartbleed, или что в java появилась очередная бяка. Это все суть ошибки программистов, разной степени вовлеченности в DNA. С ними народ научился более-менее жЫдь.

В последние несколько лет очень модным направлением стало всякое *aS(as Service), ну типа там SaaS, PaaS etc. Некоторым образом это перекликается с Web 2.0, который вроде бы как наступил, а вроде бы как его сменил Web 3.0, а то и Web 4.0, что бы это не значило.

Товарищи из ZeroTurnaround пошли еще дальше - а что будет, если мы короче такие опа - и прям библиотеки будем подключать удаленно? Идея вроде бы и хорошая, и даже годная, и не то чтобы совсем новая - RMI и загрузку классов по HTTP придумали более 10 лет тому взад - но как любая идея в руках с радиусом кривизны сильно отличным от бесконечности иногда доставляет. Так, товарищи из NodeJS обычно грузят все самое дорогое из NPM, и все у них хорошо. Было до момента, когда один товарищ не распаблишил свой проект. Волны говна на вентилятор получились отменные, товарищ получил свой час славы во всем твиттере.

Но все это было преамбула, фабула будет ниже, с описаниями кровавой борьбы за вселенское добро против локального зла.

История первая, или FFMPEG наше все.

Сегодня не использовать ffmpeg в продакшне день не все могут. Вернее, использовать могут не только лишь все, мало кто может это делать.

Эту цитату великого классика и достойнейшего представителя Киевских мэров со связями в космосе вполне можно применить к истории про нежную любовь к FFMPEG. Если надо обработать видео, или сделать там всякие эффекты, или перекодировать одно в другое - и притом быстро, надежно и в больших объемах - часто выбирают этот офигенский пакет.

Вот и я выбрал, чтобы на сервере уметь генерировать разные видеофайлы из JSON документов хитрыми способами. В течение трех лет все работало отлично. На прошлой неделе после очередной выкатки тестовой площадки - все умерло. Причем умерло довольно неожиданно и смешно.

Unsafe file name '/tmp/23635991676764/0.mp4'
/tmp/23635991676764/input.txt: Operation not permitted

Все, приехали. Что, как, почему? Смотрел пермишны на /tmp (а то мало ли), смотрел права на запуск ffmpeg, смотрел что там в файле со списком файлов для конкатенации - все хорошо, но не работает. Тесты при этом зеленые. Мистическая мистика решается просто - запросом у в гугель. И как бы внезапно весь этот опенсорц показывается с неожиданной стороны. Девелоперы FFMPEG почесали репу и решили - а пусть теперь по умолчанию нельзя задавать полные пути к файлам. Ну потому что идите вы на хуй, вот почему. Решено - сделано, и вот чудный патч попал в апстрим. Вполне предсказуемо, что у чуваков, которые ранее пользовались ffmpeg и горя не знали - во всяких местах начало все отваливаться в страшной агонии. Про эту проблему в рассылку юзер написал письмо “чоэтааа”. И конечно же ему тут же прилетело

I also notice that you did not answer the other, "RTFM", part of my message.

Ну как бы вот. Хотим - удаляем репу из репозитория. Хотим - меняем значение опции по умолчанию, причем так, что FFMPEG тупо останавливает работу и выходит с ошибкой. Потому что можем, вот почему!

История вторая, или война с ветряными мельницами в Docker контейнере.

Всякий уважающий себя хипстор и не только - просто обязан присовывать в контейнеры. Причем неважно, надо оно там или не надо, если нет докера - то не феншуй, ретроградство и общественная обструкция. Ну раз надо, значит надо, тем более что местные одмины меня убедили что докер - это не просто феншуй, но вообще православно и все так делают, одни мы по-старинке все rsync-ом да ансиблом.

Ну думаю, ок. Собрал контейнеров, попробовал - работает, крутотень! Взапилили на тестовый кластер - работает. Выпили, собрались с силами - запилили на продакшн. Опять работает. “Аа бля - сказали суровые сибирские лесорубы” - и собссно забыли.

Но мы про кластер-то забыли, а кластер про нас - нет. И в какой-то момент оно все резко накрылось ЖПП. После очередного редеплоя в тестовый кластер - все умерло настолько ярко и красочно, с брызгами и фейерверком, что даже я удивился. Упала JVM. Вся. На всех нодах, одновременно. В коредамп, все как положено.

Stack: [0x00007f90f0777000,0x00007f90f0878000], sp=0x00007f90f0874760, free space=1013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libawt_headless.so+0x493a] Java_sun_awt_FcFontManager_getFontPathNative+0x1aa
j sun.awt.FcFontManager.getFontPathNative(ZZ)Ljava/lang/String;+0
j sun.awt.X11FontManager.getFontPath(Z)Ljava/lang/String;+8
j sun.font.SunFontManager.getPlatformFontPath(Z)Ljava/lang/String;+10
j sun.font.SunFontManager$10.run()Ljava/lang/Object;+21
v ~StubRoutines::call_stub
V [libjvm.so+0x68c616] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x1056
V [libjvm.so+0x7252dc] JVM_DoPrivileged+0x27c
J 403 java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object; (0 bytes) @ 0x00007f91291f5aff [0x00007f91291f5a40+0xbf]
j sun.font.SunFontManager.loadFonts()V+42
j sun.awt.X11FontManager.loadFonts()V+1
j sun.font.SunFontManager.findFont2D(Ljava/lang/String;II)Lsun/font/Font2D;+932
j java.awt.Font.getFont2D()Lsun/font/Font2D;+86
j java.awt.Font.canDisplay(C)Z+1

На этом месте фантазия закончилась у всех, начали выкладывать разные билды с разными JDK, с разными настройками для каталогов. Пеняли на Докер, на Амазон, на джаву, на все человечество - и вот когда все уже аргУменты закончились, было решено понять - а что ж там было в докерах.

В докерах оказалось прекрасноЭ - зачем-то в какчестве образа было выбрано дистрибутив Arch Linux с докерхаба. Изменения в этом образе были относительно недавние, и вот тут начали закрадываться подозрения. Никакие другие штуки в докерфайлах наших образов не менялись, соответственно это был последний довод королей - давайте поменяем образ уже базового линукса, если и это не поможет - значит на МПХ, и в ЖПП этот ваш докер, проклято и анафема.

Взяли pritunl/archlinux:2016-03-26 и обвесили его тэгом, во избежание. Собрали-запустили. Все контейнеры поднялись, женщины ликуют, дети смеются, радость и счастье пришло вот в это все. Выпили по этому поводу, чо уж там.

Мораль.

Опенсорц - это дико хорошо. Можно подкрутить штучку и сделать приятно себе. Можно написать что-то эдакое и сделать приятно людям. Написать какой-либо программный продукт без опенсорцных библиотек нынче - это упороться на месяцы, изобретая велосипеды. Работа большинства программистов нынче заключается в найти нужную либу и яростно ее вкрутить в код, и скорее всего эта тенденция будет сохраняться. Подключаемые “по запросу” библиотеки все ближе и ближе - начиная с JS и CSS файлов из всяких CDN от гугла и иже с ними, и заканчивая поддержкой удаленной загрузки кода в Java (с версии 1.3 даже стабы не обязательны). Но опенсорц - это также и мы тебе ничего не должны. Любой уебок может поменять значение по-умолчанию какого-то флага, и все умрет. Или скачанный тэг базового линуксообраза окажется говном. И разбираться с этими проблемами в конечном итоге ничуть не менее сложно, чем с ошибками в переполнении буффера в каком-нибудь nginx. А значит что дивный новый мир подключаемых библиотек и SaaS/PaaS привнесет с собой еще качественно другие проблемы, про которые еще 5 лет тому взад никто и не думал “А шо, и так можно?”.

Опенсорцодевелоперам хочется пожелать все ж думать о пользователях своих штук, и не менять существующее поведение, делая его несовместимым с более старыми версиями.