Постоянная ссылка: 2014-11-28 01:59:00+03:00 , автор Евгений Лопатин в Блог тэги: ubuntu upstart dbus

Всем, кто администрирует Ubuntu - уже давно известно, что Canonical продвигают свою альтернативу для init - upstart, и постепенно мигрирует все init.d скрипты в соответствующие сценарии upstart .

Многим, кто занимается разработкой серверных приложений под Linux, известно о множественных "демонах-контроллерах" вроде daemon-tools или supervisor, цель которых - следить за работой приложения, запустив как дочерний процесс; логгировать его stdout и stderr, перезапускать его в случае краха.

Но не все знают, что upstart предоставляет "из коробки" функционал, в том числе, минимальный для демонов-контроллеров, но в большинстве своём более чем достаточный - перезапуск в случае краха и логгирование выводов.

Собственно, данный функционал сам по себе достаточно неприметен, и используется upstart для реализации аналога древнего как мир функционала inittab "respawn", которым классически поддерживалась работа текстовых консолей.

Важно другое - что upstart позволяет непривилегированному пользователю иметь свои собственные сценарии upstart!

Работает это достаточно просто:

  1. в домашнем каталоге пользователя создаётся каталог .init, в котором и создаются сценарии
  2. сценарии upstart пишутся полностью в том же виде, как и "системные"

Есть нюанс - по-умолчанию, в Ubuntu возможность выполнять сценарии от непривилегированного пользователя запрещена политиками D-Bus. Нужно добавить соответствующую политику в /etc/dbus-1/system.d/Upstart.conf (пример для пользователя username):

    <policy user="username">
        <allow send_destination="com.ubuntu.Upstart"
               send_interface="org.freedesktop.DBus.Introspectable" />
        <allow send_destination="com.ubuntu.Upstart"
               send_interface="org.freedesktop.DBus.Properties" />
        <allow send_destination="com.ubuntu.Upstart"
               send_interface="com.ubuntu.Upstart0_6" />
        <allow send_destination="com.ubuntu.Upstart"
               send_interface="com.ubuntu.Upstart0_6.Job" />
        <allow send_destination="com.ubuntu.Upstart"
               send_interface="com.ubuntu.Upstart0_6.Instance" />
     </policy>

Конечно, можно просто сменить контекст default (он по-умолчанию даёт read-only доступ всем), но изменить политику для одного пользователя мне показалось безопаснее.


Данное решение почти настолько же "админонезависимо" как, например, пользовательский crontab - оно позволяет приложению, работающему с правами непривелегированного пользователя, иметь собственные сервисы и управлять ими, что иногда бывает очень полезно.

В моём случае я использую upstart для организации работы всяких обработчиков очередей в php-приложениях, без установки дополнительных демонов.

UPD: Есть ещё одна особенность, которую я обнаружил после рестарта сервера - сценарии upstart, созданные пользователем, не принимаются в учёт initctl до тех пор, пока сам initctl не будет вызван этим пользователем - пока не откроется сессия upstart. Для этого достаточно выполнить любую команду initctl после перезагрузки от имени данного пользователя, и вызвать затем событие initctl emit EVENT, а на данный EVENT повесить start on пользовательского сценария upstart. В интернете есть примеры изящного решения это проблемы в виде скрипта upstart, например здесь

P.S. upstart может работать весь целиком от имени обычного пользователя (ключ --session), но это скорее для отладки и экспериментов.