10.09.2009Создание init-скриптов с помощью руби
Предисловие
Сегодня у меня кроме всего прочего появился повод похвастаться! :) Когда вы смотрите широко обсуждаемые Яндекс-Панорамы, знайте, что их производством в составе моей любимой компании neq4 занимался и я.
В частности, флэш-просмотрщик, который кроме панорам и улиц показывает ещё и номера домов в соответствии с информацией, полученной от сервера, был разработан мной и передан на поддержку Яндексу. Когда происходит полная передача проекта с исходниками, не совсем справедливо забирать всю славу себе. Но следует отметить, что мои исходники исчерпывающе документированы. И разработчики обратились ко мне с вопросами лишь два раза. Но, может быть, они всё уже переписали с нуля, и я зря тешу своё самолюбие :)
Так же я, безусловно, планирую раскрывать некоторые секреты. Кстати, практически все записи в этом блоге основаны на работе над этим проектом. Например, программа, которая управляет камерами во время движения, а так же получает данные от приборов, была так же написана мной. И теперь вы знаете, что написана она на руби. :) За исключением библиотеки для работы с камерами, о которой я уже писал.
Это и подводит нас вплотную к теме сегодняшней записи.
Введение
Безусловно, руби — лучший из языков. Для меня выбор в его пользу обусловлен прежде всего высокой скоростью разработки. Поэтому при возникновении какой-то задачи, особенно если её нужно сделать быстро, я пробую решить её на руби. В прошлый раз я рассказал об автоподстановке. А сегодня — создание init-скриптов
Скрипты эти располагаются в папке /etc/init.d и запускаются при старте в определённых условиях. Они должны принимать параметры start, stop, restart и status. Как правило, они служат для запуска и остановки служб.
Решение
Написать программу, которая принимает текстовый ключ на входе, не составляет труда (/etc/init.d/my_script):
#!/usr/bin/env ruby
APP_NAME = "my_script"
case ARGV.first
when "status"
if...
...
exit 0
elsif ...
...
exit 1
else
exit ...
end
when "start"
...
when "stop"
...
when "restart"
...
else
puts "Usage: #{APP_NAME} {start|stop|restart|status}"
end
Круто, но до настоящего init-скрипта не дотягивает. Когда система проходит свой цикл жизни от запуска до перезагрузки или выключения, она проходит через шесть стадий. Нужно указать, в каких стадиях наш скрипт следует запустить с параметром start, а когда — с параметром stop. Для этого используется спецификация LSB (Linux Standard Base). Вот так:
#!/usr/bin/env ruby
# Start/stop my daemon
#
### BEGIN INIT INFO
# Provides: my_script
# Required-Start: $all
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Initializes my daemon at boot time
# Description: In a Galaxy far, far away...
### END INIT INFO
APP_NAME = "my_script"
case ARGV.first
.....
Теперь лежащий в /etc/init.d скрипт нужно подрегулировать и зарегистрировать:
sudo chown root:root /etc/init.d/my_script
sudo chmod 755 /etc/init.d/my_script
sudo update-rc.d my_script defaults
Таким образом, вовсе необязательно изучать bash-скрипт. Вот, кстати, оболочка-альтернатива всяким башам, использующая синтаксис руби. Для таких, как я. :)