Pull to refresh

Comments 28

UFO just landed and posted this here
В принципе Вы правы, у перла с модулями на первый взгляд просто беда. Но беда поправимая.
У меня как-то сложился другой взгляд на работу с модулями. Ну может быть в Gentoo так как Вы описали и должно быть — не знаю, я его не видел. А для остальных систем типа Debian, где более-менее всё хорошо и с модулями, и с порядком в системе, например, довольно очевидно, что надо использовать встроенные модули, пока это возможно, и ставить через cpanminus все остальные. Трогать системные модули чревато проблемами.

Насчёт обновлений. Делать это следует тогда, когда это необходимо, а не когда выходит очередная версия на CPAN — где последняя версия далеко не всегда самая стабильная. То есть работает — не трогай.

Вообще правило должно быть таким: система сама по себе, пользовательское приложения сами по себе. Система не обязана поставлять приложению перловые модули, они в системе только чтобы она сама работала. Такой подход избавит от проблем. Да и поддержка скриптов в течении многих лет упростится. Вот с разными версиями перла — это уже хуже, не уверен что стоит этим увлекаться.
Вообще-то всё описанное (кроме самой утилитки g-cpan) должно быть идентично в любом *NIX, и даже под виндой — там вроде тоже core/site/vendor присутствуют. Поэтому описанная Вами ситуация — когда одновременно используются и «системные модули» (т.е. vendor) и вручную устанавливаемые через cpanminus (т.е. site) — это как раз максимально возможный хаос и потенциальные конфликты версий.

Насчёт обновлений. :) Вопрос сложный. Тот набор модулей, который стоит на Вашем сервере прямо сейчас — скорее всего является случайным. Т.е. это те модули, которые были «текущими» на CPAN в момент установки системы. Ничем принципиальным этот набор модулей от любого другого случайного набора «текущих на CPAN в момент времени X» не отличается. Учитывая уже обсуждавшуюся нами в другой статье любовь к code reuse (в данном случае выражающуюся в том, что большинство авторов CPAN-модулей выбирая между «написать 4 строчки кода» и «подключить новый CPAN-модуль и написать одну строчку кода» выбирают второе) если Ваш проект использует 10 CPAN-модулей, то в систему придётся поставить ещё 150 как зависимости. Причём лично Вы эти 150 напрямую не используете, баги в них не отслеживаете… и принимать решение стоит ли их обновлять очень сложно… а принимать взвешенное решение отдельно по каждому модулю вообще нереально. «Работает — не трогай» — одна из возможных стратегий для такой ситуации. Но меня Gentoo приучил обновлять систему раз в 2-3 дня, и хорошо продемонстрировал насколько болезненно обновляться раз в полгода-год или реже. Поэтому я предпочитаю периодически (примерно раз в полгода-год) запускать «cpan>upgrade», после чего тестировать что все проекты работают, и при необходимости фиксить их для совместимости с текущими версиями CPAN-модулей. За очень много лет лично у меня из-за этого проблем не было, так что это тоже вполне рабочая стратегия. Не лучше и не хуже Вашей, просто другая.

«Система сама по себе …» — угу, а дальше у нас появляются проекты с тем же Moose или другим монстром. Много проектов, у каждого локально установлены сотни модулей, и разработчиков этих проектов меньше всего беспокоит обновление этих модулей из-за, к примеру, обнаруженных дыр в безопасности, и вообще отслеживание устаревших версий. Нет уж, система, конечно, не обязана, но уж лучше этот Moose и его зависимости будет стоять общесистемно в одном экземпляре. На самом деле это вопрос ответственности. Когда админ отдельно, а программист отдельно — у них и интересы и области ответственности и подходы к решению проблем сильно отличаются. А я одновременно и программист и админ, так уж сложилось. Поэтому стараюсь выбирать решения эффективные одновременно с обоих точек зрения.
core/site/vendor… а имеет ли право пользователь писать в эти директории? Для пользователя ли они предназначены? Нет.

Рассмотрим конкретно Moose. Не в том беда что он монстр, беда в том, что он в принципе не может быть один для всех — так как активно меняется. DBIX требует один Moose, другой модуль другой Moose — и как быть? Только так как я и описал. И это не только с Moose — DBD::Oracle однажды взял и сломал работу с Oracle Instant Client — несколько месяцев было просто необходимо для Оракла пользоваться устаревшей версией.

Насчёт «Тот набор модулей, который стоит на Вашем сервере прямо сейчас — скорее всего является случайным.» — я согласен, потому и написал что 1) это в Debian, 2) надо отделять систему от приложения на уровне модулей.

Обновлять систему раз в несколько дней… на одном сервере и ничего другого не делая может и можно, но как-то не представляю зачем этим заниматься. Но конечно, если такая стратегия работает — что-то в ней есть правильное.

Я тоже и программист и админ, но если мне раз в несколько дней на паре десятков серверов придётся обновлять перл с полным тестированием, я переквалифицируюсь в управдомы :)
Не-не-не! Чур меня! Перл с полным тестированием, как я уже написал, раз в полгода-год. А раз в несколько дней обновляется сам Gentoo, там делов на пару минут. Просто совсем перл-модули не обновлять тоже нельзя. У меня вон система не переустанавливалась почти 8 лет (как перешёл на Gentoo, так и прекратились переустановки системы) — нельзя же всю жизнь использовать CPAN-модули образца 2004 года по принципу «работает — не трогай».
Почему бы и нет, если работает — из любви к искусству что ли? Рано или поздно у Вас будет столько программ и систем, что никакого времени не хватит их перелопачивать. Для этого и внедряют виртуализацию — чтобы сохранить устаревшие конфигурации, в частности. Хотя действительно очень хочется обновиться до современного состояния, я это стремление очень хорошо понимаю, у меня часть машин в etch и это напрягает.

Обновив один модуль, есть хороший шанс получить проблемы, так что тестировать придётся всё. Ну или полагаться на удачу.
Любое обновление чего угодно — риск получить проблемы, которых не было.

Отсутствие обновлений (да-да, включая последствия виртуализации устаревших конфигураций) — это громадные риски в плане безопасности, которыми иногда можно пренебречь если доступ к системе ограничен, но это не касается типичных публичных перл/веб проектов с кучей локальных устаревших модулей, которую мы (или по крайней мере я) тут вроде как обсуждаем.

Очень редкие обновления — это двойной риск: во-первых сильно возрастают риски в плане безопасности, а во-вторых повышается вероятность серьёзных проблем при попытке обновления, вплоть до доведения системы до нерабочего состояния когда её проще переустановить, нежели обновить (а это уже попахивает виндой, что печально).

И, да, если коротко: требования «чтоб работало» и требования безопасности в данном случае (в отношении вопроса обновлений) конфликтуют. Если проблемы безопасности не актуальны, то я полностью согласен с Вашим подходом.
Если проблема на уровне системы — правится система.
Если проблема на уровне приложения — правится приложение.

Это разделение ролей, иначе получается, что Вы просто выпускаете свою ветку дистрибутива линукса.

И в случае с перлом изменение модулей без изменения приложения невозможно в общем случае, => то есть такое изменение должен делать автор приложения, => то есть выпускать новую версию, == а это сделать проще всего таская все нужные модули с приложением. Очень может быть, что потребуется пропатчить модуль, не меняя его версии, либо серьёзно переделывать приложение, тестировать, ловить баги, организовывать взаимодействие с другими программистами на том же сервере, а если приложение установлено в нескольких местах… А если баг в модуле касается одного приложения из десяти, а изменение версии модуля потребует тестирование всех… Меняя модуль в системе, мы не улучшаем ситуацию с безопасностью приложения, мы наоборот делаем приложение менее стабильным.

Вообще-то я действительно выпускал свой дистрибутив линуха (POWER Linux, с августа 2001 до февраля 2004, когда я устал поддерживать свой дистрибутив и перешёл на Gentoo). Так что Вы меня поймали, осталось только понять, на чём именно, и как к этому относится. :)

У меня действительно используется достаточно нетипичная установка линуха (даже для Gentoo — в частности, вся система загрузочных скриптов и сервисов используется моя, а не Gentoo-шная), она действительно заточена в том числе под нужды наших проектов, и я не вижу в этом ничего плохого. И, да, совместное использование глобальных модулей всеми проектами вписывается в эту схему.

Если проблема на уровне системы — правится система.
Если проблема на уровне приложения — правится приложение.
В идеальном мире — да. А в реальности получается так, что вопросы безопасности — почему-то проблема админа, а программисты наставившие в проект кучу устаревших и потенциально дырявых модулей за их безопасность не отвечают (хорошо если они беспокоятся о безопасности хотя бы своего кода). И заставить их за этим следить абсолютно нереально, хотя это решило бы все проблемы.
Спасибо за статью, видно, что по дороге к такому подходу вы набили много шишек :)
Я в свое время отказался от использования portage/g-cpan для установки perl модулей и стараюсь пользоваться исключительно утилитой cpan. Из всех описанных вами проблем действительно часто сталкивался лишь с конфликтами vendor и site веток, не знал, что сейчас их порядок поменялся.
По поводу инсталляций на боевой сервер, мы с коллегами делаем локализованные инсталляции приложений в отдельные директории со всеми неудовлетворенными глобально зависимостями, local::lib рулит :) Такой подход позволяет не бояться, что новая инсталляция сломает уже работающие приложения, а кроме этого можно быстро откатиться на предыдущие версии в случае проблем с новой инсталляцией.
Всё так, только проблема в том, что локальные модули обычно никто не беспокоится обновлять. Админу grep-ом выискивать во всех проектах используемые локальные модули, контролировать их версии, и теребить разработчиков чтобы они их обновляли — на практике нереально. И получается, что за эти локальные модули никто не отвечает, вообще: админ — потому, что они локальные, мало ли что там юзеры у себя в домашний каталог наставят; программисты — потому, что они отвечают за свой код, а не за управление CPAN-модулями.

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

Борьба с дырами в модулях вообще отдельный вопрос. Простая логика показывает, что новая версия модуля может иметь проблемы безопасности, если их имела старая версия — ведь старая тоже была когда то новой. Так что этот аргумент в пользу частого обновления надо применять осторожно. Слава богу, в перле не так распространены проблемы с безопасностью.
Дыры новой версии обычно ещё не используются червяками, ломающими сервера пачками. В отличие от дыр старой версии. В этом весь смысл регулярных обновлений с точки зрения безопасности — даже если в последней версии дыр больше, то они всё-равно пока известны меньшему количеству потенциальных взломщиков (как людей так и программ).

Вторая, но тоже важная причина обновляться — новые модули/софт обычно пишется совместимым с текущими версиями модулей. Совместимость со старыми версиями обычно если и обеспечивается, то не очень серьёзно, основное тестирование идёт с текущими версиями. Поэтому обновляясь, мы улучшаем совместимость большинства установленных приложений (кроме устаревших). Исключение: ситуация, когда на сервере стоит старый софт, который не обновляется, и новый софт не устанавливается — здесь заниматься обновлением модулей просто глупо и чревато.
Я тоже большой фанат обновлений своей личной машины, но на боевом сервере к сожалению это просто невозможно, да и не нужно.
Обновлять перловый модуль из-за проблем с безопасностью мне не случалось, но даже если и случится, то это настолько редкая процедура, что можно найти все локальные инсталляции и обновить их тоже.
«Улучшаем совместимость»… Как раз все наоборот, обновление глобального модуля с гораздо большей вероятность сломает старый работающий проект, чем улучшит совместимость с новыми. Поэтому, если новый проект требует более новую версию модуля установленного глобально, то почти всегда она ставится локально.
Если честно, то мне нравится ваш подход, с удовольствием бы его практиковал, но с большим зоопарком различных проектов применять его становится очень сложно и дорого.
>Дыры новой версии

Можно подумать что эти червяки есть. Что это за червяки, ломающие перловые сайты? Да и на перле в основном пишут не сайты.

>Поэтому обновляясь, мы улучшаем совместимость большинства установленных приложений

Совместимость чего с чем? Обновляя модули, мы теряем совместимость их с уже установленными приложениями — ведь они были рассчитаны на старые версии, то есть УХУДШАЕМ совместимость. Вот это и есть аргумент в пользу необновления. Мы же принимаем для обсуждения мой постулат, что приложение в основном тянет с собой нужные модули, а не пользуется общесистемными, в таком случае нет проблем с совместимостью вообще.
Червяки есть. Конечно, в основном для разных PHP-сайтов, но есть. И это скорее вопрос популярности сайта/приложения, а не языка. Кроме того, когда тебя уже сломали — поздно объяснять, что ты не знал про червяка/эксплоит/дыру, через которую тебя сломали. Лучше заранее сделать всё возможное, чтобы уменьшить вероятность взлома. По сути, это обычно входит в служебные обязанности админа.

Насчёт совместимости… ну… мы улучшаем совместимость с потенциальными новыми приложениями которые мы потенциально будет устанавливать в будущем… за счёт потенциальной потери совместимости с уже установленными приложениями, всё верно. Нда. Согласен, звучит как-то не так. :) Но мне очень хотелось найти ещё один аргумент в пользу обновлений, и я его нашёл — ведь потенциальная совместимость с потенциальными новыми программами действительно потенциально улучшается! :)
И червяков нет, и дыр немного — проще их отслеживать индивидуально. Вообще чем ценен подход, когда опираемся на модули дистрибутива — там отслеживание дыр делается централизованно.

Но это детали.

Смотрите с другой точки зрения, более глобальной. Вспомним историю перла в веб-сайтах. cgi работали медленно, fastcgi был недоделан (его и не делали всерьёз, ведь крутые все на modperl писали как заведённые), перловый скрипт как web-сервер (как Mojo сейчас) ещё не работал по разным причинам. Оставался modperl — вроде прекрасная идея, централизованный перл, в его репозиторий кладутся простые модули-обработчики, всё в теории выглядит просто великолепно. Каков результат? Перл в сайтах практически не используется, и. А ведь Вы примерно то же хотите сделать — только на другом уровне. Централизованный репозиторий модулей и маленькие обработчики — вот Ваша модель перл-программ на уровне сервера, то есть Вы пытаетесь сделать, на самом деле, то что сейчас называется облачным сервисом и что пытается сделать с перлом ActiveState. Только перл на это не заточен.
Э… я не совсем уловил логику перехода от концепции регулярных обновлений в облака… но эта тема тоже интересная.

Все аналогии лживы (правда, совсем без них тоже не получается), но сравнение общесистемных модулей и modperl это всё-таки слишком. Лично я на modperl никогда не рвался писать, т.к. с самого начала видел там несколько проблем: во-первых, это misuse — modperl разрабатывался не для ускорения CGIшек, а для управления апачем на перле — а misuse никогда ничем хорошим не заканчивается; а во-вторых мне категорически не нравится идея грузить разные приложения в память одного процесса, это вызывает проблемы и с надёжностью и с безопасностью. Поэтому я писал обычные CGI пока это удовлетворяло нужды проектов, а потом перешёл на FastCGI (и, да, стандартные CPAN-модули не ахти, пришлось писать для этого свой).

И то, что я пытаюсь сделать (впрочем, не пытаюсь, а сделал) — это регулярное обновление всех наших проектов на всех серверах, чтобы они были совместимы с текущими версиями используемых CPAN-модулей. Я просто сделал это частью процесса maintenance наших проектов. И, честно говоря, на практике необходимость подстукивать наш код после обновления CPAN-модулей возникает раз в пару лет, причём по мелочам (впрочем, мы не так уж много CPAN-модулей используем, стараемся без нужды лишние модули не подключать). И никто не мешает ставить модули локально — просто вместо того, чтобы локально ставить все модули по умолчанию, ставятся только некоторые, причём каждый по определённой и известной причине (вроде описанных Вами случаев с DBD::Oracle), и когда причина исчезает мы стараемся не забыть снести локальный модуль и вернуться к использованию общесистемных.
>а во-вторых мне категорически не нравится идея грузить разные приложения в память одного процесса, это вызывает проблемы и с надёжностью и с безопасностью.

Вот именно это Вы и пытаетесь сделать — грузить разные приложения в (память) одного сервера.
Сервер — не процесс, он предназначен для совместной работы разных приложений. И глобальные модули — предназначены для совместного использования разными приложениями. Здесь нет никакой проблемы или misuse, в отличие от ситуации с modperl.

К тому же, если честно, ведь и при Вашем подходе с установкой большинства модулей локально — ведь никто не ставит локально все модули… А значит, и Ваши проекты используют некоторые глобальные модули, просто их меньше, чем в моём случае, но проблемы вызванные их обновлениями всё те же. Далее, нередко проекты и/или некоторые модули используют разные внешние утилиты и/или библиотеки (не перловские, я про .so-шки). А эти внешние утилиты и библиотеки обновляются, постоянно, даже если Вы ставите только security updates Вашего дистрибутива. Чтобы полностью изолировать проект нужно с каждым проектом ставить весь perl со всеми модулями (через perlbrew), но и это не даст 100% изоляции, для неё нужно каждому проекту свою виртуалку выделять. В очень редких случаях это может иметь смысл, но для всех остальных ситуаций это просто абсурдно.

Так что, фактически, мы спорим о том, сколько глобальных модулей будут использовать установленные проекты — чуть больше или чуть меньше. В такой постановке вопроса он уже не выглядит таким принципиальным, не правда ли?
Я опираюсь на политики Debian — а он старается не ставить новые модули и вообще новые версии, если это возможно, поэтому опираться на его обновления менее проблематично.

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

>Сервер — не процесс, он предназначен для совместной работы разных приложений. И глобальные модули — предназначены для совместного использования разными приложениями. Здесь нет никакой проблемы или misuse, в отличие от ситуации с modperl.

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

Спасибо за интересную беседу.
Одно не радует — кроме нас это никого не интересует. Перл умирает, похоже.
Глупости, просто вы вполне продуктивно общаетесь, зачем там срач устраивать?

P.S. Про умирание языков программирования вообще миф невероятный, люди по сей день пишут на cobol, хотя про него никто и не слышит уже много лет. Так что не стоит уподобляться вот им:
image
UFO just landed and posted this here
PAR слишком overengineered из-за ограничений самой архитектуры перловых модулей (в основном, из-за того, что модули любят проникать друг в друга).

Но вообще, после того, как в крайнем обновлении в конторе для того, что бы обновить системный perl с 5.8 на 5.10, пришлось выделить прикладной perl в /usr/local, мне всё больше и больше хочется системно-агностичного пакетного менеджера, который бы поддерживал различные уровни поддержки той или иной конфигурации (вендорные-системные-пользовательские-проектные пакеты с зависимостями, корректно удовлетворяемыми даже при отсутствии или кривой версии на вышестоящем уровне).
У меня возникали проблемы в свое время g-cpan и я обнаружил, что в CPANPLUS входит утилита под названием cpan2dist. С ее помощью возможно создавать пакеты практически любого формата (deb, ebuild, rpm)
Список бекендов для генерации пакетов находится в неймспейсе CPANPLUS::Dist.

«CPANPLUS и Gentoo — Автоматически создаем ebuild-ы модулей из CPAN» — koorchik.blogspot.com/2010/08/cpanplus-gentoo-ebuild-cpan.html
Но у нее был ряд проблем( криво как-то работала с CPAN-репозитариями ). Возможно в новых версиях все уже исправлено.
Да, я упоминал в статье, что несколько лет назад g-cpan был неюзабельным, но сейчас всё отлично.

На самом деле я столкнулся с ещё одной проблемой g-cpan, которую не упомянул в статье. Проблемой напоминающей те, из-за которых несколько лет назад он был неюзабельным, и вполне подходящей под Ваше описание «криво работала с CPAN». Эта проблема возникала как следствие сразу трёх факторов в трёх разных местах:
  1. CPAN-модуль должен использовать рекомендованную в PBP установку версии из трёх цифр через модуль version:
    use version; $VERSION = qv('1.2.3');

  2. CPAN-модуль должен использовать для сборки модуль Module::Build. Это приводит к тому, что команда:
    ./Build dist
    создаёт файл Your-Module-v1.2.3.tar.gz (обратите внимание на «v» перед версией).
  3. А дальше в дело вступает g-cpan, который архитектурно реализован так, что отрезает возможное «v» из номера версии в одном месте, а потом использует эту версию для формирования имени файла для выкачки с CPAN в совершенно другом месте (и чего было просто не взять имя файла из CPAN-индексов, оно там вроде должно быть), и в результате полученный ebuild пытается выкачать несуществующий Your-Module-1.2.3.tar.gz.
Можно, конечно, заявить, что виноват g-cpan, но есть несколько смягчающих обстоятельств:
  1. Из ~300 установленных мной с CPAN модулей ни у одного нет такой комбинации факторов — все либо версию устанавливают в десятичном формате, либо для сборки не используют Module::Build.
  2. При установке модуля с такой версией через ExtUtils::MakeMaker или Module::Install или даже через Module::Build в режиме совместимости с Makefile.PL — создаётся архив Your-Module-1.2.3.tar.gz, совместимый с g-cpan. Так что добавление «v» может оказаться и багом Module::Build.
  3. Module::Build известен своей расширяемостью, так что я сумел заставить его создавать архивы без «v» просто добавив 5-6 строчек в свой Build.PL.
В этих условиях я предпочёл просто пофиксить десяток своих приватных модулей через Build.PL, чем отказываться от использования g-cpan.
Sign up to leave a comment.

Articles

Change theme settings