Копать или не копать?
     Я хочу поговорить о казалось-бы простой, но важной части любой ОС — о регламенте или структуре размещения файлов или более просто — хочется поговорить о порядке и удобстве. Затрагивать я буду UNIX подобные ОС, а конкретно все многообразие дистрибутивов на базе ядра Linux.
     Итак, программист создал программу и хочет её распространять, теперь есть задача — установка программы пользователем, для этого вроде как существуют стандарты (FHS, LFS), однако многообразие средств установки ПО просто обескураживает и программист, в меру своих способностей, реализует средства по установке, от простого README до чего-то более сложного.
     Да, сегодня большинство дистрибутивов обладают системой установки программ, которая в целом в пределах дистрибутива решает вопросы с установкой программ и в какой-то степени облегчает труд программисту. И когда понадобилось управлять большой группой разных дистрибутивов (стойки в ЦОД'ах, VM) были создали различные системы управления конфигурациями (CFEngine, Bcfg2 puppet, Chef, etc). И вроде-бы всё ok, но чувство костыльности, всего этого многообразия, вот уже лет 14 (с момента когда начал ковырять RedHat Linux 5.2) не покидает меня… Так в чём же дело?
Корни
     Попробую отбросить всё наносное, что сегодня применяется для установки/удаления программ в типичном дистрибутиве Linux — прикину что делать с программой, сложнее чем helloworld, убрав:
- системы управления конфигурациями;
- пакетный менеджер;
- все без исключения скрипты установки, в том числе те, которые производят предварительные действия типа создания каталогов для размещения библиотек, ресурсов, документации программы, скрипты компиляции и т.п.;
- и даже README/INSTALL файл.
Какие теперь надо выполнить действия что-бы установить, а затем удалить программу, вместе со всеми её компонентами?
     Допустим я сумел разобраться в том, где должны размещаться части программы, создал нужные каталоги, скопировал файлы, обновил окружение и программа теперь успешно выполняется.
     Но прошло время, мной уже давно забыто где и как размещались компоненты программы, я лишь помню название программы и мне нужно удалить её вместе со всеми компонентами и созданными ею файлами. И вот тут я становлюсь в тупик — что делать? Натравить на программу strace и ldd? Найти все одноимённые каталоги, что-бы удалить документацию? Ради того, что-бы просто удалить программу и все её компоненты? И ведь не факт, что всё будет найдено и удалено.
     Итак, если обойтись без реверансов, то наблюдаемая ситуация с установкой/удалением программ в Linux — хорошо замаскированный bullshit:
И что с этим делать?
     Есть простая программа install, которая позволяет копировать и устанавливать нужные атрибуты на копируемые файлы, однако и результаты её работы следует удалять привычным rm.
     Что-бы запустить какую-либо программу и завершить её выполнение доступны функции execve() и _exit(), что-бы отрыть файл и закрыть его есть функции open()/create() и close(). При этом при выполнении/остановке программы имеет место быть идентификатор процесса (PID), а при открытии/закрытии файла — десктриптор файла. Так почему бы для установки/удаления программы не ввести, что-то похожее на идентификатор размещения программы, допустим назвать его Deploy ID (DID)/Install ID (IID), который на самом деле может являться стандартным UUID, предоставив несколько функции для оперирования с этим идентификатором типа _appinstall()/_appupdate()/_appuninstall()/etc и соответствующую команду типа ps, например app? И почему-бы не размещать программу с её компонентами, допустим не в
/etc/program.conf
/etc/program.conf.d/someone.conf
/usr/bin/program
/usr/lib/program/libprogram.so
/usr/share/doc/program/manual.txt
/var/program/database
а в
/etc/<did>/program.conf
/etc/<did>/program.conf.d/someone.conf
/usr/bin/<did>/program
/usr/lib/<did>/libprogram.so
/usr/docs/<did>/manual.txt
/var/<did>/database
Да, это будет ещё один пакетный менеджер, к нему могут появляться удобные GUI и системы управления конфигурациями никуда не денутся. Но! Все может ложиться в POSIX, размещение программы и её компонент может производиться строгим образом, а удаление становится простым даже в случае разрушения базы идентификаторов. Кроме-того, пройдясь по структуре размещения файлов можно будет восстановить все идентификаторы, пересоздав базу, так же как это делает updatedb строя индекс для locate. Появляется возможность, достаточно просто, производить установку нескольких версий или экземпляров одной программы и переключения между версиями.
     Если идти дальше, то резонно и конфигурационные файлы программ привести к какому-то общему знаменателю, унифицировав их содержимое используя, например, тот же xml или json, но предоставляя функции на манер _appconfigdeploy() с валидацией конфигурации на соответствие предопределённой, допустим в том же POSIX, схеме.
Сухари сушить или удочку забрасывать?
     Вообще есть дистрибутивы, которые вроде как двинулись в сторону унификации размещения программ их компонент и конфигурационных файлов, такие как GoboLinux, и на мой взгляд к этому подходу ближе всех пакетный менеджер nix и созданный на его базе дистрибутив NixOS. Но я думаю нужна масштабная инициатива, обсуждение, такое-же как в отношении FHS. Если конечно я вообще прав.
Вот такие пироги.
P.S. Как-то я поднимал обсуждение на эту тему в 2006 году, на форуме gentoo.ru.
Автор: RNZ